Template language overhaul & misc. improvements
[bpt/mlt.git] / src / mlt.grm
index a559649..6a584f5 100644 (file)
@@ -38,18 +38,23 @@ fun addNumbers L =
 %term 
    EOF
  | HTML of string
- | IF | THEN | ELSE | AS | WITH | OPEN | VAL | REF | TRY | CATCH
- | FOREACH | IN | CASE | ORELSE | ANDALSO
+ | IF | THEN | ELSE
+ | AS | WITH | OPEN | VAL | REF | TRY | CATCH
+ | FN | END | RAISE
+ | FOREACH | IN | DO
+ | SWITCH | CASE | OF | BAR | ARROW
  | LPAREN | RPAREN | LBRACK | RBRACK | LBRACE | RBRACE | HASH | SEMI | CONS
  | PLUS | MINUS | TIMES | DIVIDE | MOD | NEG | DOLLAR | AT | STRCAT
  | ASN | EQ | NEQ | GT | GTE | LT | LTE
+ | ANDALSO | ORELSE
  | IDENT of string | DOT | DOTDOT | DOTDOTDOT | COMMA | COLON | CARET | TILDE | UNDER
- | INT of int | STRING of string | CHAR of string
+ | INT of int | STRING of string | CHAR of string | REAL of real
 
 %nonterm 
    file of block
  | block of block
  | exp of exp
+ | cases of (pat * exp) list
  | appsL of exp list
  | apps of exp
  | term of exp
@@ -59,7 +64,7 @@ fun addNumbers L =
  | path of ident list
  | pathList of ident list list
  | blockItem of blockItem
- | ifte of ((exp * block) list * block option) withext
+ | elseOpt of block option
  | matches of (pat * block) list withext
  | pexp of exp
  | ppat of pat
@@ -103,10 +108,10 @@ ilist     : IDENT ilist                   (IDENT :: ilist)
 ivlist : IDENT EQ exp COMMA ivlist     ((IDENT, exp) :: ivlist)
        | IDENT EQ exp                  ([(IDENT, exp)])
 
-catch  : CATCH ppat LBRACE block RBRACE        (ppat, block)
+catch  : pat ARROW block               (pat, block)
 
-catches        : catch catches                         (catch::catches)
-       | catch                                 ([catch])
+catches        : catches BAR catch             (catch::catches)
+       | catch                         ([catch])
 
 blockItem      : HTML                  (BITEM (Html_i HTML, (HTMLleft, HTMLright)))
                | REF ivlist            (BITEM (Ref_i ivlist, (REFleft, ivlistright)))
@@ -114,27 +119,22 @@ blockItem : HTML                  (BITEM (Html_i HTML, (HTMLleft, HTMLright)))
                | VAL pat EQ exp        (BITEM (Val_i (pat, exp), (patleft, expright)))
                | IDENT ASN exp         (BITEM (Assn_i (IDENT, exp), (IDENTleft, expright)))
                | exp                   (BITEM (Exp_i exp, (expleft, expright)))
