114 lines
2.4 KiB
OCaml
114 lines
2.4 KiB
OCaml
type value =
|
|
| Int of int
|
|
| Closure of { code : int; env : value list }
|
|
| Continuation of continuation
|
|
| Bool of bool
|
|
|
|
and continuation =
|
|
| Halt
|
|
| Return_to of continuation
|
|
| Apply_to of { func : value; cont : continuation }
|
|
| Eval_to of { expr : t; cont : continuation }
|
|
| Pop_to of { n : int; cont : continuation }
|
|
| Exception_to of { handler : continuation; cont : continuation }
|
|
|
|
and t =
|
|
| PUSH of value
|
|
| POP
|
|
| DUP
|
|
| SWAP
|
|
| OVER
|
|
| ROT
|
|
| ADD
|
|
| SUB
|
|
| MUL
|
|
| DIV
|
|
| MOD
|
|
| EQ
|
|
| NE
|
|
| LT
|
|
| LE
|
|
| GT
|
|
| GE
|
|
| AND
|
|
| OR
|
|
| NOT
|
|
| NEG
|
|
| JMP of int
|
|
| JMP_IF of int
|
|
| JMP_IF_NOT of int
|
|
| CALL
|
|
| RET
|
|
| MK_CLOSURE of int
|
|
| LOAD of int
|
|
| STORE of int
|
|
| PUSH_ENV
|
|
| POP_ENV
|
|
| HALT
|
|
| TRY of int
|
|
| RAISE
|
|
| RERAISE
|
|
|
|
let show_value = function
|
|
| Int n -> Printf.sprintf "Int(%d)" n
|
|
| Bool b -> Printf.sprintf "Bool(%b)" b
|
|
| Closure { code; env } -> Printf.sprintf "Closure(code=%d, env_len=%d)" code (List.length env)
|
|
| Continuation _ -> "Continuation"
|
|
|
|
let show_continuation = function
|
|
| Halt -> "Halt"
|
|
| Return_to _ -> "Return_to"
|
|
| Apply_to _ -> "Apply_to"
|
|
| Eval_to _ -> "Eval_to"
|
|
| Pop_to _ -> "Pop_to"
|
|
| Exception_to _ -> "Exception_to"
|
|
|
|
let show = function
|
|
| PUSH v -> Printf.sprintf "PUSH %s" (show_value v)
|
|
| POP -> "POP"
|
|
| DUP -> "DUP"
|
|
| SWAP -> "SWAP"
|
|
| OVER -> "OVER"
|
|
| ROT -> "ROT"
|
|
| ADD -> "ADD"
|
|
| SUB -> "SUB"
|
|
| MUL -> "MUL"
|
|
| DIV -> "DIV"
|
|
| MOD -> "MOD"
|
|
| EQ -> "EQ"
|
|
| NE -> "NE"
|
|
| LT -> "LT"
|
|
| LE -> "LE"
|
|
| GT -> "GT"
|
|
| GE -> "GE"
|
|
| AND -> "AND"
|
|
| OR -> "OR"
|
|
| NOT -> "NOT"
|
|
| NEG -> "NEG"
|
|
| JMP offset -> Printf.sprintf "JMP %d" offset
|
|
| JMP_IF offset -> Printf.sprintf "JMP_IF %d" offset
|
|
| JMP_IF_NOT offset -> Printf.sprintf "JMP_IF_NOT %d" offset
|
|
| CALL -> "CALL"
|
|
| RET -> "RET"
|
|
| MK_CLOSURE code -> Printf.sprintf "MK_CLOSURE %d" code
|
|
| LOAD idx -> Printf.sprintf "LOAD %d" idx
|
|
| STORE idx -> Printf.sprintf "STORE %d" idx
|
|
| PUSH_ENV -> "PUSH_ENV"
|
|
| POP_ENV -> "POP_ENV"
|
|
| HALT -> "HALT"
|
|
| TRY offset -> Printf.sprintf "TRY %d" offset
|
|
| RAISE -> "RAISE"
|
|
| RERAISE -> "RERAISE"
|
|
|
|
let int_of_value = function
|
|
| Int n -> Some n
|
|
| Bool true -> Some 1
|
|
| Bool false -> Some 0
|
|
| _ -> None
|
|
|
|
let bool_of_value = function
|
|
| Bool b -> Some b
|
|
| Int 0 -> Some false
|
|
| Int n -> Some (n <> 0)
|
|
| _ -> None
|