Last active
March 21, 2024 16:32
-
-
Save SHoltzen/ac1ae6ba18092cedd1d597e45a10c234 to your computer and use it in GitHub Desktop.
Starter code for assignment 8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (**********************************************************************************) | |
| (* micro-asm *) | |
| exception Trap | |
| (** a memory unsafe language *) | |
| type asm = | |
| (* load heap[addr] into reg *) | |
| | Load of { reg: int; addr: int } | |
| (* load heap[register[loc_reg]] into reg *) | |
| | Dynamicload of {reg: int; loc_reg: int} | |
| (* store register[reg] into heap[addr] *) | |
| | Store of { reg : int; addr: int } | |
| (* set register[reg] = value *) | |
| | Setreg of { reg: int; value: int } | |
| (* trap: gives a runtime error if register[0] != v *) | |
| | Trap of int | |
| (* set register[0] = register[1] + register[2] *) | |
| | AddInt | |
| | MulInt | |
| (* terminate *) | |
| | Ret | |
| type state = { reg: int array; | |
| heap: int array;} | |
| let rec interp_insn (state:state) (asm: asm list) : unit = | |
| match asm with | |
| | Load { reg=r; addr=addr}::rst -> | |
| Array.set state.reg r (Array.get state.heap addr); | |
| interp_insn state rst | |
| | Dynamicload {reg; loc_reg} :: rst -> | |
| let addr = Array.get state.reg loc_reg in | |
| Array.set state.reg reg (Array.get state.heap addr); | |
| interp_insn state rst | |
| | Store { reg=r; addr=addr } :: rst -> | |
| let v = Array.get state.reg r in | |
| Array.set state.heap addr v; | |
| interp_insn state rst | |
| | Setreg { reg=r; value=v } :: rst -> | |
| Array.set state.reg r v; | |
| interp_insn state rst | |
| | Trap(i) :: rst -> | |
| if (Array.get state.reg 0) = i then () else raise Trap; | |
| interp_insn state rst | |
| | AddInt :: rst -> | |
| let v = (Array.get state.reg 1) + (Array.get state.reg 2) in | |
| Array.set state.reg 0 v; | |
| interp_insn state rst | |
| | MulInt :: rst -> | |
| let v = (Array.get state.reg 1) * (Array.get state.reg 2) in | |
| Array.set state.reg 0 v; | |
| interp_insn state rst | |
| | Ret :: rst -> () | |
| | _ -> raise Trap | |
| (** run all instructions in l and return the result in register 0 *) | |
| let interp_asm (l: asm list) : int = | |
| let state = {reg = (Array.make 4 (-1)); | |
| heap=(Array.make 100 (-1)); | |
| } in | |
| interp_insn state l; | |
| Array.get state.reg 0 | |
| (**********************************************************************************) | |
| (* compiling to asm *) | |
| let fresh (iref: int ref) : int = | |
| let cur = !iref in | |
| iref := cur + 1; | |
| cur | |
| type exp = | |
| | Let of { id: string; binding: exp; body: exp } | |
| | Var of string | |
| | Fst of exp | |
| | Snd of exp | |
| | Pair of exp * exp | |
| | Num of int | |
| module StringMap = Map.Make(String) | |
| exception Compile_error | |
| exception Not_impl | |
| let rec safe_ast_to_asm (env:int StringMap.t) (counter: int ref) (c: exp) : (int * asm list) = | |
| match c with | |
| | Let {id; binding; body} -> | |
| raise Not_impl | |
| | Var(s) -> | |
| raise Not_impl | |
| | Pair(e1, e2) -> | |
| raise Not_impl | |
| | Fst(e) -> | |
| raise Not_impl | |
| | Snd(e) -> | |
| raise Not_impl | |
| | Num(n) -> | |
| raise Not_impl | |
| let to_asm_prog (c:exp) : asm list = | |
| raise Not_impl | |
| let run_safe (c:exp) : int = | |
| let asm = to_asm_prog c in | |
| interp_asm asm | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment