# The GF Prelude

Last update: 2006-02-27 09:41:31 CET

- Strings, records, and tables
- Optional elements
- Infixes. prefixes, and postfixes
- Booleans
- High-level acces to Predef operations
- Lexer-related operations
- Miscellaneous

Produced by gfdoc - a rudimentary GF document generator. (c) Aarne Ranta (aarne@cs.chalmers.se) 2002 under GNU GPL.

This file defines some prelude facilities usable in all grammars.

        resource Prelude = open (Predef=Predef) in {

        oper

## Strings, records, and tables

          SS  : Type = {s : Str} ;
          ss  : Str -> SS = \s -> {s = s} ;
          ss2 : (_,_ : Str) -> SS = \x,y -> ss (x ++ y) ;
          ss3 : (_,_ ,_: Str) -> SS = \x,y,z -> ss (x ++ y ++ z) ;

          cc2 : (_,_ : SS) -> SS = \x,y -> ss (x.s ++ y.s) ;
          cc3 : (_,_,_ : SS) -> SS = \x,y,z -> ss (x.s ++ y.s ++ z.s) ;

          SS1 : Type -> Type = \P -> {s : P => Str} ;
          ss1 : (A : Type) -> Str -> SS1 A = \A,s -> {s = table {_ => s}} ;

          SP1 : Type -> Type = \P -> {s : Str ; p : P} ;
          sp1 : (A : Type) -> Str -> A -> SP1 A = \_,s,a -> {s = s ; p = a} ;

          constTable : (A,B : Type) -> B -> A => B = \_,_,b -> \\_ => b ;
          constStr   : (A : Type) -> Str -> A => Str = \A -> constTable A Str ;

Discontinuous constituents.

          SD2 = {s1,s2 : Str} ;
          sd2 : (_,_ : Str) -> SD2 = \x,y -> {s1 = x ; s2 = y} ;

## Optional elements

Missing form.

          nonExist : Str = variants {} ;

Optional string with preference on the string vs. empty.

          optStr : Str -> Str = \s -> variants {s ; []} ;
          strOpt : Str -> Str = \s -> variants {[] ; s} ;

Free order between two strings.

          bothWays : Str -> Str -> Str = \x,y -> variants {x ++ y ; y ++ x} ;

Parametric order between two strings.

          preOrPost : Bool -> Str -> Str -> Str = \pr,x,y ->
            if_then_Str pr (x ++ y) (y ++ x) ;

## Infixes. prefixes, and postfixes

Fixes with precedences are defined in Precedence.

          infixSS   : Str  -> SS -> SS -> SS = \f,x,y -> ss (x.s ++ f ++ y.s) ;
          prefixSS  : Str        -> SS -> SS = \f,x   -> ss (f ++ x.s) ;
          postfixSS : Str        -> SS -> SS = \f,x   -> ss (x.s ++ f) ;
          embedSS   : Str -> Str -> SS -> SS = \f,g,x -> ss (f ++ x.s ++ g) ;

## Booleans

         param Bool = True | False ;

        oper
          if_then_else : (A : Type) -> Bool -> A -> A -> A = \_,c,d,e ->
            case c of {
              True => d ;  ---- should not need to qualify
              False => e
             } ;

          andB : (_,_ : Bool) -> Bool = \a,b -> if_then_else Bool a b False ;
          orB  : (_,_ : Bool) -> Bool = \a,b -> if_then_else Bool a True b ;
          notB : Bool         -> Bool = \a   -> if_then_else Bool a False True ;

          if_then_Str : Bool -> Str -> Str -> Str = if_then_else Str ;

          onlyIf : Bool -> Str -> Str = \b,s -> case b of {
            True => s ;
            _ => nonExist
            } ;

Interface to internal booleans

          pbool2bool : Predef.PBool -> Bool = \b -> case b of {
            Predef.PFalse => False ; Predef.PTrue => True
            } ;

          init : Tok -> Tok = Predef.tk 1 ;
          last : Tok -> Tok = Predef.dp 1 ;

## High-level acces to Predef operations

          isNil : Tok -> Bool = \b -> pbool2bool (Predef.eqStr [] b) ;

          ifTok : (A : Type) -> Tok -> Tok -> A -> A -> A = \A,t,u,a,b ->
            case Predef.eqStr t u of {Predef.PTrue => a ; Predef.PFalse => b} ;

## Lexer-related operations

Bind together two tokens in some lexers, either obligatorily or optionally

          oper
            glue : Str -> Str -> Str = \x,y -> x ++ BIND ++ y ;
            glueOpt : Str -> Str -> Str = \x,y -> variants {glue x y ; x ++ y} ;
            noglueOpt : Str -> Str -> Str = \x,y -> variants {x ++ y ; glue x y} ;

Force capitalization of next word in some unlexers

            capitalize : Str -> Str = \s -> CAPIT ++ s ;

These should be hidden, and never changed since they are hardcoded in (un)lexers

            BIND : Str = "&+" ;
            PARA : Str = "&-" ;
            CAPIT : Str = "&|" ;

## Miscellaneous

Identity function

          id : (A : Type) -> A -> A = \_,a -> a ;

Parentheses

          paren : Str -> Str = \s -> "(" ++ s ++ ")" ;
          parenss : SS -> SS = \s -> ss (paren s.s) ;

Zero, one, two, or more (elements in a list etc)

        param
          ENumber = E0 | E1 | E2 | Emore ;

        oper
          eNext : ENumber -> ENumber = \e -> case e of {
            E0 => E1 ; E1 => E2 ; _ => Emore} ;

        }