diff --git a/bin/dune b/bin/dune index 5abb7b8..927a2f4 100644 --- a/bin/dune +++ b/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)) diff --git a/bin/main.ml b/bin/inter.ml similarity index 80% rename from bin/main.ml rename to bin/inter.ml index 043065d..d95b42e 100644 --- a/bin/main.ml +++ b/bin/inter.ml @@ -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 ;; diff --git a/lib/ast.ml b/interpreter/ast.ml similarity index 78% rename from lib/ast.ml rename to interpreter/ast.ml index e781c6a..5135236 100644 --- a/lib/ast.ml +++ b/interpreter/ast.ml @@ -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 @@ -16,8 +30,8 @@ type lisp_val = | LFunction of string * environment * lisp_val * 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 *) + that it receives all of its arguments completely unevaluated + *) | 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) diff --git a/interpreter/dune b/interpreter/dune new file mode 100644 index 0000000..27aebc8 --- /dev/null +++ b/interpreter/dune @@ -0,0 +1,3 @@ +(library + (name interpreter) + (libraries parser)) diff --git a/lib/env.ml b/interpreter/env.ml similarity index 100% rename from lib/env.ml rename to interpreter/env.ml diff --git a/lib/eval.ml b/interpreter/eval.ml similarity index 100% rename from lib/eval.ml rename to interpreter/eval.ml diff --git a/lib/interpreterStdlib.ml b/interpreter/stdlib.ml similarity index 98% rename from lib/interpreterStdlib.ml rename to interpreter/stdlib.ml index 6f00749..5234b77 100644 --- a/lib/interpreterStdlib.ml +++ b/interpreter/stdlib.ml @@ -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)); () diff --git a/lib/dune b/lib/dune deleted file mode 100644 index c6ff196..0000000 --- a/lib/dune +++ /dev/null @@ -1,7 +0,0 @@ -(library - (name lisp)) - -(include_subdirs unqualified) - -(menhir (modules parser)) -(ocamllex lexer) \ No newline at end of file diff --git a/parser.opam b/parser.opam new file mode 100644 index 0000000..e69de29 diff --git a/parser/ast.ml b/parser/ast.ml new file mode 100644 index 0000000..b122c7e --- /dev/null +++ b/parser/ast.ml @@ -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 diff --git a/parser/ast.mli b/parser/ast.mli new file mode 100644 index 0000000..37bdb91 --- /dev/null +++ b/parser/ast.mli @@ -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 diff --git a/parser/dune b/parser/dune new file mode 100644 index 0000000..549ec66 --- /dev/null +++ b/parser/dune @@ -0,0 +1,8 @@ +(library + (name parser) + (public_name parser) + (modules parser lex parse ast) + ) + +(menhir (modules parse)) +(ocamllex lex) diff --git a/lib/lexer.mll b/parser/lex.mll similarity index 98% rename from lib/lexer.mll rename to parser/lex.mll index 612b623..abff6c9 100644 --- a/lib/lexer.mll +++ b/parser/lex.mll @@ -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);; diff --git a/lib/parser.mly b/parser/parse.mly similarity index 90% rename from lib/parser.mly rename to parser/parse.mly index 28aa6f9..91969bc 100644 --- a/lib/parser.mly +++ b/parser/parse.mly @@ -12,7 +12,7 @@ %token DOT %token EOF -%start prog +%start 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 } diff --git a/lib/read.ml b/parser/parser.ml similarity index 69% rename from lib/read.ml rename to parser/parser.ml index 4955f4a..83beecf 100644 --- a/lib/read.ml +++ b/parser/parser.ml @@ -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