Mercurial > urweb
comparison src/urweb.grm @ 2009:799be3911ce3
Monadic bind supports patterns
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Fri, 02 May 2014 17:16:02 -0400 |
parents | 93ff76058825 |
children | 403f0cc65b9c |
comparison
equal
deleted
inserted
replaced
2008:93ff76058825 | 2009:799be3911ce3 |
---|---|
320 val e' = (EApp (e', pb), loc) | 320 val e' = (EApp (e', pb), loc) |
321 in | 321 in |
322 (EApp (e', ob), loc) | 322 (EApp (e', ob), loc) |
323 end | 323 end |
324 | 324 |
325 fun patternOut (e : exp) = | |
326 case #1 e of | |
327 EWild => (PWild, #2 e) | |
328 | EVar ([], x, Infer) => | |
329 if Char.isUpper (String.sub (x, 0)) then | |
330 (PCon ([], x, NONE), #2 e) | |
331 else | |
332 (PVar x, #2 e) | |
333 | EVar (xs, x, Infer) => | |
334 if Char.isUpper (String.sub (x, 0)) then | |
335 (PCon (xs, x, NONE), #2 e) | |
336 else | |
337 (ErrorMsg.errorAt (#2 e) "Badly capitalized constructor name in pattern"; | |
338 (PWild, #2 e)) | |
339 | EPrim p => (PPrim p, #2 e) | |
340 | EApp ((EVar (xs, x, Infer), _), e') => | |
341 (PCon (xs, x, SOME (patternOut e')), #2 e) | |
342 | ERecord (xes, flex) => | |
343 (PRecord (map (fn (x, e') => | |
344 let | |
345 val x = | |
346 case #1 x of | |
347 CName x => x | |
348 | _ => (ErrorMsg.errorAt (#2 e) "Field name not constant in pattern"; | |
349 "") | |
350 in | |
351 (x, patternOut e') | |
352 end) xes, flex), #2 e) | |
353 | EAnnot (e', t) => | |
354 (PAnnot (patternOut e', t), #2 e) | |
355 | _ => (ErrorMsg.errorAt (#2 e) "This is an expression but not a pattern."; | |
356 (PWild, #2 e)) | |
357 | |
325 %% | 358 %% |
326 %header (functor UrwebLrValsFn(structure Token : TOKEN)) | 359 %header (functor UrwebLrValsFn(structure Token : TOKEN)) |
327 | 360 |
328 %term | 361 %term |
329 EOF | 362 EOF |
426 | 459 |
427 | eexp of exp | 460 | eexp of exp |
428 | eapps of exp | 461 | eapps of exp |
429 | eterm of exp | 462 | eterm of exp |
430 | etuple of exp list | 463 | etuple of exp list |
431 | rexp of (con * exp) list | 464 | rexp of (con * exp) list * bool |
432 | xml of exp | 465 | xml of exp |
433 | xmlOne of exp | 466 | xmlOne of exp |
434 | xmlOpt of exp | 467 | xmlOpt of exp |
435 | tag of (string * exp) * exp option * exp option * exp | 468 | tag of (string * exp) * exp option * exp option * exp |
436 | tagHead of string * exp | 469 | tagHead of string * exp |
437 | bind of string * con option * exp | 470 | bind of pat * con option * exp |
438 | edecl of edecl | 471 | edecl of edecl |
439 | edecls of edecl list | 472 | edecls of edecl list |
440 | 473 |
441 | earg of exp * con -> exp * con | 474 | earg of exp * con -> exp * con |
442 | eargp of exp * con -> exp * con | 475 | eargp of exp * con -> exp * con |
728 | 761 |
729 val e = (EVar (["Basis"], "foreign_key", Infer), loc) | 762 val e = (EVar (["Basis"], "foreign_key", Infer), loc) |
730 val e = (EApp (e, mat), loc) | 763 val e = (EApp (e, mat), loc) |
731 val e = (EApp (e, texp), loc) | 764 val e = (EApp (e, texp), loc) |
732 in | 765 in |
733 (EApp (e, (ERecord [((CName "OnDelete", loc), | 766 (EApp (e, (ERecord ([((CName "OnDelete", loc), |
734 findMode Delete), | 767 findMode Delete), |
735 ((CName "OnUpdate", loc), | 768 ((CName "OnUpdate", loc), |
736 findMode Update)], loc)), loc) | 769 findMode Update)], false), loc)), loc) |
737 end) | 770 end) |
738 | 771 |
739 | LBRACE eexp RBRACE (eexp) | 772 | LBRACE eexp RBRACE (eexp) |
740 | 773 |
741 tnameW : tname (let | 774 tnameW : tname (let |
777 val e = (EDisjointApp e, loc) | 810 val e = (EDisjointApp e, loc) |
778 | 811 |
779 val witness = map (fn (c, _) => | 812 val witness = map (fn (c, _) => |
780 (c, (EWild, loc))) | 813 (c, (EWild, loc))) |
781 (#1 tnames :: #2 tnames) | 814 (#1 tnames :: #2 tnames) |
782 val witness = (ERecord witness, loc) | 815 val witness = (ERecord (witness, false), loc) |
783 in | 816 in |
784 (EApp (e, witness), loc) | 817 (EApp (e, witness), loc) |
785 end) | 818 end) |
786 | 819 |
787 pkopt : (EVar (["Basis"], "no_primary_key", Infer), dummy) | 820 pkopt : (EVar (["Basis"], "no_primary_key", Infer), dummy) |
1134 (ECase (eexp1, [((PCon (["Basis"], "True", NONE), loc), eexp2), | 1167 (ECase (eexp1, [((PCon (["Basis"], "True", NONE), loc), eexp2), |
1135 ((PCon (["Basis"], "False", NONE), loc), eexp3)]), loc) | 1168 ((PCon (["Basis"], "False", NONE), loc), eexp3)]), loc) |
1136 end) | 1169 end) |
1137 | bind SEMI eexp (let | 1170 | bind SEMI eexp (let |
1138 val loc = s (bindleft, eexpright) | 1171 val loc = s (bindleft, eexpright) |
1139 val (v, to, e1) = bind | 1172 val (p, to, e1) = bind |
1140 val e = (EVar (["Basis"], "bind", Infer), loc) | 1173 val e = (EVar (["Basis"], "bind", Infer), loc) |
1141 val e = (EApp (e, e1), loc) | 1174 val e = (EApp (e, e1), loc) |
1142 in | 1175 |
1143 (EApp (e, (EAbs (v, to, eexp), loc)), loc) | 1176 val f = case #1 p of |
1177 PVar v => (EAbs (v, to, eexp), loc) | |
1178 | _ => (EAbs ("$x", to, | |
1179 (ECase ((EVar ([], "$x", Infer), loc), | |
1180 [(p, eexp)]), loc)), loc) | |
1181 in | |
1182 (EApp (e, f), loc) | |
1144 end) | 1183 end) |
1145 | eexp EQ eexp (native_op ("eq", eexp1, eexp2, s (eexp1left, eexp2right))) | 1184 | eexp EQ eexp (native_op ("eq", eexp1, eexp2, s (eexp1left, eexp2right))) |
1146 | eexp NE eexp (native_op ("ne", eexp1, eexp2, s (eexp1left, eexp2right))) | 1185 | eexp NE eexp (native_op ("ne", eexp1, eexp2, s (eexp1left, eexp2right))) |
1147 | MINUS eterm (native_unop ("neg", eterm, s (MINUSleft, etermright))) | 1186 | MINUS eterm (native_unop ("neg", eterm, s (MINUSleft, etermright))) |
1148 | eexp PLUS eexp (native_op ("plus", eexp1, eexp2, s (eexp1left, eexp2right))) | 1187 | eexp PLUS eexp (native_op ("plus", eexp1, eexp2, s (eexp1left, eexp2right))) |
1179 | 1218 |
1180 | eapps DCOLON eexp (let | 1219 | eapps DCOLON eexp (let |
1181 val loc = s (eappsleft, eexpright) | 1220 val loc = s (eappsleft, eexpright) |
1182 in | 1221 in |
1183 (EApp ((EVar (["Basis"], "Cons", Infer), loc), | 1222 (EApp ((EVar (["Basis"], "Cons", Infer), loc), |
1184 (ERecord [((CName "1", loc), | 1223 (ERecord ([((CName "1", loc), |
1185 eapps), | 1224 eapps), |
1186 ((CName "2", loc), | 1225 ((CName "2", loc), |
1187 eexp)], loc)), loc) | 1226 eexp)], false), loc)), loc) |
1188 end) | 1227 end) |
1189 | 1228 |
1190 bind : SYMBOL LARROW eapps (SYMBOL, NONE, eapps) | 1229 bind : eapps LARROW eapps (patternOut eapps1, NONE, eapps2) |
1191 | eapps (let | 1230 | eapps (let |
1192 val loc = s (eappsleft, eappsright) | 1231 val loc = s (eappsleft, eappsright) |
1193 in | 1232 in |
1194 ("_", SOME (TRecord (CRecord [], loc), loc), eapps) | 1233 ((PVar "_", loc), SOME (TRecord (CRecord [], loc), loc), eapps) |
1195 end) | 1234 end) |
1196 | 1235 |
1197 eargs : earg (earg) | 1236 eargs : earg (earg) |
1198 | eargl (eargl) | 1237 | eargl (eargl) |
1199 | 1238 |
1287 | LPAREN etuple RPAREN (let | 1326 | LPAREN etuple RPAREN (let |
1288 val loc = s (LPARENleft, RPARENright) | 1327 val loc = s (LPARENleft, RPARENright) |
1289 in | 1328 in |
1290 (ERecord (ListUtil.mapi (fn (i, e) => | 1329 (ERecord (ListUtil.mapi (fn (i, e) => |
1291 ((CName (Int.toString (i + 1)), loc), | 1330 ((CName (Int.toString (i + 1)), loc), |
1292 e)) etuple), loc) | 1331 e)) etuple, false), loc) |
1293 end) | 1332 end) |
1294 | 1333 |
1295 | path (EVar (#1 path, #2 path, Infer), s (pathleft, pathright)) | 1334 | path (EVar (#1 path, #2 path, Infer), s (pathleft, pathright)) |
1296 | cpath (EVar (#1 cpath, #2 cpath, Infer), s (cpathleft, cpathright)) | 1335 | cpath (EVar (#1 cpath, #2 cpath, Infer), s (cpathleft, cpathright)) |
1297 | AT path (EVar (#1 path, #2 path, TypesOnly), s (ATleft, pathright)) | 1336 | AT path (EVar (#1 path, #2 path, TypesOnly), s (ATleft, pathright)) |
1298 | AT AT path (EVar (#1 path, #2 path, DontInfer), s (AT1left, pathright)) | 1337 | AT AT path (EVar (#1 path, #2 path, DontInfer), s (AT1left, pathright)) |
1299 | AT cpath (EVar (#1 cpath, #2 cpath, TypesOnly), s (ATleft, cpathright)) | 1338 | AT cpath (EVar (#1 cpath, #2 cpath, TypesOnly), s (ATleft, cpathright)) |
1300 | AT AT cpath (EVar (#1 cpath, #2 cpath, DontInfer), s (AT1left, cpathright)) | 1339 | AT AT cpath (EVar (#1 cpath, #2 cpath, DontInfer), s (AT1left, cpathright)) |
1301 | LBRACE rexp RBRACE (ERecord rexp, s (LBRACEleft, RBRACEright)) | 1340 | LBRACE rexp RBRACE (ERecord rexp, s (LBRACEleft, RBRACEright)) |
1302 | UNIT (ERecord [], s (UNITleft, UNITright)) | 1341 | LBRACE RBRACE (ERecord ([], false), s (LBRACEleft, RBRACEright)) |
1342 | UNIT (ERecord ([], false), s (UNITleft, UNITright)) | |
1303 | 1343 |
1304 | INT (EPrim (Prim.Int INT), s (INTleft, INTright)) | 1344 | INT (EPrim (Prim.Int INT), s (INTleft, INTright)) |
1305 | FLOAT (EPrim (Prim.Float FLOAT), s (FLOATleft, FLOATright)) | 1345 | FLOAT (EPrim (Prim.Float FLOAT), s (FLOATleft, FLOATright)) |
1306 | STRING (EPrim (Prim.String STRING), s (STRINGleft, STRINGright)) | 1346 | STRING (EPrim (Prim.String STRING), s (STRINGleft, STRINGright)) |
1307 | CHAR (EPrim (Prim.Char CHAR), s (CHARleft, CHARright)) | 1347 | CHAR (EPrim (Prim.Char CHAR), s (CHARleft, CHARright)) |
1384 ErrorMsg.errorAt loc ("Length mismatch in INSERT field specification (" | 1424 ErrorMsg.errorAt loc ("Length mismatch in INSERT field specification (" |
1385 ^ Int.toString (length fields) | 1425 ^ Int.toString (length fields) |
1386 ^ " vs. " ^ Int.toString (length sqlexps) ^ ")") | 1426 ^ " vs. " ^ Int.toString (length sqlexps) ^ ")") |
1387 else | 1427 else |
1388 (); | 1428 (); |
1389 (EApp (e, (ERecord (ListPair.zip (fields, sqlexps)), loc)), loc) | 1429 (EApp (e, (ERecord (ListPair.zip (fields, sqlexps), false), loc)), loc) |
1390 end) | 1430 end) |
1391 | LPAREN enterDml UPDATE texp SET fsets CWHERE sqlexp leaveDml RPAREN | 1431 | LPAREN enterDml UPDATE texp SET fsets CWHERE sqlexp leaveDml RPAREN |
1392 (let | 1432 (let |
1393 val loc = s (LPARENleft, RPARENright) | 1433 val loc = s (LPARENleft, RPARENright) |
1394 | 1434 |
1395 val e = (EVar (["Basis"], "update", Infer), loc) | 1435 val e = (EVar (["Basis"], "update", Infer), loc) |
1396 val e = (ECApp (e, (CWild (KRecord (KType, loc), loc), loc)), loc) | 1436 val e = (ECApp (e, (CWild (KRecord (KType, loc), loc), loc)), loc) |
1397 val e = (EApp (e, (ERecord fsets, loc)), loc) | 1437 val e = (EApp (e, (ERecord (fsets, false), loc)), loc) |
1398 val e = (EApp (e, texp), loc) | 1438 val e = (EApp (e, texp), loc) |
1399 in | 1439 in |
1400 (EApp (e, sqlexp), loc) | 1440 (EApp (e, sqlexp), loc) |
1401 end) | 1441 end) |
1402 | LPAREN enterDml DELETE FROM texp CWHERE sqlexp leaveDml RPAREN | 1442 | LPAREN enterDml DELETE FROM texp CWHERE sqlexp leaveDml RPAREN |
1484 | INT EQ pat COMMA rpat ((Int64.toString INT, pat) :: #1 rpat, #2 rpat) | 1524 | INT EQ pat COMMA rpat ((Int64.toString INT, pat) :: #1 rpat, #2 rpat) |
1485 | 1525 |
1486 ptuple : pat COMMA pat ([pat1, pat2]) | 1526 ptuple : pat COMMA pat ([pat1, pat2]) |
1487 | pat COMMA ptuple (pat :: ptuple) | 1527 | pat COMMA ptuple (pat :: ptuple) |
1488 | 1528 |
1489 rexp : ([]) | 1529 rexp : DOTDOTDOT ([], true) |
1490 | ident EQ eexp ([(ident, eexp)]) | 1530 | ident EQ eexp ([(ident, eexp)], false) |
1491 | ident EQ eexp COMMA rexp ((ident, eexp) :: rexp) | 1531 | ident EQ eexp COMMA rexp ((ident, eexp) :: #1 rexp, #2 rexp) |
1492 | 1532 |
1493 xml : xmlOne xml (let | 1533 xml : xmlOne xml (let |
1494 val pos = s (xmlOneleft, xmlright) | 1534 val pos = s (xmlOneleft, xmlright) |
1495 in | 1535 in |
1496 (EApp ((EApp ( | 1536 (EApp ((EApp ( |
1624 end) (doOne data) datas | 1664 end) (doOne data) datas |
1625 in | 1665 in |
1626 ((CName "Data", pos), datas') :: #6 attrs | 1666 ((CName "Data", pos), datas') :: #6 attrs |
1627 end | 1667 end |
1628 | 1668 |
1629 val e = (EApp (e, (ERecord atts, pos)), pos) | 1669 val e = (EApp (e, (ERecord (atts, false), pos)), pos) |
1630 val e = (EApp (e, (EApp (#2 tagHead, | 1670 val e = (EApp (e, (EApp (#2 tagHead, |
1631 (ERecord [], pos)), pos)), pos) | 1671 (ERecord ([], false), pos)), pos)), pos) |
1632 in | 1672 in |
1633 (tagHead, #1 attrs, #2 attrs, e) | 1673 (tagHead, #1 attrs, #2 attrs, e) |
1634 end) | 1674 end) |
1635 | 1675 |
1636 tagHead: BEGIN_TAG (let | 1676 tagHead: BEGIN_TAG (let |
1706 | LBRACE eexp RBRACE (eexp) | 1746 | LBRACE eexp RBRACE (eexp) |
1707 | 1747 |
1708 query : query1 obopt lopt ofopt (let | 1748 query : query1 obopt lopt ofopt (let |
1709 val loc = s (query1left, query1right) | 1749 val loc = s (query1left, query1right) |
1710 | 1750 |
1711 val re = (ERecord [((CName "Rows", loc), | 1751 val re = (ERecord ([((CName "Rows", loc), |
1712 query1), | 1752 query1), |
1713 ((CName "OrderBy", loc), | 1753 ((CName "OrderBy", loc), |
1714 obopt), | 1754 obopt), |
1715 ((CName "Limit", loc), | 1755 ((CName "Limit", loc), |
1716 lopt), | 1756 lopt), |
1717 ((CName "Offset", loc), | 1757 ((CName "Offset", loc), |
1718 ofopt)], loc) | 1758 ofopt)], false), loc) |
1719 in | 1759 in |
1720 (EApp ((EVar (["Basis"], "sql_query", Infer), loc), re), loc) | 1760 (EApp ((EVar (["Basis"], "sql_query", Infer), loc), re), loc) |
1721 end) | 1761 end) |
1722 | 1762 |
1723 dopt : (EVar (["Basis"], "False", Infer), dummy) | 1763 dopt : (EVar (["Basis"], "False", Infer), dummy) |
1794 end | 1834 end |
1795 | 1835 |
1796 val e = (EVar (["Basis"], "sql_query1", Infer), loc) | 1836 val e = (EVar (["Basis"], "sql_query1", Infer), loc) |
1797 val e = (ECApp (e, (CRecord (map (fn nm => (nm, (CUnit, loc))) empties), | 1837 val e = (ECApp (e, (CRecord (map (fn nm => (nm, (CUnit, loc))) empties), |
1798 loc)), loc) | 1838 loc)), loc) |
1799 val re = (ERecord [((CName "Distinct", loc), | 1839 val re = (ERecord ([((CName "Distinct", loc), |
1800 dopt), | 1840 dopt), |
1801 ((CName "From", loc), | 1841 ((CName "From", loc), |
1802 #2 tables), | 1842 #2 tables), |
1803 ((CName "Where", loc), | 1843 ((CName "Where", loc), |
1804 wopt), | 1844 wopt), |
1805 ((CName "GroupBy", loc), | 1845 ((CName "GroupBy", loc), |
1806 grp), | 1846 grp), |
1807 ((CName "Having", loc), | 1847 ((CName "Having", loc), |
1808 hopt), | 1848 hopt), |
1809 ((CName "SelectFields", loc), | 1849 ((CName "SelectFields", loc), |
1810 (ECApp ((EVar (["Basis"], "sql_subset", Infer), loc), | 1850 (ECApp ((EVar (["Basis"], "sql_subset", Infer), loc), |
1811 sel), loc)), | 1851 sel), loc)), |
1812 ((CName "SelectExps", loc), | 1852 ((CName "SelectExps", loc), |
1813 (ERecord exps, loc))], loc) | 1853 (ERecord (exps, false), loc))], false), loc) |
1814 | 1854 |
1815 val e = (EApp (e, re), loc) | 1855 val e = (EApp (e, re), loc) |
1816 in | 1856 in |
1817 e | 1857 e |
1818 end) | 1858 end) |