Big changes:
Compiler and VM are now working well enough to support larger programs. A test program is included and executed immediately upon running the executable. A more feature complete read-eval-print loop is planned.
This commit is contained in:
@@ -5,6 +5,7 @@ type literal =
|
||||
| Int of int
|
||||
| Double of float
|
||||
| String of string
|
||||
| Symbol of string
|
||||
| Nil
|
||||
| Cons of literal * literal
|
||||
|
||||
@@ -96,6 +97,7 @@ and of_literal : Syntactic_ast.literal -> literal = function
|
||||
| LitString x -> String x
|
||||
| LitCons (a, b) -> Cons (of_literal a, of_literal b)
|
||||
| LitNil -> Nil
|
||||
| LitSymbol s -> Symbol s
|
||||
|
||||
and of_expr : Syntactic_ast.expr -> expression = function
|
||||
| Literal l -> Literal (of_literal l)
|
||||
|
||||
@@ -47,6 +47,7 @@ let rec compile_one p = function
|
||||
| Literal Nil -> emit_constant p (Vm.Types.Nil)
|
||||
| Literal (Double x) -> emit_constant p (Vm.Types.Double x)
|
||||
| Literal (String s) -> emit_constant p (Vm.Types.String s)
|
||||
| Literal (Symbol s) -> emit_constant p (Vm.Types.Symbol s)
|
||||
| Literal (Cons (a, b)) ->
|
||||
let* _ = compile_one p (Literal a) in
|
||||
let* _ = compile_one p (Literal b) in
|
||||
@@ -90,6 +91,7 @@ let rec compile_one p = function
|
||||
compile_one p e1
|
||||
| Begin (e1 :: e2 :: rest) ->
|
||||
let* _ = compile_one p e1 in
|
||||
let* _ = emit_instr p Vm.Types.Pop in
|
||||
compile_one p (Begin (e2 :: rest))
|
||||
|
||||
and compile_all p exprs =
|
||||
@@ -136,7 +138,6 @@ let compile (exprs : expression list) (tbl : int SymbolTable.t) =
|
||||
let* _ = emit_instr program End in
|
||||
let* _ = backpatch program in
|
||||
let final_instrs = smooth_instrs program in
|
||||
print_endline (string_of_int (SymbolTable.cardinal tbl));
|
||||
Ok (Vm.make_vm final_instrs (Dynarray.to_array program.constants) ((SymbolTable.cardinal tbl) + 1))
|
||||
|
||||
let compile_src src =
|
||||
|
||||
@@ -9,6 +9,7 @@ type literal =
|
||||
| LitDouble of float
|
||||
| LitString of string
|
||||
| LitCons of literal * literal
|
||||
| LitSymbol of string
|
||||
| LitNil
|
||||
|
||||
type lambda_list = string list * string option
|
||||
@@ -203,6 +204,18 @@ and builtin_set cons =
|
||||
let* expr = unwrap_exp (transform expr) in
|
||||
exp (Set (sym, expr))
|
||||
|
||||
and builtin_quote cons =
|
||||
let* expr = sexpr_cadr cons in
|
||||
let lit x = exp (Literal x) in
|
||||
let rec aux = function
|
||||
| LSymbol s -> (LitSymbol s)
|
||||
| LInt x -> (LitInt x)
|
||||
| LDouble x -> (LitDouble x)
|
||||
| LString x -> (LitString x)
|
||||
| LCons (a, b) -> (LitCons (aux a, aux b))
|
||||
| LNil -> (LitNil) in
|
||||
lit (aux expr)
|
||||
|
||||
and apply f args =
|
||||
let* args = list_of_sexpr args in
|
||||
let* args = traverse (fun x -> unwrap_exp (transform x)) args in
|
||||
@@ -217,6 +230,7 @@ and builtin_symbol = function
|
||||
| "cond" -> builtin_cond
|
||||
| "if" -> builtin_if
|
||||
| "set!" -> builtin_set
|
||||
| "quote" -> builtin_quote
|
||||
| _ -> (function
|
||||
| LCons (f, args) -> apply f args
|
||||
| _ -> Error "Invalid function application!")
|
||||
@@ -236,7 +250,8 @@ and transform : lisp_ast -> (top_level, string) result = function
|
||||
let make (expr : Parser.Ast.lisp_ast) : (top_level, string) result =
|
||||
transform expr
|
||||
|
||||
|
||||
let of_src s =
|
||||
Util.traverse make (Parser.parse_str s)
|
||||
|
||||
(* Printing, for debug purposes *)
|
||||
let pf = Printf.sprintf
|
||||
@@ -266,7 +281,7 @@ and print_literal = function
|
||||
| LitString x -> pf "\"%s\"" x
|
||||
| LitNil -> pf "nil"
|
||||
| LitCons (a, b) -> pf "(%s . %s)" (print_literal a) (print_literal b)
|
||||
|
||||
| LitSymbol s -> pf "'%s" s
|
||||
and print_expr = function
|
||||
| Literal l -> print_literal l
|
||||
| Lambda (ll, (defs, exprs)) ->
|
||||
|
||||
Reference in New Issue
Block a user