Mercurial > urweb
changeset 109:813e5a52063d
Remove closure conversion in favor of zany fun with modules, which also replaces 'page'
line wrap: on
line diff
--- a/src/cjr.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/cjr.sml Sun Jul 13 10:17:06 2008 -0400 @@ -31,8 +31,7 @@ datatype typ' = TTop - | TFun - | TCode of typ * typ + | TFun of typ * typ | TRecord of int | TNamed of int | TFfi of string * string @@ -45,14 +44,11 @@ | ENamed of int | EFfi of string * string | EFfiApp of string * string * exp list - | ECode of int | EApp of exp * exp | ERecord of int * (string * exp) list | EField of exp * string - | ELet of (string * typ * exp) list * exp - | EWrite of exp | ESeq of exp * exp @@ -61,10 +57,10 @@ datatype decl' = DStruct of int * (string * typ) list | DVal of string * int * typ * exp - | DFun of int * string * typ * typ * exp + | DFun of string * int * string * typ * typ * exp withtype decl = decl' located -type file = decl list * ((string * typ) list * exp) list +type file = decl list * int list end
--- a/src/cjr_env.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/cjr_env.sig Sun Jul 13 10:17:06 2008 -0400 @@ -47,9 +47,6 @@ val pushENamed : env -> string -> int -> Cjr.typ -> env val lookupENamed : env -> int -> string * Cjr.typ - val pushF : env -> int -> string -> Cjr.typ -> Cjr.typ -> env - val lookupF : env -> int -> string * Cjr.typ * Cjr.typ - val pushStruct : env -> int -> (string * Cjr.typ) list -> env val lookupStruct : env -> int -> (string * Cjr.typ) list
--- a/src/cjr_env.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/cjr_env.sml Sun Jul 13 10:17:06 2008 -0400 @@ -44,7 +44,6 @@ relE : (string * typ) list, namedE : (string * typ) IM.map, - F : (string * typ * typ) IM.map, structs : (string * typ) list IM.map } @@ -55,7 +54,6 @@ relE = [], namedE = IM.empty, - F = IM.empty, structs = IM.empty } @@ -66,7 +64,6 @@ relE = #relE env, namedE = #namedE env, - F = #F env, structs = #structs env} fun lookupTNamed (env : env) n = @@ -81,7 +78,6 @@ relE = (x, t) :: #relE env, namedE = #namedE env, - F = #F env, structs = #structs env} fun lookupERel (env : env) n = @@ -99,7 +95,6 @@ relE = #relE env, namedE = IM.insert (#namedE env, n, (x, t)), - F = #F env, structs = #structs env} fun lookupENamed (env : env) n = @@ -107,21 +102,6 @@ NONE => raise UnboundNamed n | SOME x => x -fun pushF (env : env) n x dom ran = - {namedT = #namedT env, - - numRelE = #numRelE env, - relE = #relE env, - namedE = #namedE env, - - F = IM.insert (#F env, n, (x, dom, ran)), - structs = #structs env} - -fun lookupF (env : env) n = - case IM.find (#F env, n) of - NONE => raise UnboundF n - | SOME x => x - fun pushStruct (env : env) n xts = {namedT = #namedT env, @@ -129,7 +109,6 @@ relE = #relE env, namedE = #namedE env, - F = #F env, structs = IM.insert (#structs env, n, xts)} fun lookupStruct (env : env) n = @@ -137,10 +116,10 @@ NONE => raise UnboundStruct n | SOME x => x -fun declBinds env (d, _) = +fun declBinds env (d, loc) = case d of DVal (x, n, t, _) => pushENamed env x n t - | DFun (n, x, dom, ran, _) => pushF env n x dom ran + | DFun (fx, n, _, dom, ran, _) => pushENamed env fx n (TFun (dom, ran), loc) | DStruct (n, xts) => pushStruct env n xts end
--- a/src/cjr_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/cjr_print.sml Sun Jul 13 10:17:06 2008 -0400 @@ -44,16 +44,13 @@ fun p_typ' par env (t, loc) = case t of TTop => string "void*" - | TFun => - (EM.errorAt loc "Undetermined function type"; - string "?->") - | TCode (t1, t2) => parenIf par (box [p_typ' true env t2, - space, - string "(*)", - space, - string "(", - p_typ env t1, - string ")"]) + | TFun (t1, t2) => parenIf par (box [p_typ' true env t2, + space, + string "(*)", + space, + string "(", + p_typ env t1, + string ")"]) | TRecord i => box [string "struct", space, string "__lws_", @@ -68,13 +65,16 @@ fun p_rel env n = string ("__lwr_" ^ #1 (E.lookupERel env n) ^ "_" ^ Int.toString (E.countERels env - n - 1)) handle CjrEnv.UnboundRel _ => string ("__lwr_UNBOUND_" ^ Int.toString (E.countERels env - n - 1)) +fun p_enamed env n = + string ("__lwn_" ^ #1 (E.lookupENamed env n) ^ "_" ^ Int.toString n) + handle CjrEnv.UnboundNamed _ => string ("__lwn_UNBOUND_" ^ Int.toString n) + fun p_exp' par env (e, _) = case e of EPrim p => Prim.p_t p | ERel n => p_rel env n - | ENamed n => - (string ("__lwn_" ^ #1 (E.lookupENamed env n) ^ "_" ^ Int.toString n) - handle CjrEnv.UnboundNamed _ => string ("__lwn_UNBOUND_" ^ Int.toString n)) + | ENamed n => p_enamed env n + | EFfi (m, x) => box [string "lw_", string m, string "_", string x] | EFfiApp (m, x, es) => box [string "lw_", string m, @@ -83,7 +83,6 @@ string "(", p_list (p_exp env) es, string ")"] - | ECode n => string ("__lwc_" ^ Int.toString n) | EApp (e1, e2) => parenIf par (box [p_exp' true env e1, string "(", p_exp env e2, @@ -112,36 +111,6 @@ string ".", string x] - | ELet (xes, e) => - let - val (env, pps) = foldl (fn ((x, t, e), (env, pps)) => - let - val env' = E.pushERel env x t - in - (env', - List.revAppend ([p_typ env t, - space, - p_rel env' 0, - space, - string "=", - space, - p_exp env e, - string ";", - newline], - pps)) - end) - (env, []) xes - in - box [string "({", - newline, - box (rev pps), - p_exp env e, - space, - string ";", - newline, - string "})"] - end - | EWrite e => box [string "(lw_write(", p_exp env e, string "), lw_unit_v)"] @@ -180,7 +149,7 @@ space, p_exp env e, string ";"] - | DFun (n, x, dom, ran, e) => + | DFun (fx, n, x, dom, ran, e) => let val env' = E.pushERel env x dom in @@ -188,7 +157,7 @@ space, p_typ env ran, space, - string ("__lwc_" ^ Int.toString n), + string ("__lwn_" ^ fx ^ "_" ^ Int.toString n), string "(", p_typ env dom, space, @@ -204,46 +173,8 @@ string "}"] end -fun p_page env (xts, (e, loc)) = - case e of - ERecord (_, xes) => - let - fun read x = ListUtil.search (fn (x', e) => if x' = x then SOME e else NONE) xes - in - case (read "code", read "env") of - (SOME code, SOME envx) => - (case #1 code of - ECode i => - let - val (_, (dom, _), _) = E.lookupF env i - in - case dom of - TRecord ri => - let - val axts = E.lookupStruct env ri - fun read x = ListUtil.search (fn (x', t) => if x' = x then SOME t else NONE) axts - in - case read "arg" of - NONE => string "Page handler is too complicated! [5]" - | SOME (at, _) => - case at of - TRecord ari => - let - val r = (ERecord (ri, [("env", envx), - ("arg", (ERecord (ari, []), loc))]), loc) - in - box [p_exp env (EApp (code, r), loc), - string ";"] - end - | _ => string "Page handler is too complicated! [6]" - end - | _ => string "Page handler is too complicated! [4]" - end - | _ => string "Page handler is too complicated! [3]") - - | _ => string "Page handler is too complicated! [1]" - end - | _ => string "Page handler is too complicated! [2]" +fun p_page env n = box [p_enamed env n, + string "(lw_unit_v);"] fun p_file env (ds, ps) = let
--- a/src/cjrize.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/cjrize.sig Sun Jul 13 10:17:06 2008 -0400 @@ -27,6 +27,6 @@ signature CJRIZE = sig - val cjrize : Flat.file -> Cjr.file + val cjrize : Mono.file -> Cjr.file end
--- a/src/cjrize.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/cjrize.sml Sun Jul 13 10:17:06 2008 -0400 @@ -27,7 +27,7 @@ structure Cjrize :> CJRIZE = struct -structure L = Flat +structure L = Mono structure L' = Cjr structure Sm :> sig @@ -41,7 +41,7 @@ structure FM = BinaryMapFn(struct type ord_key = L.typ - val compare = FlatUtil.Typ.compare + val compare = MonoUtil.Typ.compare end) type t = int * int FM.map * (int * (string * L'.typ) list) list @@ -63,20 +63,12 @@ fun cifyTyp ((t, loc), sm) = case t of - L.TTop => ((L'.TTop, loc), sm) - | L.TFun (t1, t2) => - let - val (_, sm) = cifyTyp (t1, sm) - val (_, sm) = cifyTyp (t2, sm) - in - ((L'.TFun, loc), sm) - end - | L.TCode (t1, t2) => + L.TFun (t1, t2) => let val (t1, sm) = cifyTyp (t1, sm) val (t2, sm) = cifyTyp (t2, sm) in - ((L'.TCode (t1, t2), loc), sm) + ((L'.TFun (t1, t2), loc), sm) end | L.TRecord xts => let @@ -95,6 +87,8 @@ | L.TNamed n => ((L'.TNamed n, loc), sm) | L.TFfi mx => ((L'.TFfi mx, loc), sm) +val dummye = (L'.EPrim (Prim.Int 0), ErrorMsg.dummySpan) + fun cifyExp ((e, loc), sm) = case e of L.EPrim p => ((L'.EPrim p, loc), sm) @@ -107,7 +101,6 @@ in ((L'.EFfiApp (m, x, es), loc), sm) end - | L.ECode n => ((L'.ECode n, loc), sm) | L.EApp (e1, e2) => let val (e1, sm) = cifyExp (e1, sm) @@ -115,6 +108,8 @@ in ((L'.EApp (e1, e2), loc), sm) end + | L.EAbs _ => (ErrorMsg.errorAt loc "Anonymous function remains at code generation"; + (dummye, sm)) | L.ERecord xes => let @@ -143,21 +138,6 @@ ((L'.EField (e, x), loc), sm) end - | L.ELet (xes, e) => - let - val (xes, sm) = ListUtil.foldlMap (fn ((x, t, e), sm) => - let - val (t, sm) = cifyTyp (t, sm) - val (e, sm) = cifyExp (e, sm) - in - ((x, t, e), sm) - end) - sm xes - val (e, sm) = cifyExp (e, sm) - in - ((L'.ELet (xes, e), loc), sm) - end - | L.EStrcat _ => raise Fail "Cjrize EStrcat" | L.EWrite e => @@ -177,34 +157,31 @@ fun cifyDecl ((d, loc), sm) = case d of - L.DVal (x, n, t, e) => + L.DVal (x, n, t, e, _) => let val (t, sm) = cifyTyp (t, sm) - val (e, sm) = cifyExp (e, sm) + + val (d, sm) = case #1 t of + L'.TFun (dom, ran) => + (case #1 e of + L.EAbs (ax, _, _, e) => + let + val (e, sm) = cifyExp (e, sm) + in + (L'.DFun (x, n, ax, dom, ran, e), sm) + end + | _ => (ErrorMsg.errorAt loc "Function isn't explicit at code generation"; + (L'.DVal ("", 0, t, (L'.EPrim (Prim.Int 0), ErrorMsg.dummySpan)), sm))) + | _ => + let + val (e, sm) = cifyExp (e, sm) + in + (L'.DVal (x, n, t, e), sm) + end in - (SOME (L'.DVal (x, n, t, e), loc), NONE, sm) + (SOME (d, loc), NONE, sm) end - | L.DFun (n, x, dom, ran, e) => - let - val (dom, sm) = cifyTyp (dom, sm) - val (ran, sm) = cifyTyp (ran, sm) - val (e, sm) = cifyExp (e, sm) - in - (SOME (L'.DFun (n, x, dom, ran, e), loc), NONE, sm) - end - | L.DPage (xts, e) => - let - val (xts, sm) = ListUtil.foldlMap (fn ((x, t), sm) => - let - val (t, sm) = cifyTyp (t, sm) - in - ((x, t), sm) - end) - sm xts - val (e, sm) = cifyExp (e, sm) - in - (NONE, SOME (xts, e), sm) - end + | L.DExport n => (NONE, SOME n, sm) fun cjrize ds = let
--- a/src/cloconv.sig Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -signature CLOCONV = sig - - val cloconv : Mono.file -> Flat.file - -end
--- a/src/cloconv.sml Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -structure Cloconv :> CLOCONV = struct - -structure L = Mono -structure L' = Flat - -structure IS = IntBinarySet - -structure U = FlatUtil -structure E = FlatEnv - -open Print.PD -open Print - -val liftExpInExp = - U.Exp.mapB {typ = fn t => t, - exp = fn bound => fn e => - case e of - L'.ERel xn => - if xn < bound then - e - else - L'.ERel (xn + 1) - | _ => e, - bind = fn (bound, U.Exp.RelE _) => bound + 1 - | (bound, _) => bound} -val subExpInExp = - U.Exp.mapB {typ = fn t => t, - exp = fn (xn, rep) => fn e => - case e of - L'.ERel xn' => - (case Int.compare (xn', xn) of - EQUAL => #1 rep - | GREATER => L'.ERel (xn' - 1) - | _ => e) - | _ => e, - bind = fn ((xn, rep), U.Exp.RelE _) => (xn+1, liftExpInExp 0 rep) - | (ctx, _) => ctx} - - -fun ccTyp (t, loc) = - case t of - L.TFun (t1, t2) => (L'.TFun (ccTyp t1, ccTyp t2), loc) - | L.TRecord xts => (L'.TRecord (map (fn (x, t) => (x, ccTyp t)) xts), loc) - | L.TNamed n => (L'.TNamed n, loc) - | L.TFfi mx => (L'.TFfi mx, loc) - -structure Ds :> sig - type t - - val empty : t - - val exp : t -> string * int * L'.typ * L'.exp -> t - val func : t -> string * L'.typ * L'.typ * L'.exp -> t * int - val page : t -> (string * L'.typ) list * L'.exp -> t - val decls : t -> L'.decl list - - val enter : t -> t - val used : t * int -> t - val leave : t -> t - val listUsed : t -> int list -end = struct - -type t = int * L'.decl list * IS.set - -val empty = (0, [], IS.empty) - -fun exp (fc, ds, vm) (v as (_, _, _, (_, loc))) = (fc, (L'.DVal v, loc) :: ds, vm) - -fun func (fc, ds, vm) (x, dom, ran, e as (_, loc)) = - ((fc+1, (L'.DFun (fc, x, dom, ran, e), loc) :: ds, vm), fc) - -fun page (fc, ds, vm) (xts, e as (_, loc)) = (fc, (L'.DPage (xts, e), loc) :: ds, vm) - -fun decls (_, ds, _) = rev ds - -fun enter (fc, ds, vm) = (fc, ds, IS.map (fn n => n + 1) vm) -fun used ((fc, ds, vm), n) = (fc, ds, IS.add (vm, n)) -fun leave (fc, ds, vm) = (fc, ds, IS.map (fn n => n - 1) (IS.delete (vm, 0) handle NotFound => vm)) - -fun listUsed (_, _, vm) = IS.listItems vm - -end - - -fun ccExp env ((e, loc), D) = - case e of - L.EPrim p => ((L'.EPrim p, loc), D) - | L.ERel n => ((L'.ERel n, loc), Ds.used (D, n)) - | L.ENamed n => ((L'.ENamed n, loc), D) - | L.EFfi mx => ((L'.EFfi mx, loc), D) - | L.EFfiApp (m, x, es) => - let - val (es, D) = ListUtil.foldlMap (ccExp env) D es - in - ((L'.EFfiApp (m, x, es), loc), D) - end - | L.EApp (e1, e2) => - let - val (e1, D) = ccExp env (e1, D) - val (e2, D) = ccExp env (e2, D) - in - ((L'.ELet ([("closure", (L'.TTop, loc), e1), - ("arg", (L'.TTop, loc), liftExpInExp 0 e2), - ("code", (L'.TTop, loc), (L'.EField ((L'.ERel 1, loc), "func"), loc)), - ("env", (L'.TTop, loc), (L'.EField ((L'.ERel 2, loc), "env"), loc))], - (L'.EApp ((L'.ERel 1, loc), - (L'.ERecord [("env", (L'.ERel 0, loc), (L'.TTop, loc)), - ("arg", (L'.ERel 2, loc), (L'.TTop, loc))], loc)), loc)), loc), D) - end - | L.EAbs (x, dom, ran, e) => - let - val dom = ccTyp dom - val ran = ccTyp ran - val (e, D) = ccExp (E.pushERel env x dom) (e, Ds.enter D) - val ns = Ds.listUsed D - val ns = List.filter (fn n => n <> 0) ns - val D = Ds.leave D - - val envT = (L'.TRecord (map (fn n => ("fv" ^ Int.toString n, #2 (E.lookupERel env (n-1)))) ns), loc) - - (*val () = Print.preface ("Before", FlatPrint.p_exp FlatEnv.basis e) - val () = List.app (fn (x, t) => preface ("Bound", box [string x, - space, - string ":", - space, - FlatPrint.p_typ env t])) - (E.listERels env) - val () = List.app (fn n => preface ("Free", FlatPrint.p_exp (E.pushERel env x dom) - (L'.ERel n, loc))) ns*) - val body = foldl (fn (n, e) => - subExpInExp (n, (L'.EField ((L'.ERel 1, loc), "fv" ^ Int.toString n), loc)) e) - e ns - (*val () = Print.preface (" After", FlatPrint.p_exp FlatEnv.basis body)*) - val body = (L'.ELet ([("env", envT, (L'.EField ((L'.ERel 0, loc), "env"), loc)), - ("arg", dom, (L'.EField ((L'.ERel 1, loc), "arg"), loc))], - body), loc) - - val (D, fi) = Ds.func D (x, (L'.TRecord [("env", envT), ("arg", dom)], loc), ran, body) - in - ((L'.ERecord [("code", (L'.ECode fi, loc), (L'.TTop, loc)), - ("env", (L'.ERecord (map (fn n => ("fv" ^ Int.toString n, - (L'.ERel (n-1), loc), - #2 (E.lookupERel env (n-1)))) ns), loc), - envT)], loc), D) - end - - | L.ERecord xes => - let - val (xes, D) = ListUtil.foldlMap (fn ((x, e, t), D) => - let - val (e, D) = ccExp env (e, D) - in - ((x, e, ccTyp t), D) - end) D xes - in - ((L'.ERecord xes, loc), D) - end - | L.EField (e1, x) => - let - val (e1, D) = ccExp env (e1, D) - in - ((L'.EField (e1, x), loc), D) - end - - | L.EStrcat (e1, e2) => - let - val (e1, D) = ccExp env (e1, D) - val (e2, D) = ccExp env (e2, D) - in - ((L'.EStrcat (e1, e2), loc), D) - end - - | L.EWrite e => - let - val (e, D) = ccExp env (e, D) - in - ((L'.EWrite e, loc), D) - end - - | L.ESeq (e1, e2) => - let - val (e1, D) = ccExp env (e1, D) - val (e2, D) = ccExp env (e2, D) - in - ((L'.ESeq (e1, e2), loc), D) - end - -fun ccDecl ((d, loc), D) = - case d of - L.DVal (x, n, t, e) => - let - val t = ccTyp t - val (e, D) = ccExp E.empty (e, D) - in - Ds.exp D (x, n, t, e) - end - | L.DPage (xts, e) => - let - val xts = map (fn (x, t) => (x, ccTyp t)) xts - val (e, D) = ccExp E.empty (e, D) - in - Ds.page D (xts, e) - end - -fun cloconv ds = - let - val D = foldl ccDecl Ds.empty ds - in - Ds.decls D - end - -end
--- a/src/compiler.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/compiler.sig Sun Jul 13 10:17:06 2008 -0400 @@ -47,7 +47,6 @@ val shake : job -> Core.file option val monoize : job -> Mono.file option val mono_opt : job -> Mono.file option - val cloconv : job -> Flat.file option val cjrize : job -> Cjr.file option val testParse : job -> unit @@ -59,7 +58,6 @@ val testShake : job -> unit val testMonoize : job -> unit val testMono_opt : job -> unit - val testCloconv : job -> unit val testCjrize : job -> unit end
--- a/src/compiler.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/compiler.sml Sun Jul 13 10:17:06 2008 -0400 @@ -111,9 +111,11 @@ fun parse fnames = let + fun nameOf fname = capitalize (OS.Path.file fname) + fun parseOne fname = let - val mname = capitalize (OS.Path.file fname) + val mname = nameOf fname val lac = OS.Path.joinBaseExt {base = fname, ext = SOME "lac"} val lig = OS.Path.joinBaseExt {base = fname, ext = SOME "lig"} @@ -137,7 +139,13 @@ SOME (Source.DStr (mname, sgnO, (Source.StrConst ds, loc)), loc) end - val ds = List.mapPartial parseOne fnames + val ds = List.mapPartial parseOne fnames + val ds = + let + val final = nameOf (List.last fnames) + in + ds @ [(Source.DExport (Source.StrVar final, ErrorMsg.dummySpan), ErrorMsg.dummySpan)] + end handle Empty => ds in if ErrorMsg.anyErrors () then NONE @@ -224,22 +232,13 @@ else SOME (MonoOpt.optimize file) -fun cloconv job = +fun cjrize job = case mono_opt job of NONE => NONE | SOME file => if ErrorMsg.anyErrors () then NONE else - SOME (Cloconv.cloconv file) - -fun cjrize job = - case cloconv job of - NONE => NONE - | SOME file => - if ErrorMsg.anyErrors () then - NONE - else SOME (Cjrize.cjrize file) fun testParse job = @@ -322,15 +321,6 @@ handle MonoEnv.UnboundNamed n => print ("Unbound named " ^ Int.toString n ^ "\n") -fun testCloconv job = - (case cloconv job of - NONE => print "Failed\n" - | SOME file => - (Print.print (FlatPrint.p_file FlatEnv.empty file); - print "\n")) - handle FlatEnv.UnboundNamed n => - print ("Unbound named " ^ Int.toString n ^ "\n") - fun testCjrize job = (case cjrize job of NONE => print "Failed\n"
--- a/src/core.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/core.sml Sun Jul 13 10:17:06 2008 -0400 @@ -80,8 +80,8 @@ datatype decl' = DCon of string * int * kind * con - | DVal of string * int * con * exp - | DPage of con * exp + | DVal of string * int * con * exp * string + | DExport of int withtype decl = decl' located
--- a/src/core_env.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/core_env.sig Sun Jul 13 10:17:06 2008 -0400 @@ -45,8 +45,8 @@ val pushERel : env -> string -> Core.con -> env val lookupERel : env -> int -> string * Core.con - val pushENamed : env -> string -> int -> Core.con -> Core.exp option -> env - val lookupENamed : env -> int -> string * Core.con * Core.exp option + val pushENamed : env -> string -> int -> Core.con -> Core.exp option -> string -> env + val lookupENamed : env -> int -> string * Core.con * Core.exp option * string val declBinds : env -> Core.decl -> env
--- a/src/core_env.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/core_env.sml Sun Jul 13 10:17:06 2008 -0400 @@ -62,7 +62,7 @@ namedC : (string * kind * con option) IM.map, relE : (string * con) list, - namedE : (string * con * exp option) IM.map + namedE : (string * con * exp option * string) IM.map } val empty = { @@ -78,7 +78,7 @@ namedC = IM.map (fn (x, k, co) => (x, k, Option.map lift co)) (#namedC env), relE = map (fn (x, c) => (x, lift c)) (#relE env), - namedE = IM.map (fn (x, c, eo) => (x, lift c, eo)) (#namedE env)} + namedE = IM.map (fn (x, c, eo, s) => (x, lift c, eo, s)) (#namedE env)} fun lookupCRel (env : env) n = (List.nth (#relC env, n)) @@ -107,12 +107,12 @@ (List.nth (#relE env, n)) handle Subscript => raise UnboundRel n -fun pushENamed (env : env) x n t eo = +fun pushENamed (env : env) x n t eo s = {relC = #relC env, namedC = #namedC env, relE = #relE env, - namedE = IM.insert (#namedE env, n, (x, t, eo))} + namedE = IM.insert (#namedE env, n, (x, t, eo, s))} fun lookupENamed (env : env) n = case IM.find (#namedE env, n) of @@ -122,7 +122,7 @@ fun declBinds env (d, _) = case d of DCon (x, n, k, c) => pushCNamed env x n k (SOME c) - | DVal (x, n, t, e) => pushENamed env x n t (SOME e) - | DPage _ => env + | DVal (x, n, t, e, s) => pushENamed env x n t (SOME e) s + | DExport _ => env end
--- a/src/core_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/core_print.sml Sun Jul 13 10:17:06 2008 -0400 @@ -145,6 +145,13 @@ CName s => string s | _ => p_con env all +fun p_enamed 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_exp' par env (e, _) = case e of EPrim p => Prim.p_t p @@ -154,12 +161,7 @@ else string (#1 (E.lookupERel env n))) handle E.UnboundRel _ => string ("UNBOUND_" ^ Int.toString n)) - | ENamed 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)) + | ENamed n => p_enamed env n | EFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"] | EFfiApp (m, x, es) => box [string "FFI(", string m, @@ -255,7 +257,7 @@ space, p_con env c] end - | DVal (x, n, t, e) => + | DVal (x, n, t, e, s) => let val xp = if !debug then box [string x, @@ -268,6 +270,10 @@ space, xp, space, + string "as", + space, + string s, + space, string ":", space, p_con env t, @@ -276,12 +282,9 @@ space, p_exp env e] end - | DPage (c, e) => box [string "page", - p_con env c, - space, - string "=", - space, - p_exp env e] + | DExport n => box [string "export", + space, + p_enamed env n] fun p_file env file = let
--- a/src/core_util.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/core_util.sig Sun Jul 13 10:17:06 2008 -0400 @@ -69,7 +69,7 @@ RelC of string * Core.kind | NamedC of string * int * Core.kind * Core.con option | RelE of string * Core.con - | NamedE of string * int * Core.con * Core.exp option + | NamedE of string * int * Core.con * Core.exp option * string val mapfoldB : {kind : (Core.kind', 'state, 'abort) Search.mapfolder, con : ('context, Core.con', 'state, 'abort) Search.mapfolderB,
--- a/src/core_util.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/core_util.sml Sun Jul 13 10:17:06 2008 -0400 @@ -203,7 +203,7 @@ RelC of string * kind | NamedC of string * int * kind * con option | RelE of string * con - | NamedE of string * int * con * exp option + | NamedE of string * int * con * exp option * string fun mapfoldB {kind = fk, con = fc, exp = fe, bind} = let @@ -375,18 +375,13 @@ S.map2 (mfc ctx c, fn c' => (DCon (x, n, k', c'), loc))) - | DVal (x, n, t, e) => + | DVal (x, n, t, e, s) => S.bind2 (mfc ctx t, fn t' => S.map2 (mfe ctx e, fn e' => - (DVal (x, n, t', e'), loc))) - | DPage (c, e) => - S.bind2 (mfc ctx c, - fn c' => - S.map2 (mfe ctx e, - fn e' => - (DPage (c', e'), loc))) + (DVal (x, n, t', e', s), loc))) + | DExport _ => S.return2 dAll in mfd end @@ -426,8 +421,8 @@ val ctx' = case #1 d' of DCon (x, n, k, c) => bind (ctx, NamedC (x, n, k, SOME c)) - | DVal (x, n, t, e) => bind (ctx, NamedE (x, n, t, SOME e)) - | DPage _ => ctx + | DVal (x, n, t, e, s) => bind (ctx, NamedE (x, n, t, SOME e, s)) + | DExport _ => ctx in S.map2 (mff ctx' ds', fn ds' =>
--- a/src/corify.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/corify.sml Sun Jul 13 10:17:06 2008 -0400 @@ -362,6 +362,7 @@ | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp st e1, corifyCon st c, {field = corifyCon st field, rest = corifyCon st rest}), loc) | L.EFold k => (L'.EFold (corifyKind k), loc) + | L.EWrite e => (L'.EWrite (corifyExp st e), loc) fun corifyDecl ((d, loc : EM.span), st) = case d of @@ -375,7 +376,7 @@ let val (st, n) = St.bindVal st x n in - ([(L'.DVal (x, n, corifyCon st t, corifyExp st e), loc)], st) + ([(L'.DVal (x, n, corifyCon st t, corifyExp st e, x), loc)], st) end | L.DSgn _ => ([], st) @@ -427,19 +428,60 @@ end | _ => raise Fail "Non-const signature for FFI structure") - | L.DPage (c, e) => - let - val c = corifyCon st c - val e = corifyExp st e + | L.DExport (en, sgn, str) => + (case #1 sgn of + L.SgnConst sgis => + let + fun pathify (str, _) = + case str of + L.StrVar m => SOME (m, []) + | L.StrProj (str, s) => + Option.map (fn (m, ms) => (m, ms @ [s])) (pathify str) + | _ => NONE + in + case pathify str of + NONE => (ErrorMsg.errorAt loc "Structure is too fancy to export"; + ([], st)) + | SOME (m, ms) => + let + fun wrapSgi ((sgi, _), (wds, eds)) = + case sgi of + L.SgiVal (s, _, t as (L.TFun (dom, ran), _)) => + (case (#1 dom, #1 ran) of + (L.TRecord _, + L.CApp ((L.CModProj (_, [], "xml"), _), + (L.TRecord (L.CRecord (_, [((L.CName "Html", _), + _)]), _), _))) => + let + val ran = (L.TRecord (L.CRecord ((L.KType, loc), []), loc), loc) + val e = (L.EModProj (m, ms, s), loc) + val e = (L.EAbs ("vs", dom, ran, + (L.EWrite (L.EApp (e, (L.ERel 0, loc)), loc), loc)), loc) + in + ((L.DVal ("wrap_" ^ s, 0, + (L.TFun (dom, ran), loc), + e), loc) :: wds, + (fn st => + case #1 (corifyExp st (L.EModProj (en, [], "wrap_" ^ s), loc)) of + L'.ENamed n => (L'.DExport n, loc) + | _ => raise Fail "Corify: Value to export didn't corify properly") + :: eds) + end + | _ => (wds, eds)) + | _ => (wds, eds) - val dom = (L'.TRecord c, loc) - val ran = (L'.TRecord (L'.CRecord ((L'.KType, loc), []), loc), loc) - val e = (L'.EAbs ("vs", dom, ran, - (L'.EWrite (L'.EApp (e, (L'.ERel 0, loc)), loc), loc)), loc) - - in - ([(L'.DPage (c, e), loc)], st) - end + val (wds, eds) = foldl wrapSgi ([], []) sgis + val wrapper = (L.StrConst wds, loc) + val (ds, {inner, outer}) = corifyStr (wrapper, st) + val st = St.bindStr outer "wrapper" en inner + + val ds = ds @ map (fn f => f st) eds + in + (ds, st) + end + end + | _ => raise Fail "Non-const signature for 'export'") + and corifyStr ((str, _), st) = case str of @@ -487,7 +529,7 @@ | L.DSgn (_, n', _) => Int.max (n, n') | L.DStr (_, n', _, str) => Int.max (n, Int.max (n', maxNameStr str)) | L.DFfiStr (_, n', _) => Int.max (n, n') - | L.DPage _ => n) + | L.DExport _ => n) 0 ds and maxNameStr (str, _) =
--- a/src/elab.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/elab.sml Sun Jul 13 10:17:06 2008 -0400 @@ -115,7 +115,7 @@ | DStr of string * int * sgn * str | DFfiStr of string * int * sgn | DConstraint of con * con - | DPage of con * exp + | DExport of int * sgn * str and str' = StrConst of decl list
--- a/src/elab_env.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/elab_env.sig Sun Jul 13 10:17:06 2008 -0400 @@ -83,4 +83,6 @@ val projectStr : env -> { sgn : Elab.sgn, str : Elab.str, field : string } -> Elab.sgn option val projectConstraints : env -> { sgn : Elab.sgn, str : Elab.str } -> (Elab.con * Elab.con) list option + val newNamed : unit -> int + end
--- a/src/elab_env.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/elab_env.sml Sun Jul 13 10:17:06 2008 -0400 @@ -91,6 +91,14 @@ val namedCounter = ref 0 +fun newNamed () = + let + val r = !namedCounter + in + namedCounter := r + 1; + r + end + val empty = { renameC = SM.empty, relC = [], @@ -292,7 +300,7 @@ | DStr (x, n, sgn, _) => pushStrNamedAs env x n sgn | DFfiStr (x, n, sgn) => pushStrNamedAs env x n sgn | DConstraint _ => env - | DPage _ => env + | DExport _ => env fun sgiBinds env (sgi, _) = case sgi of
--- a/src/elab_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/elab_print.sml Sun Jul 13 10:17:06 2008 -0400 @@ -450,12 +450,12 @@ string "~", space, p_con env c2] - | DPage (c, e) => box [string "page", - p_con env c, - space, - string "=", - space, - p_exp env e] + | DExport (_, sgn, str) => box [string "export", + p_str env str, + space, + string ":", + space, + p_sgn env sgn] and p_str env (str, _) = case str of
--- a/src/elab_util.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/elab_util.sml Sun Jul 13 10:17:06 2008 -0400 @@ -511,7 +511,7 @@ | DFfiStr (x, _, sgn) => bind (ctx, Str (x, sgn)) | DConstraint _ => ctx - | DPage _ => ctx, + | DExport _ => ctx, mfd ctx d)) ctx ds, fn ds' => (StrConst ds', loc)) | StrVar _ => S.return2 strAll @@ -572,12 +572,12 @@ S.map2 (mfc ctx c2, fn c2' => (DConstraint (c1', c2'), loc))) - | DPage (c, e) => - S.bind2 (mfc ctx c, - fn c' => - S.map2 (mfe ctx e, - fn e' => - (DPage (c', e'), loc))) + | DExport (en, sgn, str) => + S.bind2 (mfsg ctx sgn, + fn sgn' => + S.map2 (mfst ctx str, + fn str' => + (DExport (en, sgn', str'), loc))) in mfd end
--- a/src/elaborate.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/elaborate.sml Sun Jul 13 10:17:06 2008 -0400 @@ -1599,7 +1599,7 @@ | L'.DStr (x, n, sgn, _) => SOME (L'.SgiStr (x, n, sgn), loc) | L'.DFfiStr (x, n, sgn) => SOME (L'.SgiStr (x, n, sgn), loc) | L'.DConstraint cs => SOME (L'.SgiConstraint cs, loc) - | L'.DPage _ => NONE + | L'.DExport _ => NONE fun sgiBindsD (env, denv) (sgi, _) = case sgi of @@ -1929,27 +1929,41 @@ ([], (env, denv, [])) end - | L.DPage e => + | L.DExport str => let - val basis = - case E.lookupStr env "Basis" of - NONE => raise Fail "elabExp: Unbound Basis" - | SOME (n, _) => n + val (str', sgn, gs) = elabStr (env, denv) str - val (e', t, gs1) = elabExp (env, denv) e - - val k = (L'.KRecord (L'.KType, loc), loc) - val vs = cunif (loc, k) - - val c = (L'.TFun ((L'.TRecord vs, loc), - (L'.CApp ((L'.CModProj (basis, [], "xml"), loc), - (L'.CRecord ((L'.KUnit, loc), - [((L'.CName "Html", loc), - (L'.CUnit, loc))]), loc)), loc)), loc) - - val gs2 = checkCon (env, denv) e' t c + val sgn = + case #1 (hnormSgn env sgn) of + L'.SgnConst sgis => + let + fun doOne (all as (sgi, _)) = + case sgi of + L'.SgiVal (x, n, t) => + (case hnormCon (env, denv) t of + ((L'.TFun (dom, ran), _), []) => + (case (hnormCon (env, denv) dom, hnormCon (env, denv) ran) of + (((L'.TRecord domR, _), []), + ((L'.CApp (tf, ranR), _), [])) => + (case hnormCon (env, denv) ranR of + (ranR, []) => + (case (hnormCon (env, denv) domR, hnormCon (env, denv) ranR) of + ((domR, []), (ranR, [])) => + (L'.SgiVal (x, n, (L'.TFun ((L'.TRecord domR, loc), + (L'.CApp (tf, + (L'.TRecord ranR, loc)), loc)), + loc)), loc) + | _ => all) + | _ => all) + | _ => all) + | _ => all) + | _ => all + in + (L'.SgnConst (map doOne sgis), loc) + end + | _ => sgn in - ([(L'.DPage (vs, e'), loc)], (env, denv, gs1 @ gs2)) + ([(L'.DExport (E.newNamed (), sgn, str'), loc)], (env, denv, gs)) end and elabStr (env, denv) (str, loc) =
--- a/src/expl.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/expl.sml Sun Jul 13 10:17:06 2008 -0400 @@ -73,6 +73,8 @@ | EField of exp * con * { field : con, rest : con } | EFold of kind + | EWrite of exp + withtype exp = exp' located datatype sgn_item' = @@ -98,7 +100,7 @@ | DSgn of string * int * sgn | DStr of string * int * sgn * str | DFfiStr of string * int * sgn - | DPage of con * exp + | DExport of int * sgn * str and str' = StrConst of decl list
--- a/src/expl_env.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/expl_env.sml Sun Jul 13 10:17:06 2008 -0400 @@ -243,7 +243,7 @@ | DSgn (x, n, sgn) => pushSgnNamed env x n sgn | DStr (x, n, sgn, _) => pushStrNamed env x n sgn | DFfiStr (x, n, sgn) => pushStrNamed env x n sgn - | DPage _ => env + | DExport _ => env fun sgiBinds env (sgi, _) = case sgi of
--- a/src/expl_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/expl_print.sml Sun Jul 13 10:17:06 2008 -0400 @@ -92,7 +92,8 @@ handle E.UnboundNamed _ => string ("UNBOUND_NAMED" ^ Int.toString n)) | CModProj (m1, ms, x) => let - val (m1x, sgn) = E.lookupStrNamed env m1 + val m1x = #1 (E.lookupStrNamed env m1) + handle E.UnboundNamed _ => "UNBOUND" val m1s = if !debug then m1x ^ "__" ^ Int.toString m1 @@ -237,6 +238,10 @@ p_con' true env c] | EFold _ => string "fold" + | EWrite e => box [string "write(", + p_exp env e, + string ")"] + and p_exp env = p_exp' false env fun p_named x n = @@ -392,12 +397,13 @@ string ":", space, p_sgn env sgn] - | DPage (c, e) => box [string "page", - p_con env c, - space, - string "=", - space, - p_exp env e] + | DExport (_, sgn, str) => box [string "export", + space, + p_str env str, + space, + string ":", + space, + p_sgn env sgn] and p_str env (str, _) = case str of
--- a/src/expl_util.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/expl_util.sml Sun Jul 13 10:17:06 2008 -0400 @@ -271,6 +271,11 @@ S.map2 (mfk k, fn k' => (EFold k', loc)) + + | EWrite e => + S.map2 (mfe ctx e, + fn e' => + (EWrite e', loc)) in mfe end
--- a/src/explify.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/explify.sml Sun Jul 13 10:17:06 2008 -0400 @@ -116,7 +116,7 @@ | L.DStr (x, n, sgn, str) => SOME (L'.DStr (x, n, explifySgn sgn, explifyStr str), loc) | L.DFfiStr (x, n, sgn) => SOME (L'.DFfiStr (x, n, explifySgn sgn), loc) | L.DConstraint (c1, c2) => NONE - | L.DPage (c, e) => SOME (L'.DPage (explifyCon c, explifyExp e), loc) + | L.DExport (en, sgn, str) => SOME (L'.DExport (en, explifySgn sgn, explifyStr str), loc) and explifyStr (str, loc) = case str of
--- a/src/flat.sml Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -structure Flat = struct - -type 'a located = 'a ErrorMsg.located - -datatype typ' = - TTop - | TFun of typ * typ - | TCode of typ * typ - | TRecord of (string * typ) list - | TNamed of int - | TFfi of string * string - -withtype typ = typ' located - -datatype exp' = - EPrim of Prim.t - | ERel of int - | ENamed of int - | EFfi of string * string - | EFfiApp of string * string * exp list - | ECode of int - | EApp of exp * exp - - | ERecord of (string * exp * typ) list - | EField of exp * string - - | ELet of (string * typ * exp) list * exp - - | EStrcat of exp * exp - - | EWrite of exp - | ESeq of exp * exp - -withtype exp = exp' located - -datatype decl' = - DVal of string * int * typ * exp - | DFun of int * string * typ * typ * exp - | DPage of (string * typ) list * exp - -withtype decl = decl' located - -type file = decl list - -end
--- a/src/flat_env.sig Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -signature FLAT_ENV = sig - - type env - - val empty : env - - exception UnboundRel of int - exception UnboundNamed of int - exception UnboundF of int - - val pushTNamed : env -> string -> int -> Flat.typ option -> env - val lookupTNamed : env -> int -> string * Flat.typ option - - val pushERel : env -> string -> Flat.typ -> env - val lookupERel : env -> int -> string * Flat.typ - val listERels : env -> (string * Flat.typ) list - - val pushENamed : env -> string -> int -> Flat.typ -> env - val lookupENamed : env -> int -> string * Flat.typ - - val pushF : env -> int -> string -> Flat.typ -> Flat.typ -> env - val lookupF : env -> int -> string * Flat.typ * Flat.typ - - val declBinds : env -> Flat.decl -> env - -end
--- a/src/flat_env.sml Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -structure FlatEnv :> FLAT_ENV = struct - -open Flat - -structure IM = IntBinaryMap - - -exception UnboundRel of int -exception UnboundNamed of int -exception UnboundF of int - -type env = { - namedT : (string * typ option) IM.map, - - relE : (string * typ) list, - namedE : (string * typ) IM.map, - - F : (string * typ * typ) IM.map -} - -val empty = { - namedT = IM.empty, - - relE = [], - namedE = IM.empty, - - F = IM.empty -} - -fun pushTNamed (env : env) x n co = - {namedT = IM.insert (#namedT env, n, (x, co)), - - relE = #relE env, - namedE = #namedE env, - - F = #F env} - -fun lookupTNamed (env : env) n = - case IM.find (#namedT env, n) of - NONE => raise UnboundNamed n - | SOME x => x - -fun pushERel (env : env) x t = - {namedT = #namedT env, - - relE = (x, t) :: #relE env, - namedE = #namedE env, - - F = #F env} - -fun lookupERel (env : env) n = - (List.nth (#relE env, n)) - handle Subscript => raise UnboundRel n - -fun listERels (env : env) = #relE env - -fun pushENamed (env : env) x n t = - {namedT = #namedT env, - - relE = #relE env, - namedE = IM.insert (#namedE env, n, (x, t)), - - F = #F env} - -fun lookupENamed (env : env) n = - case IM.find (#namedE env, n) of - NONE => raise UnboundNamed n - | SOME x => x - -fun pushF (env : env) n x dom ran = - {namedT = #namedT env, - - relE = #relE env, - namedE = #namedE env, - - F = IM.insert (#F env, n, (x, dom, ran))} - -fun lookupF (env : env) n = - case IM.find (#F env, n) of - NONE => raise UnboundF n - | SOME x => x - -fun declBinds env (d, _) = - case d of - DVal (x, n, t, _) => pushENamed env x n t - | DFun (n, x, dom, ran, _) => pushF env n x dom ran - | DPage _ => env - -end
--- a/src/flat_print.sig Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -(* Pretty-printing Laconic/Web flat-code language *) - -signature FLAT_PRINT = sig - val p_typ : FlatEnv.env -> Flat.typ Print.printer - val p_exp : FlatEnv.env -> Flat.exp Print.printer - val p_decl : FlatEnv.env -> Flat.decl Print.printer - val p_file : FlatEnv.env -> Flat.file Print.printer - - val debug : bool ref -end
--- a/src/flat_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -(* Pretty-printing flat-code Laconic/Web *) - -structure FlatPrint :> FLAT_PRINT = struct - -open Print.PD -open Print - -open Flat - -structure E = FlatEnv - -val debug = ref false - -val dummyTyp = (TNamed 0, ErrorMsg.dummySpan) - -fun p_typ' par env (t, _) = - case t of - TTop => string "?" - | TFun (t1, t2) => parenIf par (box [p_typ' true env t1, - space, - string "->", - space, - p_typ env t2]) - | TCode (t1, t2) => parenIf par (box [p_typ' true env t1, - space, - string "-->", - space, - p_typ env t2]) - | TRecord xcs => box [string "{", - p_list (fn (x, t) => - box [string x, - space, - string ":", - space, - p_typ env t]) xcs, - string "}"] - | TNamed n => - if !debug then - string (#1 (E.lookupTNamed env n) ^ "__" ^ Int.toString n) - else - string (#1 (E.lookupTNamed env n)) - | TFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"] - -and p_typ env = p_typ' false env - -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))) - handle E.UnboundRel _ => string ("UNBOUND" ^ Int.toString n)) - | ENamed n => - if !debug then - string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n) - else - string (#1 (E.lookupENamed env n)) - | EFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"] - | EFfiApp (m, x, es) => box [string "FFI(", - string m, - string ".", - string x, - string "(", - p_list (p_exp env) es, - string "))"] - | ECode n => string ("code$" ^ Int.toString n) - | EApp (e1, e2) => parenIf par (box [p_exp env e1, - space, - p_exp' true env e2]) - - | ERecord xes => box [string "{", - p_list (fn (x, e, _) => - box [string x, - space, - string "=", - space, - p_exp env e]) xes, - string "}"] - | EField (e, x) => - box [p_exp' true env e, - string ".", - string x] - - | ELet (xes, e) => - let - val (env, pps) = foldl (fn ((x, _, e), (env, pps)) => - (E.pushERel env x dummyTyp, - List.revAppend ([space, - string "val", - space, - string x, - space, - string "=", - space, - p_exp env e], - pps))) - (env, []) xes - in - box [string "let", - space, - box (rev pps), - space, - string "in", - space, - p_exp env e, - space, - string "end"] - end - - | EStrcat (e1, e2) => box [p_exp' true env e1, - space, - string "^", - space, - p_exp' true env e2] - - | EWrite e => box [string "write(", - p_exp env e, - string ")"] - - | ESeq (e1, e2) => box [p_exp env e1, - string ";", - space, - p_exp env e2] - -and p_exp env = p_exp' false env - -fun p_decl env ((d, _) : decl) = - case d of - DVal (x, n, t, e) => - let - val xp = if !debug then - box [string x, - string "__", - string (Int.toString n)] - else - string x - in - box [string "val", - space, - xp, - space, - string ":", - space, - p_typ env t, - space, - string "=", - space, - p_exp env e] - - end - | DFun (n, x, dom, ran, e) => - let - val xp = if !debug then - box [string x, - string "__", - string (Int.toString n)] - else - string x - in - box [string "fun", - space, - string "code$", - string (Int.toString n), - space, - string "(", - xp, - space, - string ":", - space, - p_typ env dom, - string ")", - space, - string ":", - space, - p_typ env ran, - space, - string "=", - space, - p_exp (E.pushERel env x dom) e] - - end - - | DPage (xcs, e) => box [string "page", - string "[", - p_list (fn (x, t) => - box [string x, - space, - string ":", - space, - p_typ env t]) xcs, - string "]", - space, - string "=", - space, - p_exp env e] - -fun p_file env file = - let - val (pds, _) = ListUtil.foldlMap (fn (d, env) => - (p_decl env d, - E.declBinds env d)) - env file - in - p_list_sep newline (fn x => x) pds - end - -end
--- a/src/flat_util.sig Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -signature FLAT_UTIL = sig - -structure Typ : sig - val compare : Flat.typ * Flat.typ -> order - val sortFields : (string * Flat.typ) list -> (string * Flat.typ) list - - val mapfold : (Flat.typ', 'state, 'abort) Search.mapfolder - -> (Flat.typ, 'state, 'abort) Search.mapfolder - - val map : (Flat.typ' -> Flat.typ') - -> Flat.typ -> Flat.typ - - val fold : (Flat.typ' * 'state -> 'state) - -> 'state -> Flat.typ -> 'state - - val exists : (Flat.typ' -> bool) -> Flat.typ -> bool -end - -structure Exp : sig - datatype binder = - NamedT of string * int * Flat.typ option - | RelE of string * Flat.typ - | NamedE of string * int * Flat.typ * Flat.exp option - - val mapfoldB : {typ : (Flat.typ', 'state, 'abort) Search.mapfolder, - exp : ('typtext, Flat.exp', 'state, 'abort) Search.mapfolderB, - bind : 'typtext * binder -> 'typtext} - -> ('typtext, Flat.exp, 'state, 'abort) Search.mapfolderB - val mapfold : {typ : (Flat.typ', 'state, 'abort) Search.mapfolder, - exp : (Flat.exp', 'state, 'abort) Search.mapfolder} - -> (Flat.exp, 'state, 'abort) Search.mapfolder - - val map : {typ : Flat.typ' -> Flat.typ', - exp : Flat.exp' -> Flat.exp'} - -> Flat.exp -> Flat.exp - val mapB : {typ : Flat.typ' -> Flat.typ', - exp : 'typtext -> Flat.exp' -> Flat.exp', - bind : 'typtext * binder -> 'typtext} - -> 'typtext -> (Flat.exp -> Flat.exp) - - val fold : {typ : Flat.typ' * 'state -> 'state, - exp : Flat.exp' * 'state -> 'state} - -> 'state -> Flat.exp -> 'state - - val exists : {typ : Flat.typ' -> bool, - exp : Flat.exp' -> bool} -> Flat.exp -> bool -end - -structure Decl : sig - datatype binder = datatype Exp.binder - - val mapfoldB : {typ : (Flat.typ', 'state, 'abort) Search.mapfolder, - exp : ('typtext, Flat.exp', 'state, 'abort) Search.mapfolderB, - decl : ('typtext, Flat.decl', 'state, 'abort) Search.mapfolderB, - bind : 'typtext * binder -> 'typtext} - -> ('typtext, Flat.decl, 'state, 'abort) Search.mapfolderB - val mapfold : {typ : (Flat.typ', 'state, 'abort) Search.mapfolder, - exp : (Flat.exp', 'state, 'abort) Search.mapfolder, - decl : (Flat.decl', 'state, 'abort) Search.mapfolder} - -> (Flat.decl, 'state, 'abort) Search.mapfolder - - val fold : {typ : Flat.typ' * 'state -> 'state, - exp : Flat.exp' * 'state -> 'state, - decl : Flat.decl' * 'state -> 'state} - -> 'state -> Flat.decl -> 'state -end - -structure File : sig - datatype binder = - NamedT of string * int * Flat.typ option - | RelE of string * Flat.typ - | NamedE of string * int * Flat.typ * Flat.exp option - | F of int * string * Flat.typ * Flat.typ * Flat.exp - - val mapfoldB : {typ : (Flat.typ', 'state, 'abort) Search.mapfolder, - exp : ('typtext, Flat.exp', 'state, 'abort) Search.mapfolderB, - decl : ('typtext, Flat.decl', 'state, 'abort) Search.mapfolderB, - bind : 'typtext * binder -> 'typtext} - -> ('typtext, Flat.file, 'state, 'abort) Search.mapfolderB - - val mapfold : {typ : (Flat.typ', 'state, 'abort) Search.mapfolder, - exp : (Flat.exp', 'state, 'abort) Search.mapfolder, - decl : (Flat.decl', 'state, 'abort) Search.mapfolder} - -> (Flat.file, 'state, 'abort) Search.mapfolder - - val mapB : {typ : Flat.typ' -> Flat.typ', - exp : 'typtext -> Flat.exp' -> Flat.exp', - decl : 'typtext -> Flat.decl' -> Flat.decl', - bind : 'typtext * binder -> 'typtext} - -> 'typtext -> Flat.file -> Flat.file - - val fold : {typ : Flat.typ' * 'state -> 'state, - exp : Flat.exp' * 'state -> 'state, - decl : Flat.decl' * 'state -> 'state} - -> 'state -> Flat.file -> 'state -end - -end
--- a/src/flat_util.sml Thu Jul 10 16:05:14 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,376 +0,0 @@ -(* Copyright (c) 2008, Adam Chlipala - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - The names of contributors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *) - -structure FlatUtil :> FLAT_UTIL = struct - -open Flat - -structure S = Search - -structure Typ = struct - -fun join (o1, o2) = - case o1 of - EQUAL => o2 () - | v => v - -fun joinL f (os1, os2) = - case (os1, os2) of - (nil, nil) => EQUAL - | (nil, _) => LESS - | (h1 :: t1, h2 :: t2) => - join (f (h1, h2), fn () => joinL f (t1, t2)) - | (_ :: _, nil) => GREATER - -fun compare ((t1, _), (t2, _)) = - case (t1, t2) of - (TTop, TTop) => EQUAL - | (TFun (d1, r1), TFun (d2, r2)) => - join (compare (d1, d2), fn () => compare (r1, r2)) - | (TCode (d1, r1), TCode (d2, r2)) => - join (compare (d1, d2), fn () => compare (r1, r2)) - | (TRecord xts1, TRecord xts2) => - let - val xts1 = sortFields xts1 - val xts2 = sortFields xts2 - in - joinL compareFields (xts1, xts2) - end - | (TNamed n1, TNamed n2) => Int.compare (n1, n2) - | (TFfi (m1, x1), TFfi (m2, x2)) => join (String.compare (m1, m2), fn () => String.compare (x1, x2)) - - | (TTop, _) => LESS - | (_, TTop) => GREATER - - | (TFun _, _) => LESS - | (_, TFun _) => GREATER - - | (TCode _, _) => LESS - | (_, TCode _) => GREATER - - | (TRecord _, _) => LESS - | (_, TRecord _) => GREATER - - | (TNamed _, _) => LESS - | (_, TNamed _) => GREATER - -and compareFields ((x1, t1), (x2, t2)) = - join (String.compare (x1, x2), - fn () => compare (t1, t2)) - -and sortFields xts = ListMergeSort.sort (fn (x, y) => compareFields (x, y) = GREATER) xts - -fun mapfold fc = - let - fun mft c acc = - S.bindP (mft' c acc, fc) - - and mft' (cAll as (c, loc)) = - case c of - TTop => S.return2 cAll - | TFun (t1, t2) => - S.bind2 (mft t1, - fn t1' => - S.map2 (mft t2, - fn t2' => - (TFun (t1', t2'), loc))) - | TCode (t1, t2) => - S.bind2 (mft t1, - fn t1' => - S.map2 (mft t2, - fn t2' => - (TCode (t1', t2'), loc))) - | TRecord xts => - S.map2 (ListUtil.mapfold (fn (x, t) => - S.map2 (mft t, - fn t' => - (x, t'))) - xts, - fn xts' => (TRecord xts', loc)) - | TNamed _ => S.return2 cAll - | TFfi _ => S.return2 cAll - in - mft - end - -fun map typ c = - case mapfold (fn c => fn () => S.Continue (typ c, ())) c () of - S.Return () => raise Fail "Flat_util.Typ.map" - | S.Continue (c, ()) => c - -fun fold typ s c = - case mapfold (fn c => fn s => S.Continue (c, typ (c, s))) c s of - S.Continue (_, s) => s - | S.Return _ => raise Fail "FlatUtil.Typ.fold: Impossible" - -fun exists typ k = - case mapfold (fn c => fn () => - if typ c then - S.Return () - else - S.Continue (c, ())) k () of - S.Return _ => true - | S.Continue _ => false - -end - -structure Exp = struct - -datatype binder = - NamedT of string * int * typ option - | RelE of string * typ - | NamedE of string * int * typ * exp option - -fun mapfoldB {typ = fc, exp = fe, bind} = - let - val mft = Typ.mapfold fc - - fun mfe ctx e acc = - S.bindP (mfe' ctx e acc, fe ctx) - - and mfe' ctx (eAll as (e, loc)) = - case e of - EPrim _ => S.return2 eAll - | ERel _ => S.return2 eAll - | ENamed _ => S.return2 eAll - | EFfi _ => S.return2 eAll - | EFfiApp (m, x, es) => - S.map2 (ListUtil.mapfold (fn e => mfe ctx e) es, - fn es' => - (EFfiApp (m, x, es'), loc)) - | ECode _ => S.return2 eAll - | EApp (e1, e2) => - S.bind2 (mfe ctx e1, - fn e1' => - S.map2 (mfe ctx e2, - fn e2' => - (EApp (e1', e2'), loc))) - - | ERecord xes => - S.map2 (ListUtil.mapfold (fn (x, e, t) => - S.bind2 (mfe ctx e, - fn e' => - S.map2 (mft t, - fn t' => - (x, e', t')))) - xes, - fn xes' => - (ERecord xes', loc)) - | EField (e, x) => - S.map2 (mfe ctx e, - fn e' => - (EField (e', x), loc)) - - | ELet (xes, e) => - S.bind2 (ListUtil.mapfold (fn (x, t, e) => - S.bind2 (mft t, - fn t' => - S.map2 (mfe ctx e, - fn e' => - (x, t', e')))) - xes, - fn xes' => - S.map2 (mfe ctx e, - fn e' => - (ELet (xes', e'), loc))) - - | EStrcat (e1, e2) => - S.bind2 (mfe ctx e1, - fn e1' => - S.map2 (mfe ctx e2, - fn e2' => - (EStrcat (e1', e2'), loc))) - - | EWrite e => - S.map2 (mfe ctx e, - fn e' => - (EWrite e', loc)) - - | ESeq (e1, e2) => - S.bind2 (mfe ctx e1, - fn e1' => - S.map2 (mfe ctx e2, - fn e2' => - (ESeq (e1', e2'), loc))) - in - mfe - end - -fun mapfold {typ = fc, exp = fe} = - mapfoldB {typ = fc, - exp = fn () => fe, - bind = fn ((), _) => ()} () - -fun mapB {typ, exp, bind} ctx e = - case mapfoldB {typ = fn c => fn () => S.Continue (typ c, ()), - exp = fn ctx => fn e => fn () => S.Continue (exp ctx e, ()), - bind = bind} ctx e () of - S.Continue (e, ()) => e - | S.Return _ => raise Fail "FlatUtil.Exp.mapB: Impossible" - -fun map {typ, exp} e = - case mapfold {typ = fn c => fn () => S.Continue (typ c, ()), - exp = fn e => fn () => S.Continue (exp e, ())} e () of - S.Return () => raise Fail "Flat_util.Exp.map" - | S.Continue (e, ()) => e - -fun fold {typ, exp} s e = - case mapfold {typ = fn c => fn s => S.Continue (c, typ (c, s)), - exp = fn e => fn s => S.Continue (e, exp (e, s))} e s of - S.Continue (_, s) => s - | S.Return _ => raise Fail "FlatUtil.Exp.fold: Impossible" - -fun exists {typ, exp} k = - case mapfold {typ = fn c => fn () => - if typ c then - S.Return () - else - S.Continue (c, ()), - exp = fn e => fn () => - if exp e then - S.Return () - else - S.Continue (e, ())} k () of - S.Return _ => true - | S.Continue _ => false - -end - -structure Decl = struct - -datatype binder = datatype Exp.binder - -fun mapfoldB {typ = fc, exp = fe, decl = fd, bind} = - let - val mft = Typ.mapfold fc - - val mfe = Exp.mapfoldB {typ = fc, exp = fe, bind = bind} - - fun mfd ctx d acc = - S.bindP (mfd' ctx d acc, fd ctx) - - and mfd' ctx (dAll as (d, loc)) = - case d of - DVal (x, n, t, e) => - S.bind2 (mft t, - fn t' => - S.map2 (mfe ctx e, - fn e' => - (DVal (x, n, t', e'), loc))) - | DFun (n, x, dom, ran, e) => - S.bind2 (mft dom, - fn dom' => - S.bind2 (mft ran, - fn ran' => - S.map2 (mfe ctx e, - fn e' => - (DFun (n, x, dom', ran', e'), loc)))) - | DPage (xts, e) => - S.bind2 (ListUtil.mapfold (fn (x, t) => - S.map2 (mft t, - fn t' => - (x, t'))) xts, - fn xts' => - S.map2 (mfe ctx e, - fn e' => - (DPage (xts', e'), loc))) - in - mfd - end - -fun mapfold {typ = fc, exp = fe, decl = fd} = - mapfoldB {typ = fc, - exp = fn () => fe, - decl = fn () => fd, - bind = fn ((), _) => ()} () - -fun fold {typ, exp, decl} s d = - case mapfold {typ = fn c => fn s => S.Continue (c, typ (c, s)), - exp = fn e => fn s => S.Continue (e, exp (e, s)), - decl = fn d => fn s => S.Continue (d, decl (d, s))} d s of - S.Continue (_, s) => s - | S.Return _ => raise Fail "FlatUtil.Decl.fold: Impossible" - -end - -structure File = struct - -datatype binder = - NamedT of string * int * typ option - | RelE of string * typ - | NamedE of string * int * typ * exp option - | F of int * string * Flat.typ * Flat.typ * Flat.exp - -fun mapfoldB (all as {bind, ...}) = - let - val mfd = Decl.mapfoldB all - - fun mff ctx ds = - case ds of - nil => S.return2 nil - | d :: ds' => - S.bind2 (mfd ctx d, - fn d' => - let - val ctx' = - case #1 d' of - DVal (x, n, t, e) => bind (ctx, NamedE (x, n, t, SOME e)) - | DFun v => bind (ctx, F v) - | DPage _ => ctx - in - S.map2 (mff ctx' ds', - fn ds' => - d' :: ds') - end) - in - mff - end - -fun mapfold {typ = fc, exp = fe, decl = fd} = - mapfoldB {typ = fc, - exp = fn () => fe, - decl = fn () => fd, - bind = fn ((), _) => ()} () - -fun mapB {typ, exp, decl, bind} ctx ds = - case mapfoldB {typ = fn c => fn () => S.Continue (typ c, ()), - exp = fn ctx => fn e => fn () => S.Continue (exp ctx e, ()), - decl = fn ctx => fn d => fn () => S.Continue (decl ctx d, ()), - bind = bind} ctx ds () of - S.Continue (ds, ()) => ds - | S.Return _ => raise Fail "FlatUtil.File.mapB: Impossible" - -fun fold {typ, exp, decl} s d = - case mapfold {typ = fn c => fn s => S.Continue (c, typ (c, s)), - exp = fn e => fn s => S.Continue (e, exp (e, s)), - decl = fn d => fn s => S.Continue (d, decl (d, s))} d s of - S.Continue (_, s) => s - | S.Return _ => raise Fail "FlatUtil.File.fold: Impossible" - -end - -end
--- a/src/lacweb.grm Thu Jul 10 16:05:14 2008 -0400 +++ b/src/lacweb.grm Sun Jul 13 10:17:06 2008 -0400 @@ -49,7 +49,7 @@ | ARROW | LARROW | DARROW | FN | PLUSPLUS | DOLLAR | TWIDDLE | STRUCTURE | SIGNATURE | STRUCT | SIG | END | FUNCTOR | WHERE | EXTERN - | INCLUDE | OPEN | CONSTRAINT | CONSTRAINTS | PAGE + | INCLUDE | OPEN | CONSTRAINT | CONSTRAINTS | EXPORT | XML_BEGIN of string | XML_END | NOTAGS of string @@ -147,7 +147,7 @@ [] => raise Fail "Impossible mpath parse [3]" | m :: ms => (DOpenConstraints (m, ms), s (OPENleft, mpathright))) | CONSTRAINT cterm TWIDDLE cterm (DConstraint (cterm1, cterm2), s (CONSTRAINTleft, ctermright)) - | PAGE eexp (DPage eexp, s (PAGEleft, eexpright)) + | EXPORT spath (DExport spath, s (EXPORTleft, spathright)) sgn : sgntm (sgntm) | FUNCTOR LPAREN CSYMBOL COLON sgn RPAREN COLON sgn
--- a/src/lacweb.lex Thu Jul 10 16:05:14 2008 -0400 +++ b/src/lacweb.lex Sun Jul 13 10:17:06 2008 -0400 @@ -264,7 +264,7 @@ <INITIAL> "open" => (Tokens.OPEN (pos yypos, pos yypos + size yytext)); <INITIAL> "constraint"=> (Tokens.CONSTRAINT (pos yypos, pos yypos + size yytext)); <INITIAL> "constraints"=> (Tokens.CONSTRAINTS (pos yypos, pos yypos + size yytext)); -<INITIAL> "page" => (Tokens.PAGE (pos yypos, pos yypos + size yytext)); +<INITIAL> "export" => (Tokens.EXPORT (pos yypos, pos yypos + size yytext)); <INITIAL> "Type" => (Tokens.TYPE (pos yypos, pos yypos + size yytext)); <INITIAL> "Name" => (Tokens.NAME (pos yypos, pos yypos + size yytext));
--- a/src/mono.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/mono.sml Sun Jul 13 10:17:06 2008 -0400 @@ -58,8 +58,8 @@ withtype exp = exp' located datatype decl' = - DVal of string * int * typ * exp - | DPage of (string * typ) list * exp + DVal of string * int * typ * exp * string + | DExport of int withtype decl = decl' located
--- a/src/mono_env.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/mono_env.sig Sun Jul 13 10:17:06 2008 -0400 @@ -40,8 +40,8 @@ val pushERel : env -> string -> Mono.typ -> env val lookupERel : env -> int -> string * Mono.typ - val pushENamed : env -> string -> int -> Mono.typ -> Mono.exp option -> env - val lookupENamed : env -> int -> string * Mono.typ * Mono.exp option + val pushENamed : env -> string -> int -> Mono.typ -> Mono.exp option -> string -> env + val lookupENamed : env -> int -> string * Mono.typ * Mono.exp option * string val declBinds : env -> Mono.decl -> env
--- a/src/mono_env.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/mono_env.sml Sun Jul 13 10:17:06 2008 -0400 @@ -39,7 +39,7 @@ namedT : (string * typ option) IM.map, relE : (string * typ) list, - namedE : (string * typ * exp option) IM.map + namedE : (string * typ * exp option * string) IM.map } val empty = { @@ -70,11 +70,11 @@ (List.nth (#relE env, n)) handle Subscript => raise UnboundRel n -fun pushENamed (env : env) x n t eo = +fun pushENamed (env : env) x n t eo s = {namedT = #namedT env, relE = #relE env, - namedE = IM.insert (#namedE env, n, (x, t, eo))} + namedE = IM.insert (#namedE env, n, (x, t, eo, s))} fun lookupENamed (env : env) n = case IM.find (#namedE env, n) of @@ -83,7 +83,7 @@ fun declBinds env (d, _) = case d of - DVal (x, n, t, e) => pushENamed env x n t (SOME e) - | DPage _ => env + DVal (x, n, t, e, s) => pushENamed env x n t (SOME e) s + | DExport _ => env end
--- a/src/mono_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/mono_print.sml Sun Jul 13 10:17:06 2008 -0400 @@ -62,6 +62,12 @@ 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)) + fun p_exp' par env (e, _) = case e of EPrim p => Prim.p_t p @@ -70,11 +76,8 @@ string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n) else string (#1 (E.lookupERel env n)) - | ENamed n => - if !debug then - string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n) - else - string (#1 (E.lookupENamed env n)) + | ENamed n => p_enamed env n + | EFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"] | EFfiApp (m, x, es) => box [string "FFI(", string m, @@ -131,7 +134,7 @@ fun p_decl env ((d, _) : decl) = case d of - DVal (x, n, t, e) => + DVal (x, n, t, e, s) => let val xp = if !debug then box [string x, @@ -144,6 +147,10 @@ space, xp, space, + string "as", + space, + string s, + space, string ":", space, p_typ env t, @@ -152,19 +159,10 @@ space, p_exp env e] end - | DPage (xcs, e) => box [string "page", - string "[", - p_list (fn (x, t) => - box [string x, - space, - string ":", - space, - p_typ env t]) xcs, - string "]", - space, - string "=", - space, - p_exp env e] + + | DExport n => box [string "export", + space, + p_enamed env n] fun p_file env file = let
--- a/src/mono_util.sig Thu Jul 10 16:05:14 2008 -0400 +++ b/src/mono_util.sig Sun Jul 13 10:17:06 2008 -0400 @@ -28,6 +28,9 @@ signature MONO_UTIL = sig structure Typ : sig + val compare : Mono.typ * Mono.typ -> order + val sortFields : (string * Mono.typ) list -> (string * Mono.typ) list + val mapfold : (Mono.typ', 'state, 'abort) Search.mapfolder -> (Mono.typ, 'state, 'abort) Search.mapfolder @@ -44,7 +47,7 @@ datatype binder = NamedT of string * int * Mono.typ option | RelE of string * Mono.typ - | NamedE of string * int * Mono.typ * Mono.exp option + | NamedE of string * int * Mono.typ * Mono.exp option * string val mapfoldB : {typ : (Mono.typ', 'state, 'abort) Search.mapfolder, exp : ('typtext, Mono.exp', 'state, 'abort) Search.mapfolderB,
--- a/src/mono_util.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/mono_util.sml Sun Jul 13 10:17:06 2008 -0400 @@ -33,6 +33,48 @@ structure Typ = struct +fun join (o1, o2) = + case o1 of + EQUAL => o2 () + | v => v + +fun joinL f (os1, os2) = + case (os1, os2) of + (nil, nil) => EQUAL + | (nil, _) => LESS + | (h1 :: t1, h2 :: t2) => + join (f (h1, h2), fn () => joinL f (t1, t2)) + | (_ :: _, nil) => GREATER + +fun compare ((t1, _), (t2, _)) = + case (t1, t2) of + (TFun (d1, r1), TFun (d2, r2)) => + join (compare (d1, d2), fn () => compare (r1, r2)) + | (TRecord xts1, TRecord xts2) => + let + val xts1 = sortFields xts1 + val xts2 = sortFields xts2 + in + joinL compareFields (xts1, xts2) + end + | (TNamed n1, TNamed n2) => Int.compare (n1, n2) + | (TFfi (m1, x1), TFfi (m2, x2)) => join (String.compare (m1, m2), fn () => String.compare (x1, x2)) + + | (TFun _, _) => LESS + | (_, TFun _) => GREATER + + | (TRecord _, _) => LESS + | (_, TRecord _) => GREATER + + | (TNamed _, _) => LESS + | (_, TNamed _) => GREATER + +and compareFields ((x1, t1), (x2, t2)) = + join (String.compare (x1, x2), + fn () => compare (t1, t2)) + +and sortFields xts = ListMergeSort.sort (fn (x, y) => compareFields (x, y) = GREATER) xts + fun mapfold fc = let fun mft c acc = @@ -85,7 +127,7 @@ datatype binder = NamedT of string * int * typ option | RelE of string * typ - | NamedE of string * int * typ * exp option + | NamedE of string * int * typ * exp option * string fun mapfoldB {typ = fc, exp = fe, bind} = let @@ -211,21 +253,13 @@ and mfd' ctx (dAll as (d, loc)) = case d of - DVal (x, n, t, e) => + DVal (x, n, t, e, s) => S.bind2 (mft t, fn t' => S.map2 (mfe ctx e, fn e' => - (DVal (x, n, t', e'), loc))) - | DPage (xts, e) => - S.bind2 (ListUtil.mapfold (fn (x, t) => - S.map2 (mft t, - fn t' => - (x, t'))) xts, - fn xts' => - S.map2 (mfe ctx e, - fn e' => - (DPage (xts', e'), loc))) + (DVal (x, n, t', e', s), loc))) + | DExport _ => S.return2 dAll in mfd end @@ -262,8 +296,8 @@ let val ctx' = case #1 d' of - DVal (x, n, t, e) => bind (ctx, NamedE (x, n, t, SOME e)) - | DPage _ => ctx + DVal (x, n, t, e, s) => bind (ctx, NamedE (x, n, t, SOME e, s)) + | DExport _ => ctx in S.map2 (mff ctx' ds', fn ds' =>
--- a/src/monoize.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/monoize.sml Sun Jul 13 10:17:06 2008 -0400 @@ -203,15 +203,9 @@ in case d of L.DCon _ => NONE - | L.DVal (x, n, t, e) => SOME (Env.pushENamed env x n t (SOME e), - (L'.DVal (x, n, monoType env t, monoExp env e), loc)) - | L.DPage ((c, _), e) => - (case c of - L.CRecord (_, vs) => SOME (env, - (L'.DPage (map (fn (nm, t) => (monoName env nm, - monoType env t)) vs, - monoExp env e), loc)) - | _ => poly ()) + | L.DVal (x, n, t, e, s) => SOME (Env.pushENamed env x n t (SOME e) s, + (L'.DVal (x, n, monoType env t, monoExp env e, s), loc)) + | L.DExport n => SOME (env, (L'.DExport n, loc)) end fun monoize env ds =
--- a/src/reduce.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/reduce.sml Sun Jul 13 10:17:06 2008 -0400 @@ -115,7 +115,7 @@ U.Decl.RelC (x, k) => E.pushCRel env x k | U.Decl.NamedC (x, n, k, co) => E.pushCNamed env x n k co | U.Decl.RelE (x, t) => E.pushERel env x t - | U.Decl.NamedE (x, n, t, eo) => E.pushENamed env x n t eo + | U.Decl.NamedE (x, n, t, eo, s) => E.pushENamed env x n t eo s fun kind k = k @@ -143,7 +143,7 @@ case e of ENamed n => (case E.lookupENamed env n of - (_, _, SOME e') => #1 e' + (_, _, SOME e', _) => #1 e' | _ => e) | ECApp ((EApp ((EApp ((ECApp ((EFold ks, _), ran), _), f), _), i), _), (CRecord (k, xcs), loc)) =>
--- a/src/shake.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/shake.sml Sun Jul 13 10:17:06 2008 -0400 @@ -43,13 +43,13 @@ fun shake file = let - val (page_cs, page_es) = List.foldl - (fn ((DPage (c, e), _), (cs, es)) => (c :: cs, e :: es) - | (_, acc) => acc) ([], []) file + val page_es = List.foldl + (fn ((DExport n, _), page_es) => n :: page_es + | (_, page_es) => page_es) [] file val (cdef, edef) = foldl (fn ((DCon (_, n, _, c), _), (cdef, edef)) => (IM.insert (cdef, n, c), edef) - | ((DVal (_, n, t, e), _), (cdef, edef)) => (cdef, IM.insert (edef, n, (t, e))) - | ((DPage _, _), acc) => acc) + | ((DVal (_, n, t, e, _), _), (cdef, edef)) => (cdef, IM.insert (edef, n, (t, e))) + | ((DExport _, _), acc) => acc) (IM.empty, IM.empty) file fun kind (_, s) = s @@ -90,14 +90,16 @@ and shakeExp s = U.Exp.fold {kind = kind, con = con, exp = exp} s - val s = {con = IS.empty, exp = IS.empty} - - val s = foldl (fn (c, s) => U.Con.fold {kind = kind, con = con} s c) s page_cs - val s = foldl (fn (e, s) => U.Exp.fold {kind = kind, con = con, exp = exp} s e) s page_es + val s = {con = IS.empty, exp = IS.addList (IS.empty, page_es)} + + val s = foldl (fn (n, s) => + case IM.find (edef, n) of + NONE => raise Fail "Shake: Couldn't find 'val'" + | SOME (t, e) => shakeExp (shakeCon s t) e) s page_es in List.filter (fn (DCon (_, n, _, _), _) => IS.member (#con s, n) - | (DVal (_, n, _, _), _) => IS.member (#exp s, n) - | (DPage _, _) => true) file + | (DVal (_, n, _, _, _), _) => IS.member (#exp s, n) + | (DExport _, _) => true) file end end
--- a/src/source.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/source.sml Sun Jul 13 10:17:06 2008 -0400 @@ -113,7 +113,7 @@ | DOpen of string * string list | DConstraint of con * con | DOpenConstraints of string * string list - | DPage of exp + | DExport of str and str' = StrConst of decl list
--- a/src/source_print.sml Thu Jul 10 16:05:14 2008 -0400 +++ b/src/source_print.sml Sun Jul 13 10:17:06 2008 -0400 @@ -418,9 +418,9 @@ space, p_list_sep (string ".") string (m :: ms)] - | DPage e => box [string "page", - space, - p_exp e] + | DExport str => box [string "export", + space, + p_str str] and p_str (str, _) = case str of
--- a/src/sources Thu Jul 10 16:05:14 2008 -0400 +++ b/src/sources Sun Jul 13 10:17:06 2008 -0400 @@ -92,20 +92,6 @@ mono_opt.sig mono_opt.sml -flat.sml - -flat_util.sig -flat_util.sml - -flat_env.sig -flat_env.sml - -flat_print.sig -flat_print.sml - -cloconv.sig -cloconv.sml - cjr.sml cjr_env.sig
--- a/tests/attrs.lac Thu Jul 10 16:05:14 2008 -0400 +++ b/tests/attrs.lac Sun Jul 13 10:17:06 2008 -0400 @@ -1,5 +1,3 @@ val main = fn () => <html><body> <font size=42 face="awesome">Welcome</font> </body></html> - -page main