Change uses of Substring.all (obsolete) to Substring.full
[hcoop/mlt.git] / src / mlt.grm
index a559649..5bb039d 100644 (file)
@@ -31,6 +31,11 @@ fun addNumbers L =
                addNum (1, L)
        end
 
+fun compact' [] = []
+  | compact' (BITEM (Html_i h1, p1) :: BITEM (Html_i h2, p2) :: rest) = compact' (BITEM (Html_i (h1 ^ h2), p1) :: rest)
+  | compact' (first :: rest) = first :: compact' rest
+
+fun compact (BLOCK (items, pos)) = BLOCK (compact' items, pos)
 
 %%
 %header (functor MltLrValsFn(structure Token : TOKEN))
@@ -38,18 +43,23 @@ fun addNumbers L =
 %term 
    EOF
  | HTML of string
- | IF | THEN | ELSE | AS | WITH | OPEN | VAL | REF | TRY | CATCH
- | FOREACH | IN | CASE | ORELSE | ANDALSO
- | LPAREN | RPAREN | LBRACK | RBRACK | LBRACE | RBRACE | HASH | SEMI | CONS
+ | IF | THEN | ELSE | ELSEIF | IFF
+ | AS | WITH | OPEN | VAL | REF | TRY | CATCH
+ | FN | LET | IN | END | RAISE
+ | FOREACH | FOR | DO
+ | SWITCH | CASE | OF | BAR | ARROW
+ | LPAREN | RPAREN | LBRACK | RBRACK | LBRACE | RBRACE | HASH | SEMI | CONS | O
  | 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 +69,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
@@ -95,7 +105,7 @@ fun addNumbers L =
 
 %%
 
-file   : block                         (block)
+file   : block                         (compact block)
 
 ilist  : IDENT ilist                   (IDENT :: ilist)
        | IDENT                         ([IDENT])
@@ -103,10 +113,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, compact 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 +124,25 @@ 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
-                       (BITEM (Foreach_i (IDENT, exp, block),
-                               (FOREACHleft, RBRACEright)))
-               | FOREACH LPAREN IDENT IN exp DOTDOT exp RPAREN LBRACE block RBRACE
-                       (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))
+               | IF exp THEN block elseOpt END
+                        (BITEM (Ifthenelse_i(exp, compact block, elseOpt),
+                               (IFleft, ENDright)))
+               | FOREACH pat IN exp DO block END
+                       (BITEM (Foreach_i (pat, exp, compact block),
+                               (FOREACHleft, ENDright)))
+               | FOR IDENT IN exp DOTDOT exp DO block END
+                       (BITEM (For_i (IDENT, exp1, exp2, compact block),
+                               (FORleft, ENDright)))
+               | SWITCH exp OF matches END
+                       (BITEM (Case_i (exp, List.rev (#1 matches)), (SWITCHleft, ENDright)))
+               | TRY block WITH catches END
+                       (BITEM (TryCatch_i (compact block, List.rev catches), (TRYleft, ENDright)))
+
+elseOpt         :                                 (NONE)
+                | ELSEIF exp THEN block elseOpt  (SOME (BLOCK ([BITEM (Ifthenelse_i (exp, compact block, elseOpt),
+                                                                      (ELSEIFleft, elseOptright))],
+                                                              (ELSEIFleft, elseOptright))))
+                | ELSE block                      (SOME (compact block))
 
 block  : blockItem                     (BLOCK ([blockItem], (blockItemleft, blockItemright)))
        | blockItem SEMI block          (BLOCK (blockItem :: (unblock block), (blockItemleft, blockright)))
@@ -180,6 +188,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)))
@@ -203,12 +212,22 @@ exp       : apps                          (apps)
        | exp GT exp                    (EXP (Gt_e (exp1, exp2), (exp1left, exp2right)))
        | exp GTE exp                   (EXP (Gte_e (exp1, exp2), (exp1left, exp2right)))
        | exp CONS exp                  (EXP (Cons_e (exp1, exp2), (exp1left, exp2right)))
+        | exp O exp                     (EXP (Compose_e (exp1, exp2), (exp1left, exp2right)))
        | 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)))
+        | LET block IN exp END          (EXP (Let_e (compact block, exp), (LETleft, ENDright)))
+        | IFF exp THEN exp ELSE exp     (EXP (If_e (exp1, exp2, exp3), (IFFleft, exp3right)))
+
+
+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, compact block) :: (#1 matches), (matchesleft, blockright)))
+       | pat ARROW block                       ([(pat, compact 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 +253,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)))