diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/c/urweb.c | 1 | ||||
-rw-r--r-- | src/cjr_print.sml | 15 | ||||
-rw-r--r-- | src/compiler.sig | 4 | ||||
-rw-r--r-- | src/compiler.sml | 14 | ||||
-rw-r--r-- | src/elab_env.sig | 2 | ||||
-rw-r--r-- | src/elab_env.sml | 4 | ||||
-rw-r--r-- | src/elab_util.sig | 3 | ||||
-rw-r--r-- | src/elab_util.sml | 6 | ||||
-rw-r--r-- | src/elaborate.sml | 11 | ||||
-rw-r--r-- | src/iflow.sml | 8 | ||||
-rw-r--r-- | src/jscomp.sml | 5 | ||||
-rw-r--r-- | src/main.mlton.sml | 41 | ||||
-rw-r--r-- | src/postgres.sml | 2 | ||||
-rw-r--r-- | src/reduce.sml | 4 | ||||
-rw-r--r-- | src/settings.sig | 7 | ||||
-rw-r--r-- | src/settings.sml | 69 | ||||
-rw-r--r-- | src/sources | 3 | ||||
-rw-r--r-- | src/unnest.sml | 242 |
18 files changed, 305 insertions, 136 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c index a6639ef2..50aac5e8 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -519,7 +519,6 @@ size_t uw_heap_max = SIZE_MAX; size_t uw_script_max = SIZE_MAX; uw_context uw_init(int id, uw_loggers *lg) { - puts("Initializing"); uw_context ctx = malloc(sizeof(struct uw_context)); ctx->app = NULL; diff --git a/src/cjr_print.sml b/src/cjr_print.sml index 9e046d84..2c2133d6 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -2944,17 +2944,10 @@ fun p_file env (ds, ps) = file = "app." ^ timestamp ^ ".js"} val allScripts = - let - val scripts = - "<script type=\\\"text/javascript\\\" src=\\\"" - ^ app_js - ^ "\\\"></script>\\n" - in - foldl (fn (x, scripts) => - scripts - ^ "<script type=\\\"text/javascript\\\" src=\\\"" ^ x ^ "\\\"></script>\\n") - scripts (Settings.getScripts ()) - end + foldl (fn (x, scripts) => + scripts + ^ "<script type=\\\"text/javascript\\\" src=\\\"" ^ x ^ "\\\"></script>\\n") + "" (Settings.getScripts () @ [app_js]) fun p_page (ek, s, n, ts, ran, side, dbmode, tellSig) = let diff --git a/src/compiler.sig b/src/compiler.sig index 1ab0f7ae..c154240a 100644 --- a/src/compiler.sig +++ b/src/compiler.sig @@ -114,7 +114,7 @@ signature COMPILER = sig val untangle : (Mono.file, Mono.file) phase val mono_reduce : (Mono.file, Mono.file) phase val mono_shake : (Mono.file, Mono.file) phase - (* val iflow : (Mono.file, Mono.file) phase *) + val iflow : (Mono.file, Mono.file) phase val namejs : (Mono.file, Mono.file) phase val scriptcheck : (Mono.file, Mono.file) phase val jscomp : (Mono.file, Mono.file) phase @@ -169,7 +169,7 @@ signature COMPILER = sig val toMono_reduce : (string, Mono.file) transform val toMono_shake : (string, Mono.file) transform val toMono_opt2 : (string, Mono.file) transform - (* val toIflow : (string, Mono.file) transform *) + val toIflow : (string, Mono.file) transform val toNamejs : (string, Mono.file) transform val toNamejs_untangle : (string, Mono.file) transform val toScriptcheck : (string, Mono.file) transform diff --git a/src/compiler.sml b/src/compiler.sml index d91d02aa..bf7491e5 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -413,11 +413,7 @@ fun inputCommentableLine inf = val lastUrp = ref "" fun parseUrp' accLibs fname = - (if !lastUrp = fname then - () - else - ModDb.reset (); - lastUrp := fname; + (lastUrp := fname; if not (Posix.FileSys.access (fname ^ ".urp", []) orelse Posix.FileSys.access (fname ^ "/lib.urp", [])) andalso Posix.FileSys.access (fname ^ ".ur", []) then let @@ -879,6 +875,10 @@ fun parseUrp' accLibs fname = url := {action = Settings.Allow, kind = Settings.Exact, pattern = uri} :: !url) | _ => ErrorMsg.error "Bad 'file' arguments") + | "jsFile" => + (Settings.setFilePath thisPath; + Settings.addJsFile arg) + | _ => ErrorMsg.error ("Unrecognized command '" ^ cmd ^ "'"); read () end @@ -1372,21 +1372,19 @@ val toMono_shake = transform mono_shake "mono_shake1" o toMono_reduce val toMono_opt2 = transform mono_opt "mono_opt2" o toMono_shake -(* val iflow = { func = (fn file => (if !doIflow then Iflow.check file else (); file)), print = MonoPrint.p_file MonoEnv.empty } val toIflow = transform iflow "iflow" o toMono_opt2 -*) val namejs = { func = NameJS.rewrite, print = MonoPrint.p_file MonoEnv.empty } -val toNamejs = transform namejs "namejs" o toMono_opt2 +val toNamejs = transform namejs "namejs" o toIflow val toNamejs_untangle = transform untangle "namejs_untangle" o toNamejs diff --git a/src/elab_env.sig b/src/elab_env.sig index e0c589c4..cbc85cdd 100644 --- a/src/elab_env.sig +++ b/src/elab_env.sig @@ -37,6 +37,8 @@ signature ELAB_ENV = sig type env + val dump : env -> unit + val empty : env exception UnboundRel of int diff --git a/src/elab_env.sml b/src/elab_env.sml index 9c9cd14f..3523b576 100644 --- a/src/elab_env.sml +++ b/src/elab_env.sml @@ -239,6 +239,10 @@ type env = { str : (string * sgn) IM.map } +fun dump (env : env) = + (print "NamedC:\n"; + IM.appi (fn (n, (x, k, co)) => print (x ^ " [" ^ Int.toString n ^ "]\n")) (#namedC env)) + val namedCounter = ref 0 fun newNamed () = diff --git a/src/elab_util.sig b/src/elab_util.sig index 6c08442b..dc07f6f8 100644 --- a/src/elab_util.sig +++ b/src/elab_util.sig @@ -41,6 +41,9 @@ structure Kind : sig val mapB : {kind : 'context -> Elab.kind' -> Elab.kind', bind : 'context * string -> 'context} -> 'context -> (Elab.kind -> Elab.kind) + val foldB : {kind : 'context * Elab.kind' * 'state -> 'state, + bind : 'context * string -> 'context} + -> 'context -> 'state -> Elab.kind -> 'state end structure Con : sig diff --git a/src/elab_util.sml b/src/elab_util.sml index acc696dd..ed2e82a0 100644 --- a/src/elab_util.sml +++ b/src/elab_util.sml @@ -116,6 +116,12 @@ fun exists f k = S.Return _ => true | S.Continue _ => false +fun foldB {kind, bind} ctx st k = + case mapfoldB {kind = fn ctx => fn k => fn st => S.Continue (k, kind (ctx, k, st)), + bind = bind} ctx k st of + S.Continue (_, st) => st + | S.Return _ => raise Fail "ElabUtil.Kind.foldB: Impossible" + end val mliftConInCon = ref (fn n : int => fn c : con => (raise Fail "You didn't set ElabUtil.mliftConInCon!") : con) diff --git a/src/elaborate.sml b/src/elaborate.sml index c3e81b65..25cce6bd 100644 --- a/src/elaborate.sml +++ b/src/elaborate.sml @@ -1359,7 +1359,9 @@ end and unifyCons env loc c1 c2 = - unifyCons' env loc c1 c2 + ((*Print.prefaces "uc" [("c1", p_con env c1), + ("c2", p_con env c2)];*) + unifyCons' env loc c1 c2) handle CUnify' (env', err) => raise CUnify (c1, c2, env', err) | KUnify (arg as {3 = env', ...}) => raise CUnify (c1, c2, env', CKind arg) @@ -3079,6 +3081,8 @@ and subSgn' counterparts env strLoc sgn1 (sgn2 as (_, loc2)) = fun cpart n = IM.find (!counterparts, n) fun cparts (n2, n1) = counterparts := IM.insert (!counterparts, n2, n1) + fun uncparts n2 = (counterparts := #1 (IM.remove (!counterparts, n2))) + handle NotFound => () val sub2 = U.Con.map {kind = fn k => k, con = fn c => @@ -3107,7 +3111,8 @@ and subSgn' counterparts env strLoc sgn1 (sgn2 as (_, loc2)) = if E.checkENamed env n then env else - E.pushCNamedAs env x n k (SOME c) + (uncparts n; + E.pushCNamedAs env x n k (SOME c)) | L'.SgiConAbs (x, n, k) => if E.checkENamed env n then env @@ -5019,5 +5024,7 @@ fun elabFile basis basis_tm topStr topSgn top_tm env file = @ (L'.DStr ("Top", top_n, topSgn, topStr), ErrorMsg.dummySpan) :: ds' @ file end + handle e => (ModDb.revert (); + raise e) end diff --git a/src/iflow.sml b/src/iflow.sml index f68d8f72..8bde7ea3 100644 --- a/src/iflow.sml +++ b/src/iflow.sml @@ -1263,7 +1263,7 @@ fun doQuery (arg : 'a doQuery) (e as (_, loc)) = val new = ref NONE val old = ref NONE - val rvs = map (fn (tab, v) => + val rvs = map (fn Table (tab, v) => let val nv = #NextVar arg () in @@ -1272,7 +1272,8 @@ fun doQuery (arg : 'a doQuery) (e as (_, loc)) = | "Old" => old := SOME (tab, nv) | _ => (); (v, nv) - end) (#From r) + end + | _ => raise Fail "Iflow: not ready for joins or nesteds") (#From r) fun rvOf v = case List.find (fn (v', _) => v' = v) rvs of @@ -1282,7 +1283,8 @@ fun doQuery (arg : 'a doQuery) (e as (_, loc)) = val expIn = expIn (#NextVar arg) (#Env arg) rvOf val saved = #Save arg () - fun addFrom () = app (fn (t, v) => #Add arg (AReln (Sql t, [rvOf v]))) (#From r) + fun addFrom () = app (fn Table (t, v) => #Add arg (AReln (Sql t, [rvOf v])) + | _ => raise Fail "Iflow: not ready for joins or nesteds") (#From r) fun usedFields e = case e of diff --git a/src/jscomp.sml b/src/jscomp.sml index 4c6bf0a9..e5a0cb27 100644 --- a/src/jscomp.sml +++ b/src/jscomp.sml @@ -1358,8 +1358,9 @@ fun process (file : file) = val script = if !foundJavaScript then - lines ^ urlRules ^ String.concat (rev (#script st)) - ^ "\ntime_format = \"" ^ Prim.toCString (Settings.getTimeFormat ()) ^ "\";\n" + String.concatWith "" ((lines ^ urlRules ^ String.concat (rev (#script st)) + ^ "\ntime_format = \"" ^ Prim.toCString (Settings.getTimeFormat ()) ^ "\";\n") + :: map (fn r => "\n// " ^ #Filename r ^ "\n\n" ^ #Content r ^ "\n") (Settings.listJsFiles ())) else "" in diff --git a/src/main.mlton.sml b/src/main.mlton.sml index 164ddfbd..67732b58 100644 --- a/src/main.mlton.sml +++ b/src/main.mlton.sml @@ -16,7 +16,7 @@ * 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 + * 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 @@ -64,7 +64,7 @@ fun oneRun args = fun doArgs args = case args of [] => () - | "-version" :: rest => + | "-version" :: rest => printVersion () | "-numeric-version" :: rest => printNumericVersion () @@ -285,19 +285,25 @@ val () = case CommandLine.arguments () of in case cmd of "" => - let - val success = (oneRun (rev args)) - handle ex => (print "unhandled exception:\n"; - print (General.exnMessage ex ^ "\n"); - OS.Process.failure) - in - TextIO.flushOut TextIO.stdOut; - TextIO.flushOut TextIO.stdErr; - send (sock, if OS.Process.isSuccess success then - "\001" - else - "\002") - end + (case args of + ["stop", "daemon"] => + (((Socket.close listen; + OS.FileSys.remove socket) handle OS.SysErr _ => ()); + OS.Process.exit OS.Process.success) + | _ => + let + val success = (oneRun (rev args)) + handle ex => (print "unhandled exception:\n"; + print (General.exnMessage ex ^ "\n"); + OS.Process.failure) + in + TextIO.flushOut TextIO.stdOut; + TextIO.flushOut TextIO.stdErr; + send (sock, if OS.Process.isSuccess success then + "\001" + else + "\002") + end) | _ => loop' (rest, cmd :: args) end end handle OS.SysErr _ => () @@ -312,7 +318,7 @@ val () = case CommandLine.arguments () of (* Redirect the daemon's output to the socket. *) redirect Posix.FileSys.stdout; redirect Posix.FileSys.stderr; - + loop' ("", []); Socket.close sock; @@ -321,6 +327,7 @@ val () = case CommandLine.arguments () of Posix.IO.close oldStdout; Posix.IO.close oldStderr; + Settings.reset (); MLton.GC.pack (); loop () end @@ -330,8 +337,6 @@ val () = case CommandLine.arguments () of Socket.listen (listen, 1); loop () end) - | ["daemon", "stop"] => - (OS.FileSys.remove socket handle OS.SysErr _ => OS.Process.exit OS.Process.success) | args => let val sock = UnixSock.Strm.socket () diff --git a/src/postgres.sml b/src/postgres.sml index bc1238c0..1c95f414 100644 --- a/src/postgres.sml +++ b/src/postgres.sml @@ -278,7 +278,7 @@ fun init {dbstring, prepared = ss, tables, views, sequences} = val sl = CharVector.map Char.toLower s val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '" - ^ sl ^ "' AND relkind = 'S'" + ^ sl ^ "' AND relkind = 'S' AND pg_catalog.pg_table_is_visible(oid)" in box [string "res = PQexec(conn, \"", string q, diff --git a/src/reduce.sml b/src/reduce.sml index 8691b93a..0762a4a1 100644 --- a/src/reduce.sml +++ b/src/reduce.sml @@ -588,7 +588,7 @@ fun kindConAndExp (namedC, namedE) = (p, body') end) pes - val cc' = {disc = disc, result = c2} + val cc' = {disc = con env' disc, result = con env' c2} in (ECase (e, pes', cc'), loc) end @@ -626,7 +626,7 @@ fun kindConAndExp (namedC, namedE) = end) pes val c' = E.subConInCon (0, c) c' - val cc' = {disc = disc, result = c'} + val cc' = {disc = con env disc, result = con env c'} in (ECase (e, pes', cc'), loc) end diff --git a/src/settings.sig b/src/settings.sig index e94832e0..732a31fa 100644 --- a/src/settings.sig +++ b/src/settings.sig @@ -27,6 +27,10 @@ signature SETTINGS = sig + (* Call this when compiling a new project, e.g. with the Ur/Web daemon or from the SML/NJ REPL. + * Some settings stay, but most are reset, especially files cached for the app to serve. *) + val reset : unit -> unit + (* XXX these should be unit -> string too *) val configBin : string ref val configLib : string ref @@ -287,4 +291,7 @@ signature SETTINGS = sig val addFile : {Uri : string, LoadFromFilename : string} -> unit val listFiles : unit -> {Uri : string, ContentType : string option, LastModified : Time.time, Bytes : Word8Vector.vector} list + + val addJsFile : string (* filename *) -> unit + val listJsFiles : unit -> {Filename : string, Content : string} list end diff --git a/src/settings.sml b/src/settings.sml index f9125c64..94692a2e 100644 --- a/src/settings.sml +++ b/src/settings.sml @@ -727,11 +727,6 @@ val minHeap = ref 0 fun setMinHeap n = if n >= 0 then minHeap := n else raise Fail "Trying to set negative minHeap" fun getMinHeap () = !minHeap -structure SS = BinarySetFn(struct - type ord_key = string - val compare = String.compare - end) - val alwaysInline = ref SS.empty fun addAlwaysInline s = alwaysInline := SS.add (!alwaysInline, s) fun checkAlwaysInline s = SS.member (!alwaysInline, s) @@ -913,4 +908,68 @@ fun addFile {Uri, LoadFromFilename} = fun listFiles () = map #2 (SM.listItems (!files)) +val jsFiles = ref (SM.empty : {Filename : string, Content : string} SM.map) + +fun addJsFile LoadFromFilename = + let + val path = OS.Path.concat (!filePath, LoadFromFilename) + val inf = TextIO.openIn path + in + jsFiles := SM.insert (!jsFiles, + path, + {Filename = LoadFromFilename, + Content = TextIO.inputAll inf}); + TextIO.closeIn inf + end handle IO.Io _ => + ErrorMsg.error ("Error loading file " ^ LoadFromFilename) + | OS.SysErr (s, _) => + ErrorMsg.error ("Error loading file " ^ LoadFromFilename ^ " (" ^ s ^ ")") + +fun listJsFiles () = SM.listItems (!jsFiles) + +fun reset () = + (urlPrefixFull := "/"; + urlPrefix := "/"; + urlPrePrefix := ""; + timeout := 0; + headers := []; + scripts := []; + clientToServer := clientToServerBase; + effectful := effectfulBase; + benign := benignBase; + client := clientBase; + server := serverBase; + jsFuncs := jsFuncsBase; + rewrites := []; + url := []; + mime := []; + request := []; + response := []; + env := []; + debug := false; + dbstring := NONE; + exe := NONE; + sql := NONE; + coreInline := 5; + monoInline := 5; + staticLinking := false; + deadlines := false; + sigFile := NONE; + safeGet := SS.empty; + onError := NONE; + limitsList := []; + minHeap := 0; + alwaysInline := SS.empty; + neverInline := SS.empty; + noXsrfProtection := SS.empty; + timeFormat := "%c"; + mangle := true; + html5 := false; + less := false; + noMimeFile := false; + mimeTypes := NONE; + files := SM.empty; + jsFiles := SM.empty; + filePath := ".") + end diff --git a/src/sources b/src/sources index 1436575d..8bf80bc6 100644 --- a/src/sources +++ b/src/sources @@ -207,6 +207,9 @@ $(SRC)/mono_shake.sml $(SRC)/fuse.sig $(SRC)/fuse.sml +$(SRC)/iflow.sig +$(SRC)/iflow.sml + $(SRC)/name_js.sig $(SRC)/name_js.sml diff --git a/src/unnest.sml b/src/unnest.sml index fceb5026..3034eb6e 100644 --- a/src/unnest.sml +++ b/src/unnest.sml @@ -65,44 +65,71 @@ val subExpInExp = | ((xn, rep), U.Exp.RelC _) => (xn, E.liftConInExp 0 rep) | (ctx, _) => ctx} -val fvsCon = U.Con.foldB {kind = fn (_, _, st) => st, - con = fn (cb, c, cvs) => +val fvsKind = U.Kind.foldB {kind = fn (kb, k, kvs) => + case k of + KRel n => + if n >= kb then + IS.add (kvs, n - kb) + else + kvs + | _ => kvs, + bind = fn (kb, b) => kb + 1} + 0 IS.empty + +val fvsCon = U.Con.foldB {kind = fn ((kb, _), k, st as (kvs, cvs)) => + case k of + KRel n => + if n >= kb then + (IS.add (kvs, n - kb), cvs) + else + st + | _ => st, + con = fn ((_, cb), c, st as (kvs, cvs)) => case c of CRel n => if n >= cb then - IS.add (cvs, n - cb) + (kvs, IS.add (cvs, n - cb)) else - cvs - | _ => cvs, - bind = fn (cb, b) => + st + | _ => st, + bind = fn (ctx as (kb, cb), b) => case b of - U.Con.RelC _ => cb + 1 - | _ => cb} - 0 IS.empty - -fun fvsExp nr = U.Exp.foldB {kind = fn (_, _, st) => st, - con = fn ((cb, eb), c, st as (cvs, evs)) => + U.Con.RelK _ => (kb + 1, cb + 1) + | U.Con.RelC _ => (kb, cb + 1) + | _ => ctx} + (0, 0) (IS.empty, IS.empty) + +fun fvsExp nr = U.Exp.foldB {kind = fn ((kb, _, _), k, st as (kvs, cvs, evs)) => + case k of + KRel n => + if n >= kb then + (IS.add (kvs, n - kb), cvs, evs) + else + st + | _ => st, + con = fn ((kb, cb, eb), c, st as (kvs, cvs, evs)) => case c of CRel n => if n >= cb then - (IS.add (cvs, n - cb), evs) + (kvs, IS.add (cvs, n - cb), evs) else st | _ => st, - exp = fn ((cb, eb), e, st as (cvs, evs)) => + exp = fn ((kb, cb, eb), e, st as (kvs, cvs, evs)) => case e of ERel n => if n >= eb then - (cvs, IS.add (evs, n - eb)) + (kvs, cvs, IS.add (evs, n - eb)) else st | _ => st, - bind = fn (ctx as (cb, eb), b) => + bind = fn (ctx as (kb, cb, eb), b) => case b of - U.Exp.RelC _ => (cb + 1, eb) - | U.Exp.RelE _ => (cb, eb + 1) + U.Exp.RelK _ => (kb + 1, cb, eb) + | U.Exp.RelC _ => (kb, cb + 1, eb) + | U.Exp.RelE _ => (kb, cb, eb + 1) | _ => ctx} - (0, nr) (IS.empty, IS.empty) + (0, 0, nr) (IS.empty, IS.empty, IS.empty) fun positionOf (x : int) ls = let @@ -123,46 +150,62 @@ fun positionOf (x : int) ls = ^ ")") end -fun squishCon cfv = - U.Con.mapB {kind = fn _ => fn k => k, - con = fn cb => fn c => - case c of - CRel n => - if n >= cb then - CRel (positionOf (n - cb) cfv + cb) - else - c - | _ => c, - bind = fn (cb, b) => - case b of - U.Con.RelC _ => cb + 1 - | _ => cb} - 0 - -fun squishExp (nr, cfv, efv) = - U.Exp.mapB {kind = fn _ => fn k => k, - con = fn (cb, eb) => fn c => - case c of - CRel n => - if n >= cb then - CRel (positionOf (n - cb) cfv + cb) - else - c - | _ => c, - exp = fn (cb, eb) => fn e => - case e of - ERel n => - if n >= eb then - ERel (positionOf (n - eb) efv + eb - nr) +fun squishCon (kfv, cfv) = + U.Con.mapB {kind = fn (kb, _) => fn k => + case k of + KRel n => + if n >= kb then + KRel (positionOf (n - kb) kfv + kb) else - e - | _ => e, - bind = fn (ctx as (cb, eb), b) => + k + | _ => k, + con = fn (_, cb) => fn c => + case c of + CRel n => + if n >= cb then + CRel (positionOf (n - cb) cfv + cb) + else + c + | _ => c, + bind = fn (ctx as (kb, cb), b) => + case b of + U.Con.RelK _ => (kb + 1, cb) + | U.Con.RelC _ => (kb, cb + 1) + | _ => ctx} + (0, 0) + +fun squishExp (nr, kfv, cfv, efv) = + U.Exp.mapB {kind = fn (kb, _, _) => fn k => + case k of + KRel n => + if n >= kb then + KRel (positionOf (n - kb) kfv + kb) + else + k + | _ => k, + con = fn (_, cb, _) => fn c => + case c of + CRel n => + if n >= cb then + CRel (positionOf (n - cb) cfv + cb) + else + c + | _ => c, + exp = fn (_, _, eb) => fn e => + case e of + ERel n => + if n >= eb then + ERel (positionOf (n - eb) efv + eb - nr) + else + e + | _ => e, + bind = fn (ctx as (kb, cb, eb), b) => case b of - U.Exp.RelC _ => (cb + 1, eb) - | U.Exp.RelE _ => (cb, eb + 1) + U.Exp.RelK _ => (kb + 1, cb, eb) + | U.Exp.RelC _ => (kb, cb + 1, eb) + | U.Exp.RelE _ => (kb, cb, eb + 1) | _ => ctx} - (0, nr) + (0, 0, nr) type state = { maxName : int, @@ -173,7 +216,7 @@ fun kind (_, k, st) = (k, st) val basis = ref 0 -fun exp ((ks, ts), e as old, st : state) = +fun exp ((ns, ks, ts), e as old, st : state) = case e of ELet (eds, e, t) => let @@ -249,21 +292,23 @@ fun exp ((ks, ts), e as old, st : state) = val vis = map (fn (x, t, e) => (x, t, doSubst' (e, subsLocal))) vis - val (cfv, efv) = foldl (fn ((_, t, e), (cfv, efv)) => - let - val (cfv', efv') = fvsExp nr e - (*val () = Print.prefaces "fvsExp" - [("e", ElabPrint.p_exp E.empty e), - ("cfv", Print.PD.string - (Int.toString (IS.numItems cfv'))), - ("efv", Print.PD.string - (Int.toString (IS.numItems efv')))]*) - val cfv'' = fvsCon t - in - (IS.union (cfv, IS.union (cfv', cfv'')), - IS.union (efv, efv')) - end) - (IS.empty, IS.empty) vis + val (kfv, cfv, efv) = + foldl (fn ((_, t, e), (kfv, cfv, efv)) => + let + val (kfv', cfv', efv') = fvsExp nr e + (*val () = Print.prefaces "fvsExp" + [("e", ElabPrint.p_exp E.empty e), + ("cfv", Print.PD.string + (Int.toString (IS.numItems cfv'))), + ("efv", Print.PD.string + (Int.toString (IS.numItems efv')))]*) + val (kfv'', cfv'') = fvsCon t + in + (IS.union (kfv, IS.union (kfv', kfv'')), + IS.union (cfv, IS.union (cfv', cfv'')), + IS.union (efv, efv')) + end) + (IS.empty, IS.empty, IS.empty) vis (*val () = Print.prefaces "Letto" [("e", ElabPrint.p_exp E.empty (old, ErrorMsg.dummySpan))]*) (*val () = print ("A: " ^ Int.toString (length ts) ^ ", " ^ Int.toString (length ks) ^ "\n")*) @@ -272,12 +317,30 @@ fun exp ((ks, ts), e as old, st : state) = ("t", ElabPrint.p_con E.empty t)]) ts val () = IS.app (fn n => print ("Free: " ^ Int.toString n ^ "\n")) efv*) + val kfv = IS.foldl (fn (x, kfv) => + let + (*val () = print (Int.toString x ^ "\n")*) + val (_, k) = List.nth (ks, x) + in + IS.union (kfv, fvsKind k) + end) + kfv cfv + + val kfv = IS.foldl (fn (x, kfv) => + let + (*val () = print (Int.toString x ^ "\n")*) + val (_, t) = List.nth (ts, x) + in + IS.union (kfv, #1 (fvsCon t)) + end) + kfv efv + val cfv = IS.foldl (fn (x, cfv) => let (*val () = print (Int.toString x ^ "\n")*) val (_, t) = List.nth (ts, x) in - IS.union (cfv, fvsCon t) + IS.union (cfv, #2 (fvsCon t)) end) cfv efv (*val () = print "B\n"*) @@ -299,6 +362,10 @@ fun exp ((ks, ts), e as old, st : state) = val e = (ENamed n, loc) val e = IS.foldr (fn (x, e) => + (EKApp (e, (KRel x, loc)), loc)) + e kfv + + val e = IS.foldr (fn (x, e) => (ECApp (e, (CRel x, loc)), loc)) e cfv @@ -311,6 +378,7 @@ fun exp ((ks, ts), e as old, st : state) = end) vis + val kfv = IS.listItems kfv val cfv = IS.listItems cfv val efv = IS.listItems efv @@ -324,17 +392,17 @@ fun exp ((ks, ts), e as old, st : state) = (*val () = Print.prefaces "squishCon" [("t", ElabPrint.p_con E.empty t)]*) - val t = squishCon cfv t + val t = squishCon (kfv, cfv) t (*val () = Print.prefaces "squishExp" [("e", ElabPrint.p_exp E.empty e)]*) - val e = squishExp (nr, cfv, efv) e + val e = squishExp (nr, kfv, cfv, efv) e (*val () = print ("Avail: " ^ Int.toString (length ts) ^ "\n")*) val (e, t) = foldl (fn (ex, (e, t)) => let (*val () = print (Int.toString ex ^ "\n")*) val (name, t') = List.nth (ts, ex) - val t' = squishCon cfv t' + val t' = squishCon (kfv, cfv) t' in ((EAbs (name, t', @@ -360,6 +428,17 @@ fun exp ((ks, ts), e as old, st : state) = t), loc)) end) (e, t) cfv + + val (e, t) = foldl (fn (kx, (e, t)) => + let + val name = List.nth (ns, kx) + in + ((EKAbs (name, + e), loc), + (TKFun (name, + t), loc)) + end) + (e, t) kfv in (*Print.prefaces "Have a vi" [("x", Print.PD.string x), @@ -391,11 +470,12 @@ fun exp ((ks, ts), e as old, st : state) = fun default (ctx, d, st) = (d, st) -fun bind ((ks, ts), b) = +fun bind ((ns, ks, ts), b) = case b of - U.Decl.RelC p => (p :: ks, map (fn (name, t) => (name, E.liftConInCon 0 t)) ts) - | U.Decl.RelE p => (ks, p :: ts) - | _ => (ks, ts) + U.Decl.RelK x => (x :: ns, ks, ts) + | U.Decl.RelC p => (ns, p :: ks, map (fn (name, t) => (name, E.liftConInCon 0 t)) ts) + | U.Decl.RelE p => (ns, ks, p :: ts) + | _ => (ns, ks, ts) val unnestDecl = U.Decl.foldMapB {kind = kind, con = default, @@ -405,7 +485,7 @@ val unnestDecl = U.Decl.foldMapB {kind = kind, str = default, decl = default, bind = bind} - ([], []) + ([], [], []) fun unnest file = let |