diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cjr.sml | 16 | ||||
-rw-r--r-- | src/cjr_env.sig | 2 | ||||
-rw-r--r-- | src/cjr_env.sml | 13 | ||||
-rw-r--r-- | src/cjr_print.sml | 63 | ||||
-rw-r--r-- | src/cjrize.sml | 43 |
5 files changed, 127 insertions, 10 deletions
diff --git a/src/cjr.sml b/src/cjr.sml index 59f5cb2f..eb035e40 100644 --- a/src/cjr.sml +++ b/src/cjr.sml @@ -38,10 +38,24 @@ datatype typ' = withtype typ = typ' located +datatype patCon = + PConVar of int + | PConFfi of string * string + +datatype pat' = + PWild + | PVar of string + | PPrim of Prim.t + | PCon of patCon * pat option + | PRecord of (string * pat) list + +withtype pat = pat' located + datatype exp' = EPrim of Prim.t | ERel of int | ENamed of int + | ECon of int * exp option | EFfi of string * string | EFfiApp of string * string * exp list | EApp of exp * exp @@ -49,6 +63,8 @@ datatype exp' = | ERecord of int * (string * exp) list | EField of exp * string + | ECase of exp * (pat * exp) list * typ + | EWrite of exp | ESeq of exp * exp diff --git a/src/cjr_env.sig b/src/cjr_env.sig index 5cd5cb32..7573c75e 100644 --- a/src/cjr_env.sig +++ b/src/cjr_env.sig @@ -39,6 +39,8 @@ signature CJR_ENV = sig val pushDatatype : env -> string -> int -> (string * int * Cjr.typ option) list -> env val lookupDatatype : env -> int -> string * (string * int * Cjr.typ option) list + val lookupConstructor : env -> int -> string * Cjr.typ option * int + val pushERel : env -> string -> Cjr.typ -> env val lookupERel : env -> int -> string * Cjr.typ val listERels : env -> (string * Cjr.typ) list diff --git a/src/cjr_env.sml b/src/cjr_env.sml index 84f13f4d..f972a80e 100644 --- a/src/cjr_env.sml +++ b/src/cjr_env.sml @@ -39,6 +39,7 @@ exception UnboundStruct of int type env = { datatypes : (string * (string * int * typ option) list) IM.map, + constructors : (string * typ option * int) IM.map, numRelE : int, relE : (string * typ) list, @@ -49,6 +50,7 @@ type env = { val empty = { datatypes = IM.empty, + constructors = IM.empty, numRelE = 0, relE = [], @@ -59,6 +61,9 @@ val empty = { fun pushDatatype (env : env) x n xncs = {datatypes = IM.insert (#datatypes env, n, (x, xncs)), + constructors = foldl (fn ((x, n, to), constructors) => + IM.insert (constructors, n, (x, to, n))) + (#constructors env) xncs, numRelE = #numRelE env, relE = #relE env, @@ -71,8 +76,14 @@ fun lookupDatatype (env : env) n = NONE => raise UnboundNamed n | SOME x => x +fun lookupConstructor (env : env) n = + case IM.find (#constructors env, n) of + NONE => raise UnboundNamed n + | SOME x => x + fun pushERel (env : env) x t = {datatypes = #datatypes env, + constructors = #constructors env, numRelE = #numRelE env + 1, relE = (x, t) :: #relE env, @@ -90,6 +101,7 @@ fun listERels (env : env) = #relE env fun pushENamed (env : env) x n t = {datatypes = #datatypes env, + constructors = #constructors env, numRelE = #numRelE env, relE = #relE env, @@ -104,6 +116,7 @@ fun lookupENamed (env : env) n = fun pushStruct (env : env) n xts = {datatypes = #datatypes env, + constructors = #constructors env, numRelE = #numRelE env, relE = #relE env, diff --git a/src/cjr_print.sml b/src/cjr_print.sml index b0ea7214..61b2d6ce 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -90,6 +90,51 @@ fun p_exp' par env (e, _) = EPrim p => Prim.p_t p | ERel n => p_rel env n | ENamed n => p_enamed env n + | ECon (n, eo) => + let + val (x, _, dn) = E.lookupConstructor env n + val (dx, _) = E.lookupDatatype env dn + in + box [string "{(", + newline, + string "struct", + space, + string "__lwd_", + string dx, + string "_", + string (Int.toString dn), + space, + string "*tmp", + space, + string "=", + space, + string "lw_malloc(ctx, sizeof(struct __lwd_", + string dx, + string "_", + string (Int.toString dn), + string "));", + newline, + string "tmp->tag", + space, + string "=", + space, + string ("__lwc_" ^ x ^ "_" ^ Int.toString n), + string ";", + newline, + case eo of + NONE => box [] + | SOME e => box [string "tmp->data.", + string x, + space, + string "=", + space, + p_exp env e, + string ";", + newline], + string "tmp;", + newline, + string "})"] + end | EFfi (m, x) => box [string "lw_", string m, string "_", string x] | EFfiApp (m, x, es) => box [string "lw_", @@ -121,7 +166,7 @@ fun p_exp' par env (e, _) = space, string ("__lws_" ^ Int.toString i), space, - string "__lw_tmp", + string "tmp", space, string "=", space, @@ -130,7 +175,7 @@ fun p_exp' par env (e, _) = p_exp env e) xes, string "};", space, - string "__lw_tmp;", + string "tmp;", space, string "})" ] | EField (e, x) => @@ -138,6 +183,8 @@ fun p_exp' par env (e, _) = string ".", string x] + | ECase _ => raise Fail "CjrPrint ECase" + | EWrite e => box [string "(lw_write(ctx, ", p_exp env e, string "), lw_unit_v)"] @@ -430,7 +477,7 @@ fun p_file env (ds, ps) = string "__lws_", string (Int.toString i), space, - string "__lw_tmp", + string "tmp", space, string "=", space, @@ -440,7 +487,7 @@ fun p_file env (ds, ps) = space, string "};", newline, - string "__lw_tmp;", + string "tmp;", newline, string "})"] end @@ -467,13 +514,13 @@ fun p_file env (ds, ps) = space, string ("__lwd_" ^ x ^ "_" ^ Int.toString i), space, - string "*__lw_tmp = lw_malloc(ctx, sizeof(struct __lwd_", + string "*tmp = lw_malloc(ctx, sizeof(struct __lwd_", string x, string "_", string (Int.toString i), string "));", newline, - string "__lw_tmp->tag", + string "tmp->tag", space, string "=", space, @@ -491,7 +538,7 @@ fun p_file env (ds, ps) = newline, case to of NONE => box [] - | SOME t => box [string "__lw_tmp->data.", + | SOME t => box [string "tmp->data.", string x', space, string "=", @@ -499,7 +546,7 @@ fun p_file env (ds, ps) = unurlify t, string ";", newline], - string "__lw_tmp;", + string "tmp;", newline, string "})", space, diff --git a/src/cjrize.sml b/src/cjrize.sml index ac3563f0..7830e740 100644 --- a/src/cjrize.sml +++ b/src/cjrize.sml @@ -103,12 +103,38 @@ fun cifyTyp ((t, loc), sm) = val dummye = (L'.EPrim (Prim.Int 0), ErrorMsg.dummySpan) +fun cifyPatCon pc = + case pc of + L.PConVar n => L'.PConVar n + | L.PConFfi mx => L'.PConFfi mx + +fun cifyPat (p, loc) = + case p of + L.PWild => (L'.PWild, loc) + | L.PVar x => (L'.PVar x, loc) + | L.PPrim p => (L'.PPrim p, loc) + | L.PCon (pc, po) => (L'.PCon (cifyPatCon pc, Option.map cifyPat po), loc) + | L.PRecord xps => (L'.PRecord (map (fn (x, p) => (x, cifyPat p)) xps), loc) + fun cifyExp ((e, loc), sm) = case e of L.EPrim p => ((L'.EPrim p, loc), sm) | L.ERel n => ((L'.ERel n, loc), sm) | L.ENamed n => ((L'.ENamed n, loc), sm) - | L.ECon _ => raise Fail "Cjrize ECon" + | L.ECon (n, eo) => + let + val (eo, sm) = + case eo of + NONE => (NONE, sm) + | SOME e => + let + val (e, sm) = cifyExp (e, sm) + in + (SOME e, sm) + end + in + ((L'.ECon (n, eo), loc), sm) + end | L.EFfi mx => ((L'.EFfi mx, loc), sm) | L.EFfiApp (m, x, es) => let @@ -153,7 +179,20 @@ fun cifyExp ((e, loc), sm) = ((L'.EField (e, x), loc), sm) end - | L.ECase _ => raise Fail "Cjrize ECase" + | L.ECase (e, pes, t) => + let + val (e, sm) = cifyExp (e, sm) + val (pes, sm) = ListUtil.foldlMap + (fn ((p, e), sm) => + let + val (e, sm) = cifyExp (e, sm) + in + ((cifyPat p, e), sm) + end) sm pes + val (t, sm) = cifyTyp (t, sm) + in + ((L'.ECase (e, pes, t), loc), sm) + end | L.EStrcat (e1, e2) => let |