datatype 'a Search = Found of 'a | NotFound ; datatype Result = Ok | Error of string; datatype Statement = Inspect of string | Update of string | Call of string; datatype Method = Static | Dynamic; type VarDecl = string*int; type FunDecl = {name:string, vars:VarDecl list, body:Statement list}; type MainDecl = {vars:VarDecl list, funs:FunDecl list, body:Statement list}; fun doesVarExist(varname:string,nil)= false | doesVarExist(varname,x::xs)=if #1(x:VarDecl)=varname then true else doesVarExist(varname,xs); fun doesFexist(fname:string,nil)= false | doesFexist(fname,x::xs)=if #name(x:FunDecl)=fname then true else doesFexist(fname,xs); fun mygetval(varname:string,x::xs)=if #1(x:VarDecl)=varname then #2(x) else mygetval(varname,xs); fun getfun(fname:string,x::xs)=if #name(x:FunDecl)=fname then x else getfun(fname,xs); fun tracestat (myprog:MainDecl, mymethod:Method, (Update k):Statement, myglobals:VarDecl list, myenv)= if doesVarExist(k,myenv@myglobals) then ( print("Update "^k^":"^Int.toString(mygetval(k,myenv@myglobals))^"\n"); Ok ) else Error("Variable " ^ k ^ " could not be found") | tracestat (myprog, mymethod, (Inspect k), myglobals, myenv)= if doesVarExist(k,myenv@myglobals) then ( print("Inspect "^k^":"^Int.toString(mygetval(k,myenv@myglobals))^"\n"); Ok ) else Error("Variable "^k^" could not be found") | tracestat (myprog, mymethod, (Call k), myglobals, myenv)= if doesFexist(k, #funs(myprog)) then ( print("Call "^k^"\n"); let val myfun=getfun(k,#funs(myprog)) val funval = if mymethod=Static then tracebody (myprog, mymethod, #body(myfun), myglobals, #vars(myfun)) else tracebody (myprog, mymethod, #body(myfun), myglobals, (#vars(myfun))@myenv) in if funval=Ok then ( print("Return "^k^"\n"); Ok ) else funval end ) else Error("Function "^k^" is not defined") and tracebody( myprog, mymethod, mystats, myglobals, myenv)= if mystats=nil then Ok else let val myresult=tracestat( myprog, mymethod, (hd mystats), myglobals, myenv) in if myresult=Ok then tracebody (myprog, mymethod, (tl mystats), myglobals, myenv) else myresult end; fun trace myprog mymethod= tracebody( myprog:MainDecl, mymethod:Method, #body(myprog), #vars(myprog), []);