Straight-line program interpreter

dvanhorn <[email protected]>
Newsgroups gmane.org.ballistichelmet.lambda
Message-ID <[email protected]>
(*
   Straight-line program interpreter
   Ch.1 Programming excercise in Modern Compiler Implementation in ML
*)

exception Not_Found ;;

type id = string ;;
type binop = Plus | Minus | Times | Div ;;
type stm =
    CompoundStm of stm * stm
  | AssignStm of id * exp
  | PrintStm of exp list
and exp =
    IdExp of id
  | NumExp of int
  | OpExp of exp * binop * exp
  | EseqExp of stm * exp
;;

type table = Table of (id * int) list ;;

let update t i v =
  match t with
    Table(x) -> Table((i,v)::x) ;;

let rec lookup t i =
  match t with
    Table((id, v)::rest) ->
      if id = i then v
      else lookup (Table rest) i
  | Table([]) ->
      raise Not_Found
;;

let rec interpStm stm table =
  match stm with
    CompoundStm(x, y) ->
      let table = interpStm x table
      in interpStm y table
  | AssignStm(id, e) ->
      let (i, table) = interpExp e table in
        update table id i
  | PrintStm(exps) ->
      let rec loop exps =
        match exps with
        | [] -> print_newline(); table
        | exp::rest ->
            let (i, table) = interpExp exp table in
            print_int i;
            print_char ' ';
            interpStm (PrintStm rest) table
      in loop exps

and interpExp exp table =
  match exp with
    IdExp(id) -> ((lookup table id), table)
  | NumExp(i) -> (i, table)
  | OpExp(a, op, b) ->
      let (i, table) = interpExp a table in
      let (j, table) = interpExp b table in
      ((match op with
        Plus  -> i+j
      | Minus -> i-j
      | Times -> i*j
      | Div   -> i/j),
       table)
  | EseqExp(stm, exp) ->
      let table = interpStm stm table in
      interpExp exp table
;;

let interp stm = interpStm stm (Table []); () ;;

(* AST for a:=5+3; b:=(print(a,a-1), 10*a); print(b) *)
let prog =
  CompoundStm
    (AssignStm("a",OpExp(NumExp 5, Plus, NumExp 3)),
     CompoundStm
       (AssignStm
          ("b",
           EseqExp
             (PrintStm[IdExp "a"; OpExp(IdExp "a", Minus, NumExp 1)],
              OpExp(NumExp 10, Times, IdExp "a"))),
        PrintStm[IdExp "b"]))
    ;;

interp prog ;;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.