(* * Further experiments with alists. The type defs in this file define a * "non-naive" Lisp alist structure, as discussed in 501 Lecture Notes 4. * * Requires lispval2.ml and stack.ml, q.q.v. *) type dataBinding = string * lispVal; type functionBinding = string * (string list) * lispVal; type stateStore = dataBinding list; type environment = functionBinding list; type stackStore = dataBinding list stack; (* * Given the above type defs, we now define the non-naive alist to be a record * of a stateStore, environment, and stackStore. *) type alist = {store:stateStore, env:environment, stack:stackStore}; (* * Putting everything together, here is a function that builds the following * sample alist: * * ( ((x 100) (y 200) (z 30000)) ;The global state store * * ((f (x y) (g x y)) ;The environment (for defun bindings) * (g (x y) (+ (h x) y)) * (h (x) (+ x 10))) * * (((x 10) (y 20)) ((x 10) (y 20)) ((x 10))) ;The stack * ) *) fun makeSampleAlist() = let val sampleStore = [("x", N(100)), ("y", N(200)), ("z", N(30000))]; val fDefun = ("f", ["x", "y"], L[A("g"), A("x"), A("y")]); val gDefun = ("g", ["x", "y"], L[A("+"), L[A("h"), A("x")], A("y")]); val hDefun = ("h", ["x"], L[A("+"), A("x"), N(10)]); val sampleEnv = [fDefun, gDefun, hDefun]; val fActRec = [("x", N(10)), ("y", N(20))]; val gActRec = [("x", N(10)), ("y", N(20))]; val hActRec = [("x", N(10))]; val sampleStack = push(push(push(newStack, fActRec), gActRec), hActRec); in {store=sampleStore, env=sampleEnv, stack=sampleStack}:alist end; (* * Finally, we construct a sample alist and access one of its components. *) val sampleAlist = makeSampleAlist(); val valueOfBindingOfYInGsActRec = getN(#2(hd(tl(top(pop(#stack(sampleAlist)))))));