%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
| 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
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)))
| 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)))
| 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)))
| 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)
| 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)))