fun curry f x y = f(x,y); val $ = curry; (* -------------------------------------------- *) (* denotational semantics definitions: in SML *) (* = d.ml *) (* -------------------------------------------- *) (* -------------------------------------------- *) (* Skeleton for Lab # 2; *) (* fill in all missing sections. *) (* -------------------------------------------- *) (* -------------------------------------------- *) (* Template for Continuations *) (* -------------------------------------------- *) (* -------------------------------------------- *) (* ---------- Abstract Syntax ----------------- *) (* terminal nodes of the syntax *) type Numeral = int; type Ident = string; (* parsed phrases of the abstract syntax *) datatype Command = skip | assign of Ident * Expression | letin of Declaration * Command | cmdcmd of Command * Command | ifthen of Expression * Command * Command | whiledo of Expression * Command and Expression = num of Numeral | False | True | id of Ident | sumof of Expression * Expression | subof of Expression * Expression | prodof of Expression * Expression | less of Expression * Expression | notexp of Expression and Declaration = constdef of Ident * Expression | vardef of Ident * TypeDef and TypeDef = Bool | Int ; (* -------------------------------------------- *) (* ---------- Semantic Domains ---------------- *) type Integer = int; type Boolean = bool; type Location= int; datatype Value = integer of int | truth_value of bool; type Storable = Value; datatype Bindable = value of Value | variable of Location; datatype Denotable = unbound | bound of Bindable ; exception fail; (* -------------------------------------------- *) (* ---------- Semantic Functions -------------- *) (* These declarations are automatically inferred * from the defining equations below... type Environ = Ident -> Denotable; type Store = Location -> (Storable + undef + unused); *) (* -------------------------------------------- *) (* ---------- Auxiliary Semantic Functions ---- *) fun sum (x, y) = x + y:int; fun diff (x, y) = x - y:int; fun prod (x, y) = x * y:int; fun lessthan (x, y) = x < (y:int); (* ---------- Storage ---------- *) datatype Sval = stored of Storable | undef | unused; (* --bot--- --top--- ----data--------- *) datatype Store = store of Location * Location * (Location -> Sval); val sto_init = fn loc:Location => unused; val sto_null = store( 1, 0, sto_init); fun update (store(bot,top,data), loc, v) = let fun new adr = if adr=loc then stored v else (data adr); in store( bot, top, new) end; (* fetch from store, and convert into Storable (=Value) *) fun fetch (store(bot,top,data), loc:Location) = let fun stored_value(stored stble) = stble | stored_value(unused) = raise fail | stored_value(undef) = raise fail in stored_value( data loc) end; (* create a new "undefined" location in a store *) fun allocate ( store(bot,top,data) ) = let val newtop = top+1 fun new adr = if adr=newtop then undef else (data adr); in (store( bot, newtop, new), newtop) end; (* ---------- Envirionment ---------- *) type Environ = Ident -> Denotable; val env_null = fn i:Ident => unbound; fun bind (name, vl) = fn idn => if idn=(name:Ident) then bound(vl) else unbound; fun find (env:Environ, idn) = let fun getbv(bound bdbl) = bdbl | getbv(unbound) = raise fail in getbv( env idn) end; fun overlay (env', env:Environ) = fn idn => let val val' = env' idn in if val'<>unbound then val' else env idn end; (* ---------- Continuations --------- *) (* Answers *) type Ans = Storable list; (* Command continuations *) type Cc = Store -> Ans; (* Expression continuations *) type Ec = Storable -> Cc; (* Declaration continuations *) type Dc = Environ -> Cc; (* Dumps only position 1, change to dump all used store *) fun final_continuation (s:Store) : Ans = map ($ fetch s) [1]; (* ---------- Etc.... ---------- *) (* coerce a Bindable into a Value.. *) fun coerc (sto, value v) = v | coerc (sto, variable loc) = fetch(sto,loc); (* ---------- Initialize system ---------- *) (* -------------------------------------------- *) (* ---------- Semantic Equations -------------- *) (* from integer to Value *) fun valuation ( n ) = integer(n) and execute ( assign(name,exp) ) (u: Environ) (c:Cc) : Cc = let val variable loc = find(u,name) (*variable 1*) fun new_ec (ev: Storable) (s:Store) : Ans = let val new_store = update( s, loc, ev) in c new_store end in Reval exp u new_ec end | execute ( letin(def,com) ) (u: Environ) (c:Cc) : Cc = let fun new_dc (u1: Environ) : Cc = execute com (overlay (u1, u)) c in elaborate def u new_dc end | execute ( cmdcmd(com1,com2) ) (u: Environ) (c:Cc) : Cc = execute com1 u (execute com2 u c) | execute ( ifthen(e,c1,c2) ) env sto = ... | execute ( whiledo(e,c) ) en st = ... and (* simple, just build a Value *) evaluate ( num(n) ) (u:Environ) (k:Ec) :Cc = k( integer n ) | evaluate ( True ) env sto = ... | evaluate ( False ) env sto = ... | evaluate ( id(n) ) env sto = ... (* get values, and compute result *) | evaluate ( sumof (e1,e2) ) (u:Environ) (k:Ec) :Cc = let fun exp1_ec ((integer i1): Storable) : Cc = let fun exp2_ec ((integer i2): Storable) : Cc = k( integer(i1 + i2) ) in Reval e2 u exp2_ec end in Reval e1 u exp1_ec end | evaluate ( subof (e1,e2) ) env sto = ... | evaluate ( prodof(e1,e2) ) env sto = ... | evaluate ( less(e1,e2) ) env sto = ... and elaborate ( constdef(name,e) ) env sto = ... | elaborate ( vardef(name,tdef) ) (u: Environ) (c:Dc) : Cc = let fun new_cc (s:Store) : Ans = let val (new_store, loc) = allocate s val new_env = bind(name, variable loc) in c new_env new_store end in new_cc end and deref (k: Ec) (ev: Storable) (s: Store) : Ans = k ev s and Reval (exp: Expression) (u: Environ) (k: Ec) : Cc = evaluate exp u (deref k) ; (* ============================================ *) (* ---------- Test it..! ---------------------- *) val pgm1 = letin ( vardef ("y", Int), assign("y", num(3)) ); execute pgm1 env_null final_continuation sto_null; val pgm2 = letin ( vardef ("y", Int), cmdcmd ( assign("y", num(3)), assign("y", sumof(num(3),num(1))) ) ); execute pgm2 env_null final_continuation sto_null;