(*
* SNU 4190.310 Programming Languages (Fall 2006)
*
* K- Interpreter I
*)

(* Memory *)
signature MEM =
sig
   (* The type of address *)
   type address

   (* The type of memory from type address to type 'a *)
   type 'a t

   exception Not_allocated
   exception Not_initialized

   (* The empty memory *)
   val empty : 'a t

   (*
    * allocate m returns an address to a fresh (uninitialized) buffer and a
    * memory containing the same bindings as m, plus a binding of the address
    * to the allocated buffer.
    *)
   val allocate : 'a t -> address * 'a t

   (*
    * store addr v m returns a memory containing the same bindings as m, with
    * addr bounded to v, or raises Not_allocated if m doesn't contain a
    * binding for addr.
    *)
   val store : address -> 'a -> 'a t -> 'a t

   (*
    * fetch addr m returns the current binding of addr in m, raises
    * Not_initialized if the binding is not initialized yet or raises
    * Not_found if no such binding exists.
    *)
   val fetch : address -> 'a t -> 'a

   (*
    * is_allocated addr m returns true if m contains a binding for addr, and
    * false otherwise.
    *)
   val is_allocated : address -> 'a t -> bool
end

structure Mem : MEM =
struct
   type address = int
   type 'a t = address * ((address, 'a option) Map.t)

   exception Not_allocated
   exception Not_initialized

   val empty = (0, Map.empty)
   fun allocate (n, m) = (n, (n + 1, Map.add n None m))
   fun store a v (n, m)  =
       if Map.mem a m then (n, Map.add a (Some v) m) else raise Not_allocated
   fun fetch a (_, m) = (
         case (Map.find a m) of Some v => v | None => raise Not_initialized
       ) handle Not_found => raise Not_allocated
   fun is_allocated a (_, m) = Map.mem a m
end

(* Environment *)
signature ENV =
sig
   (* The type of environment from 'a to 'b *)
   type ('a, 'b) t

   exception Not_bound

   (* The empty environment *)
   val empty : ('a, 'b) t

   (*
    * bind x addr e returns an environment containing the same bindings as
    * e, plus a binding of x to addr. If x was already bound in e, its
    * previous binding disappears.
    *)
   val bind : 'a -> 'b -> ('a, 'b) t -> ('a, 'b) t

   (*
    * lookup x e returns the current binding of x in e, or raises Not_bound if
    * no such binding exists.
    *)
   val lookup : 'a -> ('a, 'b) t -> 'b

   (*
    * is_bound x e returns true if e contains a binding for x, and false
    * otherwise.
    *)
   val is_bound : 'a -> ('a, 'b) t -> bool
end

structure Env : ENV =
struct
   type ('a, 'b) t = ('a, 'b) Map.t

   exception Not_bound

   val empty = Map.empty
   fun bind x a e = Map.add x a e
   fun lookup x e = (Map.find x e) handle Not_found => raise Not_bound
   fun is_bound x e = Map.mem x e
end

(* K- Interpreter *)
signature KEVAL =
sig
   exception Error of string
   type id = string
   type exp =
       NUM of int
     | TRUE
     | FALSE
     | UNIT
     | VAR of id
     | ADD of exp * exp
     | SUB of exp * exp
     | MUL of exp * exp
     | DIV of exp * exp
     | EQUAL of exp * exp
     | LESS of exp * exp
     | NOT of exp
     | ASSIGN of id * exp
     | SEQ of exp * exp
     | IF2 of exp * exp * exp
     | IF1 of exp * exp
     | WHILE of exp * exp
     | FOR of id * exp * exp * exp
     | LET of id * exp * exp
     | READ of id
     | WRITE of exp
   type program = exp
   type memory
   type env
   type value
       val v2s : value -> string
   val emptyMem : memory
   val emptyEnv : env
   val run : memory * env * program -> value
end

structure Keval : KEVAL =
struct
   exception Error of string
   type id = string
   type exp =
       NUM of int
     | TRUE
     | FALSE
     | UNIT
     | VAR of id
     | ADD of exp * exp
     | SUB of exp * exp
     | MUL of exp * exp
     | DIV of exp * exp
     | EQUAL of exp * exp
     | LESS of exp * exp
     | NOT of exp
     | ASSIGN of id * exp
     | SEQ of exp * exp
     | IF2 of exp * exp * exp
     | IF1 of exp * exp
     | WHILE of exp * exp
     | FOR of id * exp * exp * exp
     | LET of id * exp * exp
     | READ of id
     | WRITE of exp
   type program = exp
   type value = int
   type memory = value Mem.t
   type env = (id, value) Env.t
   val emptyMem = Mem.empty
   val emptyEnv = Env.empty
       val v2s = fn x => (string_of_int x)^"\n"
   val run =
         fn (memory, env, program) =>
(*                  (case program of
                       NUM (i) => i
             | TRUE => 1
             | FALSE => 0
             | UNIT => 0
             | VAR (id) => val _ = print_string(id);
             | ADD (exp1, exp2) => fn(memory, env, exp1)
             | SUB (exp1, exp2) => fn(memory, env, exp1)
             | MUL (exp1, exp2) => fn(memory, env, exp1)
             | DIV (exp1, exp2) => fn(memory, env, exp1)
             | EQUAL (exp1, exp2) => fn(memory, env, exp1)
             | LESS (exp1, exp2) => fn(memory, env, exp1)
             | NOT (exp) => fn(memory, env, exp)
             | ASSIGN (id, exp) => memory.allocate id
             | SEQ (exp1, exp2) => fn(memory, env, exp1)
             | IF2 (exp1, exp2, exp3) => fn(memory, env, exp1)
             | IF (exp1, exp2) => fn(memory, env, exp1)
             | WHILE (exp1, exp2) => fn(memory, env, exp1)
             | FOR (id, exp1, exp2, exp3) => fn(memory, env, exp1)
             | LET (id, exp1, exp2) => fn(memory, env, exp1)
             | READ (id) =>
                 | WRITE (exp) => fn(memory, env, exp1)
       )*)
end
Posted by 백구씨쥔장
,