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 ;;