(* env.sml * * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu) * * COPYRIGHT (c) 2015 The University of Chicago * All rights reserved. *) structure Env : sig type env val new : unit -> env (* functions are either user-defined or pre-defined *) datatype fun_def = PrimFun of AST.var list (* possibly overloaded builtin function *) | UserFun of AST.var (* user-defined function *) val findStrand : env * Atom.atom -> AST.strand option val findFunc : env * Atom.atom -> fun_def val findVar : env * Atom.atom -> AST.var option val insertStrand : env * AST.strand -> env (* insert a function binding *) val insertFunc : env * Atom.atom * fun_def -> env (* insert variable bindings *) val insertGlobal : env * Atom.atom * AST.var -> env val insertLocal : env * Atom.atom * AST.var -> env (* tracking program features *) val recordProp : env * StrandUtil.program_prop -> unit val properties : env -> StrandUtil.program_prop list end = struct structure ATbl = AtomTable structure AMap = AtomMap (* functions are either user-defined or pre-defined *) datatype fun_def = PrimFun of AST.var list (* possibly overloaded builtin function *) | UserFun of AST.var (* user-defined function *) (* global environment holds global variables and strands *) datatype global_env = GE of { sEnv : AST.strand ATbl.hash_table, (* strands *) fEnv : fun_def ATbl.hash_table, (* functions, which may be overloaded *) vEnv : AST.var ATbl.hash_table, (* global variable bindings *) props : StrandUtil.program_prop list ref (* record program properties *) } datatype env = E of { g : global_env, vEnv : AST.var AMap.map } fun new () = E{ g = GE{ sEnv = ATbl.mkTable(8, Fail "strand env"), fEnv = ATbl.mkTable(128, Fail "global function env"), vEnv = ATbl.mkTable(128, Fail "global variable env"), props = ref[] }, vEnv = AMap.empty } fun findStrand (E{g=GE{sEnv, ...}, ...}, s) = ATbl.find sEnv s fun findFunc (E{g=GE{fEnv, ...}, ...}, x) = (case ATbl.find fEnv x of NONE => PrimFun[] | SOME fdef => fdef (* end case *)) fun findVar (E{g=GE{vEnv=gvEnv, ...}, vEnv}, x) = (case AMap.find(vEnv, x) of NONE => ATbl.find gvEnv x | someVar => someVar (* end case *)) fun insertStrand (env as E{g=GE{sEnv, ...}, ...}, s as AST.Strand{name, ...}) = ( ATbl.insert sEnv (name, s); env) fun insertFunc (env as E{g=GE{fEnv, ...}, ...}, f, f') = ( ATbl.insert fEnv (f, f'); env) fun insertGlobal (env as E{g=GE{vEnv, ...}, ...}, x, x') = ( ATbl.insert vEnv (x, x'); env) fun insertLocal (env as E{vEnv, g}, x, x') = E{vEnv = AMap.insert(vEnv, x, x'), g = g} (* tracking program features *) fun recordProp (E{g=GE{props, ...}, ...}, p) = if (StrandUtil.hasProp p (!props)) then () else props := p :: !props fun properties (E{g=GE{props, ...}, ...}) = !props end
Click to toggle
does not end with </html> tag
does not end with </body> tag
The output has ended thus: ) else props := p :: !props fun properties (E{g=GE{props, ...}, ...}) = !props end