Mercurial > urweb
changeset 156:34ccd7d2bea8
Start of datatype support
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 24 Jul 2008 15:02:03 -0400 |
parents | 4334bb734187 |
children | adc4e42e3adc |
files | src/elab.sml src/elab_env.sml src/elab_print.sml src/elab_util.sml src/elaborate.sml src/explify.sml src/lacweb.grm src/lacweb.lex src/source.sml src/source_print.sml tests/datatype.lac |
diffstat | 11 files changed, 365 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/elab.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/elab.sml Thu Jul 24 15:02:03 2008 -0400 @@ -93,6 +93,8 @@ datatype sgn_item' = SgiConAbs of string * int * kind | SgiCon of string * int * kind * con + | SgiDatatype of string * int * (string * int * con option) list + | SgiDatatypeImp of string * int * int * string list * string | SgiVal of string * int * con | SgiStr of string * int * sgn | SgiSgn of string * int * sgn @@ -111,6 +113,8 @@ datatype decl' = DCon of string * int * kind * con + | DDatatype of string * int * (string * int * con option) list + | DDatatypeImp of string * int * int * string list * string | DVal of string * int * con * exp | DValRec of (string * int * con * exp) list | DSgn of string * int * sgn
--- a/src/elab_env.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/elab_env.sml Thu Jul 24 15:02:03 2008 -0400 @@ -292,9 +292,18 @@ fun lookupStr (env : env) x = SM.find (#renameStr env, x) -fun declBinds env (d, _) = +fun declBinds env (d, loc) = case d of DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) + | DDatatype (x, n, xncs) => + let + val env = pushCNamedAs env x n (KType, loc) NONE + in + foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) + | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) + env xncs + end + | DDatatypeImp (x, n, m, ms, x') => pushCNamedAs env x n (KType, loc) (SOME (CModProj (m, ms, x'), loc)) | DVal (x, n, t, _) => pushENamedAs env x n t | DValRec vis => foldl (fn ((x, n, t, _), env) => pushENamedAs env x n t) env vis | DSgn (x, n, sgn) => pushSgnNamedAs env x n sgn @@ -303,10 +312,19 @@ | DConstraint _ => env | DExport _ => env -fun sgiBinds env (sgi, _) = +fun sgiBinds env (sgi, loc) = case sgi of SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) + | SgiDatatype (x, n, xncs) => + let + val env = pushCNamedAs env x n (KType, loc) NONE + in + foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) + | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) + env xncs + end + | SgiDatatypeImp (x, n, m1, ms, x') => pushCNamedAs env x n (KType, loc) (SOME (CModProj (m1, ms, x'), loc)) | SgiVal (x, n, t) => pushENamedAs env x n t | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn | SgiSgn (x, n, sgn) => pushSgnNamedAs env x n sgn @@ -324,6 +342,8 @@ case sgi of SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) + | SgiDatatype (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) + | SgiDatatypeImp (x, n, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) | SgiVal _ => seek (sgis, sgns, strs, cons) | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons) | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons) @@ -489,6 +509,8 @@ end | SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) + | SgiDatatype (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) + | SgiDatatypeImp (x, n, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) | SgiVal _ => seek (sgis, sgns, strs, cons, acc) | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons, acc) | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons, acc)
--- a/src/elab_print.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/elab_print.sml Thu Jul 24 15:02:03 2008 -0400 @@ -309,6 +309,22 @@ else string x +fun p_datatype env (x, n, cons) = + let + val env = E.pushCNamedAs env x n (KType, ErrorMsg.dummySpan) NONE + in + box [string "datatype", + space, + string x, + space, + string "=", + space, + p_list_sep (box [space, string "|", space]) + (fn (x, _, NONE) => string x + | (x, _, SOME t) => box [string x, space, string "of", space, p_con env t]) + cons] + end + fun p_sgn_item env (sgi, _) = case sgi of SgiConAbs (x, n, k) => box [string "con", @@ -329,6 +345,22 @@ string "=", space, p_con env c] + | SgiDatatype x => p_datatype env x + | SgiDatatypeImp (x, _, m1, ms, x') => + let + val m1x = #1 (E.lookupStrNamed env m1) + handle E.UnboundNamed _ => "UNBOUND_STR_" ^ Int.toString m1 + in + box [string "datatype", + space, + string x, + space, + string "=", + space, + string "datatype", + space, + p_list_sep (string ".") string (m1x :: ms @ [x'])] + end | SgiVal (x, n, c) => box [string "val", space, p_named x n, @@ -435,6 +467,22 @@ string "=", space, p_con env c] + | DDatatype x => p_datatype env x + | DDatatypeImp (x, _, m1, ms, x') => + let + val m1x = #1 (E.lookupStrNamed env m1) + handle E.UnboundNamed _ => "UNBOUND_STR_" ^ Int.toString m1 + in + box [string "datatype", + space, + string x, + space, + string "=", + space, + string "datatype", + space, + p_list_sep (string ".") string (m1x :: ms @ [x'])] + end | DVal vi => box [string "val", space, p_vali env vi]
--- a/src/elab_util.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/elab_util.sml Thu Jul 24 15:02:03 2008 -0400 @@ -365,7 +365,7 @@ fun sgi ctx si acc = S.bindP (sgi' ctx si acc, sgn_item ctx) - and sgi' ctx (si, loc) = + and sgi' ctx (siAll as (si, loc)) = case si of SgiConAbs (x, n, k) => S.map2 (kind k, @@ -377,6 +377,16 @@ S.map2 (con ctx c, fn c' => (SgiCon (x, n, k', c'), loc))) + | SgiDatatype (x, n, xncs) => + S.map2 (ListUtil.mapfold (fn (x, n, c) => + case c of + NONE => S.return2 (x, n, c) + | SOME c => + S.map2 (con ctx c, + fn c' => (x, n, SOME c'))) xncs, + fn xncs' => + (SgiDatatype (x, n, xncs'), loc)) + | SgiDatatypeImp _ => S.return2 siAll | SgiVal (x, n, c) => S.map2 (con ctx c, fn c' => @@ -408,6 +418,10 @@ bind (ctx, NamedC (x, k)) | SgiCon (x, _, k, _) => bind (ctx, NamedC (x, k)) + | SgiDatatype (x, n, xncs) => + bind (ctx, NamedC (x, (KType, loc))) + | SgiDatatypeImp (x, _, _, _, _) => + bind (ctx, NamedC (x, (KType, loc))) | SgiVal _ => ctx | SgiStr (x, _, sgn) => bind (ctx, Str (x, sgn)) @@ -512,6 +526,23 @@ (case #1 d of DCon (x, _, k, _) => bind (ctx, NamedC (x, k)) + | DDatatype (x, n, xncs) => + let + val ctx = bind (ctx, NamedC (x, (KType, loc))) + in + foldl (fn ((x, _, co), ctx) => + let + val t = + case co of + NONE => CNamed n + | SOME t => TFun (t, (CNamed n, loc)) + in + bind (ctx, NamedE (x, (t, loc))) + end) + ctx xncs + end + | DDatatypeImp (x, n, m, ms, x') => + bind (ctx, NamedC (x, (KType, loc))) | DVal (x, _, c, _) => bind (ctx, NamedE (x, c)) | DValRec vis => @@ -558,6 +589,16 @@ S.map2 (mfc ctx c, fn c' => (DCon (x, n, k', c'), loc))) + | DDatatype (x, n, xncs) => + S.map2 (ListUtil.mapfold (fn (x, n, c) => + case c of + NONE => S.return2 (x, n, c) + | SOME c => + S.map2 (mfc ctx c, + fn c' => (x, n, SOME c'))) xncs, + fn xncs' => + (DDatatype (x, n, xncs'), loc)) + | DDatatypeImp _ => S.return2 dAll | DVal vi => S.map2 (mfvi ctx vi, fn vi' =>
--- a/src/elaborate.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/elaborate.sml Thu Jul 24 15:02:03 2008 -0400 @@ -1158,6 +1158,7 @@ | UnmatchedSgi of L'.sgn_item | SgiWrongKind of L'.sgn_item * L'.kind * L'.sgn_item * L'.kind * kunify_error | SgiWrongCon of L'.sgn_item * L'.con * L'.sgn_item * L'.con * cunify_error + | SgiMismatchedDatatypes of L'.sgn_item * L'.sgn_item * (L'.con * L'.con * cunify_error) option | SgnWrongForm of L'.sgn * L'.sgn | UnWhereable of L'.sgn * string | WhereWrongKind of L'.kind * L'.kind * kunify_error @@ -1189,6 +1190,15 @@ ("Con 1", p_con env c1), ("Con 2", p_con env c2)]; cunifyError env cerr) + | SgiMismatchedDatatypes (sgi1, sgi2, cerro) => + (ErrorMsg.errorAt (#2 sgi1) "Mismatched 'datatype' specifications:"; + eprefaces' [("Have", p_sgn_item env sgi1), + ("Need", p_sgn_item env sgi2)]; + Option.app (fn (c1, c2, ue) => + (eprefaces "Unification error" + [("Con 1", p_con env c1), + ("Con 2", p_con env c2)]; + cunifyError env ue)) cerro) | SgnWrongForm (sgn1, sgn2) => (ErrorMsg.errorAt (#2 sgn1) "Incompatible signatures:"; eprefaces' [("Sig 1", p_sgn env sgn1), @@ -1223,6 +1233,7 @@ | FunctorRebind of ErrorMsg.span | UnOpenable of L'.sgn | NotType of L'.kind * (L'.kind * L'.kind * kunify_error) + | DuplicateConstructor of string * ErrorMsg.span fun strError env err = case err of @@ -1242,6 +1253,8 @@ ("Subkind 1", p_kind k1), ("Subkind 2", p_kind k2)]; kunifyError ue) + | DuplicateConstructor (x, loc) => + ErrorMsg.errorAt loc ("Duplicate datatype constructor " ^ x) val hnormSgn = E.hnormSgn @@ -1270,6 +1283,10 @@ ([(L'.SgiCon (x, n, k', c'), loc)], (env', denv, gs' @ gs)) end + | L.SgiDatatype _ => raise Fail "Elaborate SgiDatatype" + + | L.SgiDatatypeImp _ => raise Fail "Elaborate SgiDatatypeImp" + | L.SgiVal (x, c) => let val (c', ck, gs') = elabCon (env, denv) c @@ -1342,6 +1359,28 @@ else (); (SS.add (cons, x), vals, sgns, strs)) + | L'.SgiDatatype (x, _, xncs) => + let + val vals = foldl (fn ((x, _, _), vals) => + (if SS.member (vals, x) then + sgnError env (DuplicateVal (loc, x)) + else + (); + SS.add (vals, x))) + vals xncs + in + if SS.member (cons, x) then + sgnError env (DuplicateCon (loc, x)) + else + (); + (SS.add (cons, x), vals, sgns, strs) + end + | L'.SgiDatatypeImp (x, _, _, _, _) => + (if SS.member (cons, x) then + sgnError env (DuplicateCon (loc, x)) + else + (); + (SS.add (cons, x), vals, sgns, strs)) | L'.SgiVal (x, _, _) => (if SS.member (vals, x) then sgnError env (DuplicateVal (loc, x)) @@ -1476,6 +1515,22 @@ | L'.SgiCon (x, n, k, c) => ((L'.DCon (x, n, k, (L'.CModProj (str, strs, x), loc)), loc), (E.pushCNamedAs env' x n k (SOME c), denv')) + | L'.SgiDatatype (x, n, xncs) => + let + val k = (L'.KType, loc) + val c = (L'.CModProj (str, strs, x), loc) + in + ((L'.DDatatypeImp (x, n, str, strs, x), loc), + (E.pushCNamedAs env' x n k (SOME c), denv')) + end + | L'.SgiDatatypeImp (x, n, m1, ms, x') => + let + val k = (L'.KType, loc) + val c = (L'.CModProj (m1, ms, x'), loc) + in + ((L'.DCon (x, n, k, (L'.CModProj (str, strs, x), loc)), loc), + (E.pushCNamedAs env' x n k (SOME c), denv')) + end | L'.SgiVal (x, n, t) => ((L'.DVal (x, n, t, (L'.EModProj (str, strs, x), loc)), loc), (E.pushENamedAs env' x n t, denv')) @@ -1487,7 +1542,7 @@ (E.pushSgnNamedAs env' x n sgn, denv')) | L'.SgiConstraint (c1, c2) => ((L'.DConstraint (c1, c2), loc), - (env', denv (* D.assert env denv (c1, c2) *) ))) + (env', denv))) (env, denv) sgis | _ => (strError env (UnOpenable sgn); ([], (env, denv))) @@ -1528,6 +1583,8 @@ fun sgiOfDecl (d, loc) = case d of L'.DCon (x, n, k, c) => [(L'.SgiCon (x, n, k, c), loc)] + | L'.DDatatype x => [(L'.SgiDatatype x, loc)] + | L'.DDatatypeImp x => [(L'.SgiDatatypeImp x, loc)] | L'.DVal (x, n, t, _) => [(L'.SgiVal (x, n, t), loc)] | L'.DValRec vis => map (fn (x, n, t, _) => (L'.SgiVal (x, n, t), loc)) vis | L'.DSgn (x, n, sgn) => [(L'.SgiSgn (x, n, sgn), loc)] @@ -1551,7 +1608,7 @@ | (L'.SgnConst sgis1, L'.SgnConst sgis2) => let - fun folder (sgi2All as (sgi, _), (env, denv)) = + fun folder (sgi2All as (sgi, loc), (env, denv)) = let fun seek p = let @@ -1613,6 +1670,49 @@ NONE | _ => NONE) + | L'.SgiDatatype (x, n2, xncs2) => + seek (fn sgi1All as (sgi1, _) => + case sgi1 of + L'.SgiDatatype (x', n1, xncs1) => + let + fun mismatched ue = + (sgnError env (SgiMismatchedDatatypes (sgi1All, sgi2All, ue)); + SOME (env, denv)) + + fun good () = + let + val env = E.sgiBinds env sgi2All + val env = if n1 = n2 then + env + else + E.pushCNamedAs env x n1 (L'.KType, loc) + (SOME (L'.CNamed n1, loc)) + in + SOME (env, denv) + end + + fun xncBad ((x1, _, t1), (x2, _, t2)) = + String.compare (x1, x2) <> EQUAL + orelse case (t1, t2) of + (NONE, NONE) => false + | (SOME t1, SOME t2) => + not (List.null (unifyCons (env, denv) t1 t2)) + | _ => true + in + (if x = x' then + if length xncs1 <> length xncs2 + orelse ListPair.exists xncBad (xncs1, xncs2) then + mismatched NONE + else + good () + else + NONE) + handle CUnify ue => mismatched (SOME ue) + end + | _ => NONE) + + | L'.SgiDatatypeImp _ => raise Fail "SgiDatatypeImp in subsgn" + | L'.SgiVal (x, n2, c2) => seek (fn sgi1All as (sgi1, _) => case sgi1 of @@ -1722,6 +1822,40 @@ ([(L'.DCon (x, n, k', c'), loc)], (env', denv, gs' @ gs)) end + | L.DDatatype (x, xcs) => + let + val k = (L'.KType, loc) + val (env, n) = E.pushCNamed env x k NONE + val t = (L'.CNamed n, loc) + + val (xcs, (used, env, gs)) = + ListUtil.foldlMap + (fn ((x, to), (used, env, gs)) => + let + val (to, t, gs') = case to of + NONE => (NONE, t, gs) + | SOME t' => + let + val (t', tk, gs') = elabCon (env, denv) t' + in + checkKind env t' tk k; + (SOME t', (L'.TFun (t', t), loc), gs' @ gs) + end + + val (env, n') = E.pushENamed env x t + in + if SS.member (used, x) then + strError env (DuplicateConstructor (x, loc)) + else + (); + ((x, n', to), (SS.add (used, x), env, gs')) + end) + (SS.empty, env, []) xcs + in + ([(L'.DDatatype (x, n, xcs), loc)], (env, denv, gs)) + end + + | L.DDatatypeImp _ => raise Fail "Elaborate DDatatypeImp" | L.DVal (x, co, e) => let val (c', _, gs1) = case co of @@ -1975,6 +2109,35 @@ in ((L'.SgiCon (x, n, k, c), loc) :: sgis, cons, vals, sgns, strs) end + | L'.SgiDatatype (x, n, xncs) => + let + val (cons, x) = + if SS.member (cons, x) then + (cons, "?" ^ x) + else + (SS.add (cons, x), x) + + val (xncs, vals) = + ListUtil.foldlMap + (fn ((x, n, t), vals) => + if SS.member (vals, x) then + (("?" ^ x, n, t), vals) + else + ((x, n, t), SS.add (vals, x))) + vals xncs + in + ((L'.SgiDatatype (x, n, xncs), loc) :: sgis, cons, vals, sgns, strs) + end + | L'.SgiDatatypeImp (x, n, m1, ms, x') => + let + val (cons, x) = + if SS.member (cons, x) then + (cons, "?" ^ x) + else + (SS.add (cons, x), x) + in + ((L'.SgiDatatypeImp (x, n, m1, ms, x'), loc) :: sgis, cons, vals, sgns, strs) + end | L'.SgiVal (x, n, c) => let val (vals, x) =
--- a/src/explify.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/explify.sml Thu Jul 24 15:02:03 2008 -0400 @@ -95,6 +95,8 @@ case sgi of L.SgiConAbs (x, n, k) => SOME (L'.SgiConAbs (x, n, explifyKind k), loc) | L.SgiCon (x, n, k, c) => SOME (L'.SgiCon (x, n, explifyKind k, explifyCon c), loc) + | L.SgiDatatype _ => raise Fail "Explify SgiDatatype" + | L.SgiDatatypeImp _ => raise Fail "Explify SgiDatatypeImp" | L.SgiVal (x, n, c) => SOME (L'.SgiVal (x, n, explifyCon c), loc) | L.SgiStr (x, n, sgn) => SOME (L'.SgiStr (x, n, explifySgn sgn), loc) | L.SgiSgn (x, n, sgn) => SOME (L'.SgiSgn (x, n, explifySgn sgn), loc) @@ -112,6 +114,8 @@ fun explifyDecl (d, loc : EM.span) = case d of L.DCon (x, n, k, c) => SOME (L'.DCon (x, n, explifyKind k, explifyCon c), loc) + | L.DDatatype _ => raise Fail "Explify DDatatype" + | L.DDatatypeImp _ => raise Fail "Explify DDatatypeImp" | L.DVal (x, n, t, e) => SOME (L'.DVal (x, n, explifyCon t, explifyExp e), loc) | L.DValRec vis => SOME (L'.DValRec (map (fn (x, n, t, e) => (x, n, explifyCon t, explifyExp e)) vis), loc)
--- a/src/lacweb.grm Thu Jul 24 11:32:01 2008 -0400 +++ b/src/lacweb.grm Thu Jul 24 15:02:03 2008 -0400 @@ -42,9 +42,10 @@ | STRING of string | INT of Int64.int | FLOAT of Real64.real | SYMBOL of string | CSYMBOL of string | LPAREN | RPAREN | LBRACK | RBRACK | LBRACE | RBRACE - | EQ | COMMA | COLON | DCOLON | TCOLON | DOT | HASH | UNDER | UNDERUNDER + | EQ | COMMA | COLON | DCOLON | TCOLON | DOT | HASH | UNDER | UNDERUNDER | BAR | DIVIDE | GT | CON | LTYPE | VAL | REC | AND | FOLD | UNIT | KUNIT + | DATATYPE | OF | TYPE | NAME | ARROW | LARROW | DARROW | FN | PLUSPLUS | MINUSMINUS | DOLLAR | TWIDDLE @@ -62,6 +63,10 @@ | vali of string * con option * exp | valis of (string * con option * exp) list + | barOpt of unit + | dcons of (string * con option) list + | dcon of string * con option + | sgn of sgn | sgntm of sgn | sgi of sgn_item @@ -73,6 +78,7 @@ | kcolon of explicitness | path of string list * string + | cpath of string list * string | spath of str | mpath of string list @@ -129,6 +135,8 @@ | CON SYMBOL DCOLON kind EQ cexp (DCon (SYMBOL, SOME kind, cexp), s (CONleft, cexpright)) | LTYPE SYMBOL EQ cexp (DCon (SYMBOL, SOME (KType, s (LTYPEleft, cexpright)), cexp), s (LTYPEleft, cexpright)) + | DATATYPE SYMBOL EQ barOpt dcons(DDatatype (SYMBOL, dcons), s (DATATYPEleft, dconsright)) + | DATATYPE SYMBOL EQ DATATYPE path(DDatatypeImp (SYMBOL, #1 path, #2 path), s (DATATYPEleft, pathright)) | VAL vali (DVal vali, s (VALleft, valiright)) | VAL REC valis (DValRec valis, s (VALleft, valisright)) @@ -153,6 +161,15 @@ | CONSTRAINT cterm TWIDDLE cterm (DConstraint (cterm1, cterm2), s (CONSTRAINTleft, ctermright)) | EXPORT spath (DExport spath, s (EXPORTleft, spathright)) +barOpt : () + | BAR () + +dcons : dcon ([dcon]) + | dcon BAR dcons (dcon :: dcons) + +dcon : CSYMBOL (CSYMBOL, NONE) + | CSYMBOL OF cexp (CSYMBOL, SOME cexp) + vali : SYMBOL EQ eexp (SYMBOL, NONE, eexp) | SYMBOL COLON cexp EQ eexp (SYMBOL, SOME cexp, eexp) @@ -182,6 +199,8 @@ | CON SYMBOL DCOLON kind EQ cexp (SgiCon (SYMBOL, SOME kind, cexp), s (CONleft, cexpright)) | LTYPE SYMBOL EQ cexp (SgiCon (SYMBOL, SOME (KType, s (LTYPEleft, cexpright)), cexp), s (LTYPEleft, cexpright)) + | DATATYPE SYMBOL EQ barOpt dcons(SgiDatatype (SYMBOL, dcons), s (DATATYPEleft, dconsright)) + | DATATYPE SYMBOL EQ DATATYPE path(SgiDatatypeImp (SYMBOL, #1 path, #2 path), s (DATATYPEleft, pathright)) | VAL SYMBOL COLON cexp (SgiVal (SYMBOL, cexp), s (VALleft, cexpright)) | STRUCTURE CSYMBOL COLON sgn (SgiStr (CSYMBOL, sgn), s (STRUCTUREleft, sgnright)) @@ -239,6 +258,9 @@ path : SYMBOL ([], SYMBOL) | CSYMBOL DOT path (let val (ms, x) = path in (CSYMBOL :: ms, x) end) +cpath : CSYMBOL ([], CSYMBOL) + | CSYMBOL DOT cpath (let val (ms, x) = cpath in (CSYMBOL :: ms, x) end) + mpath : CSYMBOL ([CSYMBOL]) | CSYMBOL DOT mpath (CSYMBOL :: mpath) @@ -290,6 +312,7 @@ eterm : LPAREN eexp RPAREN (#1 eexp, s (LPARENleft, RPARENright)) | path (EVar path, s (pathleft, pathright)) + | cpath (EVar cpath, s (cpathleft, cpathright)) | LBRACE rexp RBRACE (ERecord rexp, s (LBRACEleft, RBRACEright)) | UNIT (ERecord [], s (UNITleft, UNITright))
--- a/src/lacweb.lex Thu Jul 24 11:32:01 2008 -0400 +++ b/src/lacweb.lex Thu Jul 24 15:02:03 2008 -0400 @@ -248,9 +248,12 @@ <INITIAL> "__" => (Tokens.UNDERUNDER (pos yypos, pos yypos + size yytext)); <INITIAL> "_" => (Tokens.UNDER (pos yypos, pos yypos + size yytext)); <INITIAL> "~" => (Tokens.TWIDDLE (pos yypos, pos yypos + size yytext)); +<INITIAL> "|" => (Tokens.BAR (pos yypos, pos yypos + size yytext)); <INITIAL> "con" => (Tokens.CON (pos yypos, pos yypos + size yytext)); <INITIAL> "type" => (Tokens.LTYPE (pos yypos, pos yypos + size yytext)); +<INITIAL> "datatype" => (Tokens.DATATYPE (pos yypos, pos yypos + size yytext)); +<INITIAL> "of" => (Tokens.OF (pos yypos, pos yypos + size yytext)); <INITIAL> "val" => (Tokens.VAL (pos yypos, pos yypos + size yytext)); <INITIAL> "rec" => (Tokens.REC (pos yypos, pos yypos + size yytext)); <INITIAL> "and" => (Tokens.AND (pos yypos, pos yypos + size yytext));
--- a/src/source.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/source.sml Thu Jul 24 15:02:03 2008 -0400 @@ -71,6 +71,8 @@ datatype sgn_item' = SgiConAbs of string * kind | SgiCon of string * kind option * con + | SgiDatatype of string * (string * con option) list + | SgiDatatypeImp of string * string list * string | SgiVal of string * con | SgiStr of string * sgn | SgiSgn of string * sgn @@ -107,6 +109,8 @@ datatype decl' = DCon of string * kind option * con + | DDatatype of string * (string * con option) list + | DDatatypeImp of string * string list * string | DVal of string * con option * exp | DValRec of (string * con option * exp) list | DSgn of string * sgn
--- a/src/source_print.sml Thu Jul 24 11:32:01 2008 -0400 +++ b/src/source_print.sml Thu Jul 24 15:02:03 2008 -0400 @@ -241,6 +241,18 @@ and p_exp e = p_exp' false e +fun p_datatype (x, cons) = + box [string "datatype", + space, + string x, + space, + string "=", + space, + p_list_sep (box [space, string "|", space]) + (fn (x, NONE) => string x + | (x, SOME t) => box [string x, space, string "of", space, p_con t]) + cons] + fun p_sgn_item (sgi, _) = case sgi of SgiConAbs (x, k) => box [string "con", @@ -268,6 +280,17 @@ string "=", space, p_con c] + | SgiDatatype x => p_datatype x + | SgiDatatypeImp (x, ms, x') => + box [string "datatype", + space, + string x, + space, + string "=", + space, + string "datatype", + space, + p_list_sep (string ".") string (ms @ [x'])] | SgiVal (x, c) => box [string "val", space, string x, @@ -371,6 +394,17 @@ string "=", space, p_con c] + | DDatatype x => p_datatype x + | DDatatypeImp (x, ms, x') => + box [string "datatype", + space, + string x, + space, + string "=", + space, + string "datatype", + space, + p_list_sep (string ".") string (ms @ [x'])] | DVal vi => box [string "val", space, p_vali vi]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/datatype.lac Thu Jul 24 15:02:03 2008 -0400 @@ -0,0 +1,13 @@ +datatype t = A | B + +val a = A +val b = B + +datatype foo = C of t + +val c = C a + +datatype list = Nil | Cons of {Head : int, Tail : list} + +val nil = Nil +val l1 = Cons {Head = 0, Tail = nil}