82 lines
1.5 KiB
OCaml
82 lines
1.5 KiB
OCaml
open Base
|
|
|
|
let _unary = [ "@SP"; "A=M-1" ]
|
|
let _binary = [ "@SP"; "AM=M-1"; "D=M"; "A=A-1" ]
|
|
let _add = _binary @ [ "M=M+D" ]
|
|
let _sub = _binary @ [ "M=M-D" ]
|
|
let _neg = _unary @ [ "M=-M" ]
|
|
let _and = _binary @ [ "M=D&M" ]
|
|
let _or = _binary @ [ "M=D|M" ]
|
|
let _not = _unary @ [ "M=!M" ]
|
|
|
|
let _eq loc =
|
|
_binary
|
|
@ [ "D=M-D"
|
|
; "M=-1"
|
|
; "@END_EQ_" ^ loc
|
|
; "D;JEQ"
|
|
; "@SP"
|
|
; "A=M-1"
|
|
; "M=0"
|
|
; "(END_EQ_" ^ loc ^ ")"
|
|
]
|
|
;;
|
|
|
|
let _gt loc =
|
|
_binary
|
|
@ [ "D=M-D"
|
|
; "M=-1"
|
|
; "@END_GT_" ^ loc
|
|
; "D;JGT"
|
|
; "@SP"
|
|
; "A=M-1"
|
|
; "M=0"
|
|
; "(END_GT_" ^ loc ^ ")"
|
|
]
|
|
;;
|
|
|
|
let _lt loc =
|
|
_binary
|
|
@ [ "D=M-D"
|
|
; "M=-1"
|
|
; "@END_LT_" ^ loc
|
|
; "D;JLT"
|
|
; "@SP"
|
|
; "A=M-1"
|
|
; "M=0"
|
|
; "(END_LT_" ^ loc ^ ")"
|
|
]
|
|
;;
|
|
|
|
let a_command ?(loc = 0) a =
|
|
let suffix = Int.to_string loc in
|
|
match a with
|
|
| "add" -> _add
|
|
| "sub" -> _sub
|
|
| "neg" -> _neg
|
|
| "eq" -> _eq suffix
|
|
| "gt" -> _gt suffix
|
|
| "lt" -> _lt suffix
|
|
| "and" -> _and
|
|
| "or" -> _or
|
|
| "not" -> _not
|
|
| _ -> failwith "a_command: Invalid Command"
|
|
;;
|
|
|
|
let addr a = [ String.concat [ "@"; a ] ]
|
|
let push_constant = [ "D=A"; "@SP"; "A=M"; "M=D"; "@SP"; "M=M+1" ]
|
|
|
|
let _end = ["(TERMINATE)"; "@TERMINATE"; "0;JMP"]
|
|
|
|
let _process_push s a =
|
|
match s with
|
|
| "constant" -> addr a @ push_constant
|
|
| _ -> failwith "Invalid Segment"
|
|
;;
|
|
|
|
let m_command (c, s, a) =
|
|
match c with
|
|
| "push" -> _process_push s a
|
|
| _ -> failwith "m_command: Invalid Command"
|
|
;;
|