-               | IF LPAREN exp RPAREN LBRACE block RBRACE ifte
-                       (let val ((L, O), _) = ifte in
-                                BITEM (Ifthenelse_i((exp, block) :: L, O),
-                               (IFleft, ifteright))
-                        end)
-               | FOREACH LPAREN IDENT IN exp RPAREN LBRACE block RBRACE
+               | IF exp THEN block elseOpt END
+                        (BITEM (Ifthenelse_i(exp, block, elseOpt),
+                               (IFleft, ENDright)))
+               | FOREACH IDENT IN exp DO block END
                        (BITEM (Foreach_i (IDENT, exp, block),
-                               (FOREACHleft, RBRACEright)))
-               | FOREACH LPAREN IDENT IN exp DOTDOT exp RPAREN LBRACE block RBRACE
+                               (FOREACHleft, ENDright)))
+               | FOREACH IDENT IN exp DOTDOT exp DO block END
                        (BITEM (For_i (IDENT, exp1, exp2, block),
-                               (FOREACHleft, RBRACEright)))
-               | CASE pexp matches
-                       (BITEM (Case_i (pexp, #1 matches), (CASEleft, matchesright)))
-               | TRY LBRACE block RBRACE catches
-                       (BITEM (TryCatch_i (block, catches), (TRYleft, catchesright)))
-
-ifte   : ELSE LBRACE block RBRACE                              (([], SOME block), (ELSEleft, RBRACEright))
-       | ELSE IF LPAREN exp RPAREN LBRACE block RBRACE ifte    (let val ((L, O), _) = ifte in
-                                                                        (((exp, block) :: L, O), (ELSEleft, ifteright))
-                                                               end)
-       |                                                       (([], NONE), (0, 0))
+                               (FOREACHleft, ENDright)))
+               | SWITCH exp OF matches END
+                       (BITEM (Case_i (exp, List.rev (#1 matches)), (SWITCHleft, ENDright)))
+               | TRY block WITH catches END
+                       (BITEM (TryCatch_i (block, List.rev catches), (TRYleft, ENDright)))
+
+elseOpt         :                       (NONE)
+                | ELSE block            (SOME block)
 
 block  : blockItem                     (BLOCK ([blockItem], (blockItemleft, blockItemright)))
        | blockItem SEMI block          (BLOCK (blockItem :: (unblock block), (blockItemleft, blockright)))
@@ -180,6 +180,7 @@ term        : LBRACE erseq RBRACE           (EXP (Record_e (false, sortRcs erseq), (LBRACEleft,
        | pexp                          (pexp)
        | STRING                        (EXP (String_e STRING, (STRINGleft, STRINGright)))
        | CHAR                          (EXP (Char_e CHAR, (CHARleft, CHARright)))
+       | REAL                          (EXP (Real_e REAL, (REALleft, REALright)))
        | path                          (EXP (Ident_e path, (pathleft, pathright)))
        | INT                           (EXP (Int_e INT, (INTleft, INTright)))
        | NEG                           (EXP (Neg_e, (NEGleft, NEGright)))
@@ -206,9 +207,16 @@ exp        : apps                          (apps)
        | exp STRCAT exp                (EXP (StrCat_e (exp1, exp2), (exp1left, exp2right)))
        | exp ORELSE exp                (EXP (Orelse_e (exp1, exp2), (exp1left, exp2right)))
        | exp ANDALSO exp               (EXP (Andalso_e (exp1, exp2), (exp1left, exp2right)))
+        | CASE exp OF cases             (EXP (Case_e (exp, List.rev cases), (expleft, casesright)))
+        | FN cases                      (EXP (Fn_e (List.rev cases), (FNleft, casesright)))
+        | RAISE exp                     (EXP (Raise_e exp, (RAISEleft, expright)))
+
+
+cases   : pat ARROW exp                 ([(pat, exp)])
+        | cases BAR pat ARROW exp       ((pat, exp) :: cases)
 
-matches        : ppat LBRACE block RBRACE matches      (((ppat, block) :: (#1 matches), (ppatleft, matchesright)))
-       |                                       ([], (0, 0))
+matches        : matches BAR pat ARROW block           (((pat, block) :: (#1 matches), (matchesleft, blockright)))
+       | pat ARROW block                       ([(pat, block)], (patleft, blockright))
 
 rseq   : IDENT EQ pat COMMA rseq               ((IDENT, pat) :: rseq)
        | IDENT COMMA rseq                      ((IDENT, PAT (Ident_p [IDENT], (IDENTleft, IDENTright))) :: rseq)
@@ -234,6 +242,8 @@ pterm       : path                                  (PAT (Ident_p path, (pathleft, pathright)))
        | UNDER                                 (PAT (Wild_p, (UNDERleft, UNDERright)))
        | INT                                   (PAT (Int_p INT, (INTleft, INTright)))
        | STRING                                (PAT (String_p STRING, (STRINGleft, STRINGright)))
+       | CHAR                                  (PAT (Char_p CHAR, (CHARleft, CHARright)))
+       | REAL                                  (PAT (Real_p REAL, (REALleft, REALright)))
        | LBRACE rseq RBRACE                    (PAT (Record_p (false, sortRcs rseq), (LBRACEleft, RBRACEright)))
        | LBRACE RBRACE                         (PAT (Record_p (false, []), (LBRACEleft, RBRACEright)))
        | LBRACE frseq RBRACE                   (PAT (FlexRecord_p (sortRcs frseq), (LBRACEleft, RBRACEright)))