summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2008-08-03 09:26:49 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2008-08-03 09:26:49 -0400
commit5e0563d3b00303d5053827e46811c93077455208 (patch)
tree84de1a0972562b31942273587987b2a27f615d8b /src
parent49c123050b2bc8a24f250fcc0d55e49484bc604c (diff)
First part of getting cases through monoize
Diffstat (limited to 'src')
-rw-r--r--src/cjrize.sml3
-rw-r--r--src/mono.sml16
-rw-r--r--src/mono_env.sig2
-rw-r--r--src/mono_env.sml12
-rw-r--r--src/mono_print.sml80
-rw-r--r--src/mono_shake.sml22
-rw-r--r--src/mono_util.sml16
-rw-r--r--src/monoize.sml19
8 files changed, 152 insertions, 18 deletions
diff --git a/src/cjrize.sml b/src/cjrize.sml
index a4f35723..1e55cfc5 100644
--- a/src/cjrize.sml
+++ b/src/cjrize.sml
@@ -108,6 +108,7 @@ fun cifyExp ((e, loc), sm) =
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.EFfi mx => ((L'.EFfi mx, loc), sm)
| L.EFfiApp (m, x, es) =>
let
@@ -152,6 +153,8 @@ fun cifyExp ((e, loc), sm) =
((L'.EField (e, x), loc), sm)
end
+ | L.ECase _ => raise Fail "Cjrize ECase"
+
| L.EStrcat _ => raise Fail "Cjrize EStrcat"
| L.EWrite e =>
diff --git a/src/mono.sml b/src/mono.sml
index b1636775..7ed1aca1 100644
--- a/src/mono.sml
+++ b/src/mono.sml
@@ -37,10 +37,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 (string * exp * typ) list
| EField of exp * string
+ | ECase of exp * (pat * exp) list * typ
+
| EStrcat of exp * exp
| EWrite of exp
diff --git a/src/mono_env.sig b/src/mono_env.sig
index e3ff94b6..5b270799 100644
--- a/src/mono_env.sig
+++ b/src/mono_env.sig
@@ -37,6 +37,8 @@ signature MONO_ENV = sig
val pushDatatype : env -> string -> int -> (string * int * Mono.typ option) list -> env
val lookupDatatype : env -> int -> string * (string * int * Mono.typ option) list
+ val lookupConstructor : env -> int -> string * Mono.typ option * int
+
val pushERel : env -> string -> Mono.typ -> env
val lookupERel : env -> int -> string * Mono.typ
diff --git a/src/mono_env.sml b/src/mono_env.sml
index 3a6a20ba..58544726 100644
--- a/src/mono_env.sml
+++ b/src/mono_env.sml
@@ -37,6 +37,7 @@ exception UnboundNamed of int
type env = {
datatypes : (string * (string * int * typ option) list) IM.map,
+ constructors : (string * typ option * int) IM.map,
relE : (string * typ) list,
namedE : (string * typ * exp option * string) IM.map
@@ -44,6 +45,7 @@ type env = {
val empty = {
datatypes = IM.empty,
+ constructors = IM.empty,
relE = [],
namedE = IM.empty
@@ -51,6 +53,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,
relE = #relE env,
namedE = #namedE env}
@@ -60,8 +65,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,
relE = (x, t) :: #relE env,
namedE = #namedE env}
@@ -72,6 +83,7 @@ fun lookupERel (env : env) n =
fun pushENamed (env : env) x n t eo s =
{datatypes = #datatypes env,
+ constructors = #constructors env,
relE = #relE env,
namedE = IM.insert (#namedE env, n, (x, t, eo, s))}
diff --git a/src/mono_print.sml b/src/mono_print.sml
index 04380a19..0405d617 100644
--- a/src/mono_print.sml
+++ b/src/mono_print.sml
@@ -54,29 +54,73 @@ fun p_typ' par env (t, _) =
p_typ env t]) xcs,
string "}"]
| TDatatype (n, _) =>
- if !debug then
- string (#1 (E.lookupDatatype env n) ^ "__" ^ Int.toString n)
- else
- string (#1 (E.lookupDatatype env n))
+ ((if !debug then
+ string (#1 (E.lookupDatatype env n) ^ "__" ^ Int.toString n)
+ else
+ string (#1 (E.lookupDatatype env n)))
+ handle E.UnboundNamed _ => string ("UNBOUND_DATATYPE_" ^ Int.toString n))
| TFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"]
and p_typ env = p_typ' false env
fun p_enamed env n =
- if !debug then
- string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n)
- else
- string (#1 (E.lookupENamed env n))
+ (if !debug then
+ string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n)
+ else
+ string (#1 (E.lookupENamed env n)))
+ handle E.UnboundNamed _ => string ("UNBOUNDN_" ^ Int.toString n)
+
+fun p_con_named env n =
+ (if !debug then
+ string (#1 (E.lookupConstructor env n) ^ "__" ^ Int.toString n)
+ else
+ string (#1 (E.lookupConstructor env n)))
+ handle E.UnboundNamed _ => string ("CONSTRUCTOR_" ^ Int.toString n)
+
+fun p_patCon env pc =
+ case pc of
+ PConVar n => p_con_named env n
+ | PConFfi (m, x) => box [string "FFI(",
+ string m,
+ string ".",
+ string x,
+ string ")"]
+
+fun p_pat' par env (p, _) =
+ case p of
+ PWild => string "_"
+ | PVar s => string s
+ | PPrim p => Prim.p_t p
+ | PCon (n, NONE) => p_patCon env n
+ | PCon (n, SOME p) => parenIf par (box [p_patCon env n,
+ space,
+ p_pat' true env p])
+ | PRecord xps =>
+ box [string "{",
+ p_list_sep (box [string ",", space]) (fn (x, p) =>
+ box [string x,
+ space,
+ string "=",
+ space,
+ p_pat env p]) xps,
+ string "}"]
+
+and p_pat x = p_pat' false x
fun p_exp' par env (e, _) =
case e of
EPrim p => Prim.p_t p
| ERel n =>
- if !debug then
- string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n)
- else
- string (#1 (E.lookupERel env n))
+ ((if !debug then
+ string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n)
+ else
+ string (#1 (E.lookupERel env n)))
+ handle E.UnboundRel _ => string ("UNBOUND_" ^ Int.toString n))
| ENamed n => p_enamed env n
+ | ECon (n, NONE) => p_con_named env n
+ | ECon (n, SOME e) => parenIf par (box [p_con_named env n,
+ space,
+ p_exp' true env e])
| EFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"]
| EFfiApp (m, x, es) => box [string "FFI(",
@@ -114,6 +158,18 @@ fun p_exp' par env (e, _) =
string ".",
string x]
+ | ECase (e, pes, _) => parenIf par (box [string "case",
+ space,
+ p_exp env e,
+ space,
+ string "of",
+ space,
+ p_list_sep (box [space, string "|", space])
+ (fn (p, e) => box [p_pat env p,
+ space,
+ string "=>",
+ space,
+ p_exp env e]) pes])
| EStrcat (e1, e2) => box [p_exp' true env e1,
space,
diff --git a/src/mono_shake.sml b/src/mono_shake.sml
index 55054f15..e694c0dd 100644
--- a/src/mono_shake.sml
+++ b/src/mono_shake.sml
@@ -47,8 +47,10 @@ fun shake file =
(fn ((DExport (_, _, n, _), _), page_es) => n :: page_es
| (_, page_es) => page_es) [] file
- val (cdef, edef) = foldl (fn ((DDatatype _, _), acc) => acc
- | ((DVal (_, n, t, e, _), _), (cdef, edef)) => (cdef, IM.insert (edef, n, (t, e)))
+ val (cdef, edef) = foldl (fn ((DDatatype (_, n, xncs), _), (cdef, edef)) =>
+ (IM.insert (cdef, n, xncs), edef)
+ | ((DVal (_, n, t, e, _), _), (cdef, edef)) =>
+ (cdef, IM.insert (edef, n, (t, e)))
| ((DValRec vis, _), (cdef, edef)) =>
(cdef, foldl (fn ((_, n, t, e, _), edef) => IM.insert (edef, n, (t, e))) edef vis)
| ((DExport _, _), acc) => acc)
@@ -60,10 +62,22 @@ fun shake file =
if IS.member (#con s, n) then
s
else
- {exp = #exp s,
- con = IS.add (#con s, n)}
+ let
+ val s' = {exp = #exp s,
+ con = IS.add (#con s, n)}
+ in
+ case IM.find (cdef, n) of
+ NONE => s'
+ | SOME xncs => foldl (fn ((_, _, to), s) =>
+ case to of
+ NONE => s
+ | SOME t => shakeTyp s t)
+ s' xncs
+ end
| _ => s
+ and shakeTyp s = U.Typ.fold typ s
+
fun exp (e, s) =
case e of
ENamed n =>
diff --git a/src/mono_util.sml b/src/mono_util.sml
index a75a0c31..970f3fa0 100644
--- a/src/mono_util.sml
+++ b/src/mono_util.sml
@@ -141,6 +141,11 @@ fun mapfoldB {typ = fc, exp = fe, bind} =
EPrim _ => S.return2 eAll
| ERel _ => S.return2 eAll
| ENamed _ => S.return2 eAll
+ | ECon (_, NONE) => S.return2 eAll
+ | ECon (n, SOME e) =>
+ S.map2 (mfe ctx e,
+ fn e' =>
+ (ECon (n, SOME e'), loc))
| EFfi _ => S.return2 eAll
| EFfiApp (m, x, es) =>
S.map2 (ListUtil.mapfold (fn e => mfe ctx e) es,
@@ -176,6 +181,17 @@ fun mapfoldB {typ = fc, exp = fe, bind} =
fn e' =>
(EField (e', x), loc))
+ | ECase (e, pes, t) =>
+ S.bind2 (mfe ctx e,
+ fn e' =>
+ S.bind2 (ListUtil.mapfold (fn (p, e) =>
+ S.map2 (mfe ctx e,
+ fn e' => (p, e'))) pes,
+ fn pes' =>
+ S.map2 (mft t,
+ fn t' =>
+ (ECase (e', pes', t'), loc))))
+
| EStrcat (e1, e2) =>
S.bind2 (mfe ctx e1,
fn e1' =>
diff --git a/src/monoize.sml b/src/monoize.sml
index 50e705f2..8766cfa5 100644
--- a/src/monoize.sml
+++ b/src/monoize.sml
@@ -160,6 +160,19 @@ fun setRadioGroup (t : t, x) = {radioGroup = SOME x}
end
+fun monoPatCon pc =
+ case pc of
+ L.PConVar n => L'.PConVar n
+ | L.PConFfi mx => L'.PConFfi mx
+
+fun monoPat (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 (monoPatCon pc, Option.map monoPat po), loc)
+ | L.PRecord xps => (L'.PRecord (map (fn (x, p) => (x, monoPat p)) xps), loc)
+
fun monoExp (env, st) (all as (e, loc)) =
let
fun poly () =
@@ -171,7 +184,7 @@ fun monoExp (env, st) (all as (e, loc)) =
L.EPrim p => (L'.EPrim p, loc)
| L.ERel n => (L'.ERel n, loc)
| L.ENamed n => (L'.ENamed n, loc)
- | L.ECon _ => raise Fail "Monoize ECon"
+ | L.ECon (n, eo) => (L'.ECon (n, Option.map (monoExp (env, st)) eo), loc)
| L.EFfi mx => (L'.EFfi mx, loc)
| L.EFfiApp (m, x, es) => (L'.EFfiApp (m, x, map (monoExp (env, st)) es), loc)
@@ -450,7 +463,9 @@ fun monoExp (env, st) (all as (e, loc)) =
| L.ECut _ => poly ()
| L.EFold _ => poly ()
- | L.ECase _ => raise Fail "Monoize ECase"
+ | L.ECase (e, pes, t) => (L'.ECase (monoExp (env, st) e,
+ map (fn (p, e) => (monoPat p, monoExp (env, st) e)) pes,
+ monoType env t), loc)
| L.EWrite e => (L'.EWrite (monoExp (env, st) e), loc)