Reorganized basically everything, making way for the compiler
This commit is contained in:
9
bin/dune
9
bin/dune
@@ -1,6 +1,5 @@
|
||||
(executable
|
||||
(name main)
|
||||
(public_name main)
|
||||
(libraries str lisp unix))
|
||||
(include_subdirs unqualified)
|
||||
|
||||
(name inter)
|
||||
(public_name inter)
|
||||
(libraries str interpreter unix)
|
||||
(package main))
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
open Lisp.Ast;;
|
||||
open Interpreter.Ast;;
|
||||
open Printf;;
|
||||
open Lisp;;
|
||||
open Interpreter;;
|
||||
open Env;;
|
||||
open Eval;;
|
||||
open Read;;
|
||||
|
||||
let () = InterpreterStdlib.init_default_env ()
|
||||
let () = Stdlib.init_default_env ()
|
||||
|
||||
let rec repl env c =
|
||||
let () = printf ">>> "; Out_channel.flush Out_channel.stdout; in
|
||||
@@ -14,7 +13,7 @@ let rec repl env c =
|
||||
| Some "exit" -> ()
|
||||
| Some l ->
|
||||
try
|
||||
let vals = (parse_str l) in
|
||||
let vals = (read_from_str l) in
|
||||
(* dbg_print_all vals; *)
|
||||
pretty_print_all (eval_all env vals);
|
||||
Out_channel.flush Out_channel.stdout;
|
||||
@@ -23,7 +22,7 @@ let rec repl env c =
|
||||
| Invalid_argument s ->
|
||||
printf "%s\nResuming repl\n" s;
|
||||
repl env c
|
||||
| Parser.Error ->
|
||||
| Parser.Parse.Error ->
|
||||
printf "Expression '%s' couldn't be parsed, try again\n" l;
|
||||
repl env c
|
||||
;;
|
||||
@@ -1,3 +1,17 @@
|
||||
|
||||
(* This is different from the lisp_ast data returned by the parser!
|
||||
We will first need to translate that into this in order to use it.
|
||||
This representation includes things that can only occur during runtime,
|
||||
like the various kinds of functions and macros.
|
||||
|
||||
Additionally, since this is an interpreter, macros tend to be a little
|
||||
awkward in that they behave exactly like the macro gets expanded just
|
||||
before the result gets executed. This is different from the compiled
|
||||
behaviour where the macro is evaluated at compile time.
|
||||
|
||||
Though of course, with the dynamic nature of lisp, and its capability
|
||||
to compile more code at runtime, there will naturally be complications.
|
||||
*)
|
||||
type lisp_val =
|
||||
| LInt of int
|
||||
| LDouble of float
|
||||
@@ -17,7 +31,7 @@ type lisp_val =
|
||||
| LLambda of environment * lisp_val * lisp_val
|
||||
(* a macro is exactly the same as a function, with the distinction
|
||||
that it receives all of its arguments completely unevaluated
|
||||
in a compiled lisp this would probably make more of a difference *)
|
||||
*)
|
||||
| LMacro of string * environment * lisp_val * lisp_val
|
||||
| LUnnamedMacro of environment * lisp_val * lisp_val
|
||||
| LQuoted of lisp_val
|
||||
@@ -113,3 +127,16 @@ let pretty_print_all vs =
|
||||
let dbg_print_all vs =
|
||||
let pr v = Printf.printf "%s\n" (dbg_print_one v) in
|
||||
List.iter pr vs
|
||||
|
||||
|
||||
let rec convert_one = function
|
||||
| Parser.Ast.LInt x -> LInt x
|
||||
| Parser.Ast.LDouble x -> LDouble x
|
||||
| Parser.Ast.LNil -> LNil
|
||||
| Parser.Ast.LString s -> LString s
|
||||
| Parser.Ast.LSymbol s -> LSymbol s
|
||||
| Parser.Ast.LCons (a, b) -> LCons (convert_one a, convert_one b)
|
||||
|
||||
|
||||
let read_from_str s =
|
||||
List.map convert_one (Parser.parse_str s)
|
||||
3
interpreter/dune
Normal file
3
interpreter/dune
Normal file
@@ -0,0 +1,3 @@
|
||||
(library
|
||||
(name interpreter)
|
||||
(libraries parser))
|
||||
@@ -200,5 +200,5 @@ let init_default_env () =
|
||||
Idea: maybe put this in a file instead of putting
|
||||
literally the entire standard library in a constant string
|
||||
*)
|
||||
ignore (Eval.eval_all default_env (Read.parse_str init_script));
|
||||
ignore (Eval.eval_all default_env (read_from_str init_script));
|
||||
()
|
||||
7
lib/dune
7
lib/dune
@@ -1,7 +0,0 @@
|
||||
(library
|
||||
(name lisp))
|
||||
|
||||
(include_subdirs unqualified)
|
||||
|
||||
(menhir (modules parser))
|
||||
(ocamllex lexer)
|
||||
0
parser.opam
Normal file
0
parser.opam
Normal file
9
parser/ast.ml
Normal file
9
parser/ast.ml
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
type lisp_ast =
|
||||
| LInt of int
|
||||
| LDouble of float
|
||||
| LSymbol of string
|
||||
| LString of string
|
||||
| LNil
|
||||
| LCons of lisp_ast * lisp_ast
|
||||
18
parser/ast.mli
Normal file
18
parser/ast.mli
Normal file
@@ -0,0 +1,18 @@
|
||||
(** This is a simplified representation for the source code.
|
||||
Note that this is different from the data representation used
|
||||
during execution - that must naturally include things like
|
||||
functions, structs, classes, etc.
|
||||
|
||||
This is used just to represent source code in an easy to process
|
||||
manner. We translate this before actually using it.
|
||||
The interpreter directly translates to its value type, the
|
||||
compiler uses this to optimise and compile.
|
||||
**)
|
||||
|
||||
type lisp_ast =
|
||||
| LInt of int
|
||||
| LDouble of float
|
||||
| LSymbol of string
|
||||
| LString of string
|
||||
| LNil
|
||||
| LCons of lisp_ast * lisp_ast
|
||||
8
parser/dune
Normal file
8
parser/dune
Normal file
@@ -0,0 +1,8 @@
|
||||
(library
|
||||
(name parser)
|
||||
(public_name parser)
|
||||
(modules parser lex parse ast)
|
||||
)
|
||||
|
||||
(menhir (modules parse))
|
||||
(ocamllex lex)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
open Lexing
|
||||
open Parser
|
||||
open Parse
|
||||
exception SyntaxError of string
|
||||
|
||||
let strip_quotes s = String.sub s 1 (String.length s - 2);;
|
||||
@@ -12,7 +12,7 @@
|
||||
%token DOT
|
||||
%token EOF
|
||||
|
||||
%start <Ast.lisp_val option> prog
|
||||
%start <lisp_ast option> prog
|
||||
%%
|
||||
|
||||
prog:
|
||||
@@ -22,7 +22,7 @@ prog:
|
||||
|
||||
expr:
|
||||
| i = INT { LInt i }
|
||||
| d = DOUBLE {LDouble d}
|
||||
| d = DOUBLE { LDouble d}
|
||||
| s = SYM { LSymbol s }
|
||||
| s = STR { LString (String.uppercase_ascii s) }
|
||||
| LPAREN; l = lisp_list_rest { l }
|
||||
@@ -1,4 +1,4 @@
|
||||
let parse_one lb = Parser.prog (Lexer.read) lb
|
||||
let parse_one lb = Parse.prog (Lex.read) lb
|
||||
|
||||
let parse lb =
|
||||
let rec helper () =
|
||||
@@ -11,3 +11,6 @@ let parse lb =
|
||||
let parse_str s =
|
||||
parse (Lexing.from_string s)
|
||||
|
||||
|
||||
module Ast = Ast
|
||||
module Parse = Parse
|
||||
Reference in New Issue
Block a user