Guest User

Untitled

a guest
Jul 2nd, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 8.37 KB | None | 0 0
  1. open List
  2. open Minijavaast
  3. open Mp6common
  4.  
  5. (* MP6 interpreter - no objects, arrays, or floats; just one class;
  6.    limited set of statements.  See MP5 write-up for details. *)
  7. let rec asgn (id:id) (v:stackvalue) (env:environment) : environment = match env with
  8.   (x,y)::t -> if x = id then (x,v)::t else (x,y)::(asgn id v t)    
  9.   | [] -> raise (TypeError ("broken"))
  10.  
  11.  
  12. let rec binds (id:id) (env:environment) : bool = match env with
  13.   (x,y)::t -> if x = id then true else (binds id t)
  14.   | [] -> false
  15.  
  16.  
  17. let rec fetch (id:id) (env:environment) : stackvalue = match env with
  18.   (x,y)::t -> if x = id then y else (fetch id t)
  19.   | [] -> raise(TypeError("Not in state"))
  20.  
  21.  
  22. let rec mklist (i:int) (v:stackvalue) : stackvalue list = match i with
  23.   0 -> []
  24.   | _ -> v::(mklist (i - 1) v)
  25.  
  26. let rec zip (lis1:id list) (lis2:stackvalue list) : environment = match lis1,lis2 with
  27.   [],[] -> []
  28.   | x::xt,y::yt -> if List.length lis1 <> List.length lis2 then raise(TypeError("Suck")) else (x,y)::(zip xt yt)  
  29.  
  30. let rec zipscalar (lis:id list) (v:stackvalue) : environment = match lis with
  31.   [] -> []
  32.   | a::b -> (a,v)::(zipscalar b v)
  33.  
  34. let rec varnames (varlis:var_decl list) : id list = match varlis with
  35.   [] -> []
  36.   | Var(a,b)::t -> b::(varnames t)
  37.  
  38. let rec getMethodAux (id:id) methlis : method_decl  = match methlis with
  39.   [] -> raise (TypeError("Dicks"))
  40.   | ((Method(_,x,_,_,_,_)) as meth)::t ->  if x = id then meth else getMethodAux id t
  41.  
  42. let getMethodInClass (id:id) (Class(_, _, _, methlis)) : method_decl =
  43.   getMethodAux id methlis
  44.  
  45. let extend (st:store) (hval:heapvalue) : store =
  46.   st @ [hval]
  47.  
  48. let rec storefetch (st:store) (loc:int) : heapvalue = match st, loc with
  49.   x::y, 0 -> x
  50.   | x::y, l -> storefetch y (l-1)
  51.  
  52. let asgn_fld (obj:heapvalue) (id:varname) (sv:stackvalue) : heapvalue = match obj with
  53.     Object(a,b) -> Object(a,(asgn id sv b))
  54.     | _ -> raise (TypeError("FEFWEFEW"))
  55.  
  56.  
  57. let rec asgn_sto (sto:store) (loc:int) (obj:heapvalue) = match sto, loc with
  58.   x::y, 0 -> [obj]@ y
  59.   | x::y, _ -> [x] @ (asgn_sto y (loc-1) obj)
  60.  
  61. let rec getClass (c:id) (Program classlis) : class_decl = match classlis with
  62.  [] -> raise (TypeError("Dicksandhalf"))
  63.  | Class(name,f,u,k)::y -> if c = name then Class(name,f,u,k) else getClass c (Program y)
  64.  
  65. let rec getMethod (id:id) (c:id) (prog:program) : method_decl =
  66.   match (getClass c prog) with
  67.     Class(name, "", f, methlis) -> (
  68.   let rec aux methlis = match methlis with
  69.           [] -> raise (TypeError ("No such method: "^id))
  70.         | (Method(_, m, _, _, _, _) as themethod) :: t ->
  71.         if id=m then themethod else aux t
  72.         in aux methlis
  73.     )
  74.   | Class(name, sup, f, methlis) -> (
  75.     let rec aux methlis = match methlis with
  76.       [] -> getMethod id sup prog
  77.     | (Method(_, m, _, _, _, _) as themethod) :: t ->
  78.         if id=m then themethod else aux t
  79.     in aux methlis
  80.     )
  81.  
  82.  
  83. let rec fieldsaux fieldlis:  string list  = match fieldlis with
  84.   [] -> []
  85.   | (_,Var(b,c))::d ->  c::(fieldsaux d )
  86.  
  87. let rec fields (cls:id) (prog:program) : string list =
  88.   match (getClass cls prog) with
  89.   Class(name,sup,f,m) as x -> fieldsaux f @ (fields sup prog)
  90.   | Class(name, "", f, m) as x -> fieldsaux f
  91.   | _ -> []
  92.  
  93. let applyOp (bop:binary_operation)
  94.             (v1:stackvalue) (v2:stackvalue) : stackvalue = match bop with
  95.    Multiplication -> (match v1, v2 with
  96.         IntV(v1), IntV(v2) -> IntV(v1*v2)
  97.         |_,_ -> raise (TypeError("LOLUCANTMULTTHAT")))
  98.   | Plus ->  (match v1, v2 with
  99.     IntV(v1), IntV(v2) -> IntV(v1+v2)
  100.     | IntV(v1), StringV(v2) -> StringV( string_of_int(v1)^v2)
  101.     | StringV(v1), IntV(v2) -> StringV( v1^(string_of_int(v2)))
  102.     | StringV(v1), StringV(v2) -> StringV(v1^v2)
  103.     | BoolV(v1), StringV(v2) -> StringV(string_of_bool(v1)^v2)
  104.     | StringV(v1), BoolV(v2) -> StringV  (v1^string_of_bool(v2))
  105.     | _,_ -> raise (TypeError("UCANTADDDAT"))
  106.     | _ -> raise (TypeError("UCENWE"))
  107.     )
  108.   | Division -> (match v1, v2 with
  109.     IntV(v1), IntV(v2) -> if v2 = 0 then raise(RuntimeError("DivisionByZero")) else IntV(v1/v2)
  110.     | _ ,_-> raise (TypeError("UNODIVIDE")))
  111.   | Minus -> (match v1, v2 with
  112.     IntV(v1), IntV(v2) -> IntV(v1-v2)
  113.     |_,_-> raise( TypeError("Minus, THAT?ucwasy")))
  114.   | LessThan ->(match v1, v2 with
  115.     IntV(v1), IntV(v2) -> BoolV(v1<v2)
  116.     |_,_ -> raise (TypeError("UlessthanME")))
  117.   | Equals ->(match v1, v2 with
  118.     IntV(v1), IntV(v2) -> BoolV(v1=v2)
  119.     | StringV(v1), StringV(v2) -> BoolV(v1=v2)
  120.     | BoolV(v1), BoolV(v2) -> BoolV(v1=v2)
  121.     | NullV, NullV -> BoolV(true)
  122.     | NullV, _ -> BoolV(false)
  123.     | _, NullV -> BoolV(false)
  124.     | _,_ -> raise(TypeError("noequal")))
  125.   | _ -> raise (TypeError("NOBOPS"))
  126.  
  127. let rec eval (e:exp) ((env,sto) as sigma:state) (prog:program)
  128.        : stackvalue * store = match e with
  129.     Null -> ((NullV),sto)
  130.   | True -> BoolV(true),sto
  131.   | False -> BoolV(false),sto
  132.   | Integer i -> IntV(i),sto
  133.   | String i -> StringV(i),sto
  134.   | This -> (fetch "this" env), sto
  135.   | Not b -> (match (eval b sigma prog) with
  136.     BoolV f, sto2 -> (BoolV(not f), sto2)
  137.     | _ -> raise (TypeError("ffff")))
  138.   | Operation(v1,And,v2) -> (match (eval v1 sigma prog) with
  139.     BoolV b, sto2 -> if b = true then (eval v2 sigma prog)
  140.     else BoolV(false),sto2
  141.     |_ -> raise(TypeError("AND")))
  142.  
  143.   | Operation(v1,Or, v2) -> (match (eval v1 sigma prog) with
  144.     BoolV b, sto2 -> if b = true then BoolV(true),sto2 else (eval v2 sigma prog)
  145.     |_-> raise(TypeError("OR")))
  146.   | Operation(v1, bop, v2) -> (match (eval v1 sigma prog), (eval v2 sigma prog) with
  147.             (x,y),(a,b) -> (applyOp bop x a),sto)
  148.   | Id i -> if binds i env then (fetch i env),sto
  149.             else if (match (evalobject env sto)
  150.                 with Object(x,y)->(binds i y)) then (match (evalobject env sto)
  151.                             with Object(x,y) -> (fetch i y),sto) (*double check for errors*)
  152.             else raise (TypeError("FKR"))
  153.   | NewId (c) -> Location(List.length(sto)),extend sto (Object(c,(zipscalar (fields c prog) NullV)))
  154.   | MethodCall(e1, x, el) -> (match (eval e1 sigma prog) with
  155.     (Location l1,l2) -> ( match (storefetch l2 l1) with
  156.             Object(cname, env1) ->(match (getMethod x cname prog), (evallist el sigma prog) with
  157.                 Method(a,b,c,d,e,f), (poo,pee) -> evalMethodCall e f (([("this",Location l1)]@(zip (varnames c) poo) @ (zipscalar (varnames d) (Location l1))),l2) prog
  158.                 | _ -> raise (TypeError("ERE"))
  159.  
  160.                           )
  161.             | _ -> raise (TypeError("rere"))
  162.                 )
  163.             |_ -> raise (TypeError("REEEREE")))
  164.        
  165.   | _ -> raise(TypeError("derere"))
  166.  
  167. and evallist (el:exp list) ((env,sto) as sigma:state) (prog:program)
  168.           : stackvalue list * store = match el with
  169.    
  170.  
  171.     a::b -> ( match(evallist b sigma prog) with
  172.             ([],_) -> (match (eval a sigma prog) with
  173.                     (x,y) -> ([x],sto) )
  174.             | (x::y,_) -> (match (eval a sigma prog) with
  175.                     (f,g)-> ((f::(x::y)),g)))
  176.     | []  -> [], sto
  177.     (*a::b -> let (x,y) = (eval a sigma prog) in ([x]@(evallist b sigma prog))
  178.        
  179.     | [] -> ([], sto)*)
  180.  
  181. and evalMethodCall (stms:statement list) (retval:exp) (sigma:state) (prog:program) : stackvalue * store =  match (execstmtlis stms sigma prog) with
  182.     a -> eval retval a prog
  183.     | _ -> raise(TypeError("ERERERE"))
  184.  
  185. and execstmt (s:statement) ((env,sto) as sigma:state) (prog:program) : state =
  186.     match s with
  187.     Assignment(id, e) ->
  188.              if (binds id env) then (match (eval e sigma prog) with
  189.                             (x,y) -> (asgn id x env),y)
  190.              else if (match (evalobject env sto) with
  191.                 Object(x,y)-> (binds id y))
  192.                         then (match (eval e sigma prog), (fetch "this" env) with
  193.                          (x,y), Location(h) ->  env,(asgn_sto y h (asgn_fld (storefetch y h) id x))
  194.                             )
  195.              else raise (TypeError("why"))
  196.   | Block s1 -> execstmtlis s1 sigma prog
  197.   | If(e, s1, s2) -> (match (eval e sigma prog) with
  198.         BoolV b,sto -> if b = true then execstmt s1 sigma prog
  199.                 else execstmt s2 sigma prog
  200.         |_ -> raise (TypeError("Invalid if")))
  201.   | _ -> raise (TypeError("Invalid if"))
  202.  
  203. and evalobject env sto = match (fetch "this" env) with
  204. Location(h) -> storefetch sto h
  205.  
  206. and execstmtlis (sl:statement list) (sigma:state) (prog:program) : state = match sl with
  207.   [] -> sigma
  208.   | a::b -> execstmtlis b (execstmt a sigma prog) prog
  209.  
  210.  
  211. let run_with_args (Program(Class(cname,_,_,_) :: _) as prog)
  212.                   (args:exp list) : string =
  213.    let env = [("this", Location 0)]
  214.    and sto = [Object(cname, [])]
  215.    in let (v,_) = eval (MethodCall(Id "this", "main", args))
  216.                        (env,sto) prog
  217.       in string_of_stackval v
  218.  
  219. let run (prog:program) : string = run_with_args prog []
Add Comment
Please, Sign In to add comment