aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/cjr.sml12
-rw-r--r--src/cjr_print.sml47
-rw-r--r--src/cjrize.sml55
3 files changed, 108 insertions, 6 deletions
diff --git a/src/cjr.sml b/src/cjr.sml
index cda7245a..e9b89bfc 100644
--- a/src/cjr.sml
+++ b/src/cjr.sml
@@ -32,8 +32,7 @@ type 'a located = 'a ErrorMsg.located
datatype datatype_kind = datatype Mono.datatype_kind
datatype typ' =
- TTop
- | TFun of typ * typ
+ TFun of typ * typ
| TRecord of int
| TDatatype of datatype_kind * int * (string * int * typ option) list ref
| TFfi of string * string
@@ -69,6 +68,15 @@ datatype exp' =
| EWrite of exp
| ESeq of exp * exp
+ | ELet of string * typ * exp * exp
+
+ | EQuery of { exps : (string * typ) list,
+ tables : (string * (string * typ) list) list,
+ rnum : int,
+ state : typ,
+ query : exp,
+ body : exp,
+ initial : exp }
withtype exp = exp' located
diff --git a/src/cjr_print.sml b/src/cjr_print.sml
index 115f09fc..4a65cd34 100644
--- a/src/cjr_print.sml
+++ b/src/cjr_print.sml
@@ -34,6 +34,8 @@ open Print
open Cjr
+val dummyt = (TRecord 0, ErrorMsg.dummySpan)
+
structure E = CjrEnv
structure EM = ErrorMsg
@@ -57,8 +59,7 @@ val dummyTyp = (TDatatype (Enum, 0, ref []), ErrorMsg.dummySpan)
fun p_typ' par env (t, loc) =
case t of
- TTop => string "void*"
- | TFun (t1, t2) => parenIf par (box [p_typ' true env t2,
+ TFun (t1, t2) => parenIf par (box [p_typ' true env t2,
space,
string "(*)",
space,
@@ -528,6 +529,48 @@ fun p_exp' par env (e, loc) =
space,
p_exp env e2,
string ")"]
+ | ELet (x, t, e1, e2) => box [string "({",
+ newline,
+ p_typ env t,
+ space,
+ p_rel env 0,
+ space,
+ string "=",
+ space,
+ p_exp env e1,
+ string ";",
+ newline,
+ p_exp (E.pushERel env x t) e2,
+ string ";",
+ newline,
+ string "})"]
+
+ | EQuery {exps, tables, rnum, state, query, body, initial} =>
+ box [string "query[",
+ p_list (fn (x, t) => box [string x, space, string ":", space, p_typ env t]) exps,
+ string "] [",
+ p_list (fn (x, xts) => box [string x,
+ space,
+ string ":",
+ space,
+ string "{",
+ p_list (fn (x, t) => box [string x, space, string ":", space, p_typ env t]) xts,
+ string "}"]) tables,
+ string "] [",
+ p_typ env state,
+ string "] [",
+ string (Int.toString rnum),
+ string "]",
+ space,
+ p_exp env query,
+ space,
+ string "initial",
+ space,
+ p_exp env initial,
+ space,
+ string "in",
+ space,
+ p_exp (E.pushERel (E.pushERel env "r" dummyt) "acc" dummyt) body]
and p_exp env = p_exp' false env
diff --git a/src/cjrize.sml b/src/cjrize.sml
index 7dbabe74..29182e2c 100644
--- a/src/cjrize.sml
+++ b/src/cjrize.sml
@@ -275,12 +275,63 @@ fun cifyExp ((e, loc), sm) =
((L'.ESeq (e1, e2), loc), sm)
end
- | L.ELet _ => raise Fail "Cjrize ELet"
+ | L.ELet (x, t, e1, e2) =>
+ let
+ val (t, sm) = cifyTyp (t, sm)
+ val (e1, sm) = cifyExp (e1, sm)
+ val (e2, sm) = cifyExp (e2, sm)
+ in
+ ((L'.ELet (x, t, e1, e2), loc), sm)
+ end
| L.EClosure _ => (ErrorMsg.errorAt loc "Nested closure remains in code generation";
(dummye, sm))
- | L.EQuery _ => raise Fail "Cjrize EQuery"
+ | L.EQuery {exps, tables, state, query, body, initial} =>
+ let
+ val (exps', sm) = ListUtil.foldlMap (fn ((x, t), sm) =>
+ let
+ val (t, sm) = cifyTyp (t, sm)
+ in
+ ((x, t), sm)
+ end) sm exps
+ val (tables', sm) = ListUtil.foldlMap (fn ((x, xts), sm) =>
+ let
+ val (xts, sm) = ListUtil.foldlMap
+ (fn ((x, t), sm) =>
+ let
+ val (t, sm) = cifyTyp (t, sm)
+ in
+ ((x, t), sm)
+ end) sm xts
+ in
+ ((x, xts), sm)
+ end) sm tables
+
+ val row = exps @ map (fn (x, xts) => (x, (L.TRecord xts, loc))) tables
+ val row = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) row
+
+ val (tableRows, sm) = ListUtil.foldlMap (fn (((x, xts), (_, xts')), sm) =>
+ let
+ val (sm, rnum) = Sm.find (sm, xts, xts')
+ in
+ ((x, rnum), sm)
+ end)
+ sm (ListPair.zip (tables, tables'))
+ val row' = exps' @ map (fn (x, n) => (x, (L'.TRecord n, loc))) tableRows
+ val row' = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) row'
+
+ val (sm, rnum) = Sm.find (sm, row, row')
+
+ val (state, sm) = cifyTyp (state, sm)
+ val (query, sm) = cifyExp (query, sm)
+ val (body, sm) = cifyExp (body, sm)
+ val (initial, sm) = cifyExp (initial, sm)
+ in
+ ((L'.EQuery {exps = exps', tables = tables', rnum = rnum, state = state,
+ query = query, body = body, initial = initial}, loc), sm)
+ end
+
fun cifyDecl ((d, loc), sm) =
case d of