Reorganized basically everything, making way for the compiler

This commit is contained in:
2025-11-15 13:06:16 +03:00
parent 81c349c70a
commit 8e980a8f1b
15 changed files with 84 additions and 25 deletions
+9
View 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
View 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
View File
@@ -0,0 +1,8 @@
(library
(name parser)
(public_name parser)
(modules parser lex parse ast)
)
(menhir (modules parse))
(ocamllex lex)
+35
View File
@@ -0,0 +1,35 @@
{
open Lexing
open Parse
exception SyntaxError of string
let strip_quotes s = String.sub s 1 (String.length s - 2);;
}
let digit = ['0'-'9']
let number_sign = '-' | '+'
let int = number_sign? digit+
let double = digit* '.' digit+ | digit+ '.' digit*
let white = [' ' '\t']+
let newline = '\r' | '\n' | "\r\n"
let sym_char = ['a'-'z' 'A'-'Z' '!' '\\' '+' '-' '*' '/' '_' '?']
let sym = sym_char sym_char*
let str = '"' [^'"']* '"'
rule read =
parse
| white { read lexbuf }
| newline { new_line lexbuf; read lexbuf}
| int { INT (int_of_string (Lexing.lexeme lexbuf))}
| double { DOUBLE (float_of_string (Lexing.lexeme lexbuf))}
| sym { SYM (Lexing.lexeme lexbuf)}
| str { STR (strip_quotes (Lexing.lexeme lexbuf))}
| '(' { LPAREN }
| ')' { RPAREN }
| '\'' { QUOTE }
| '.' { DOT }
| _ { raise (SyntaxError ("Unexpected char: " ^ Lexing.lexeme lexbuf))}
| eof { EOF }
+36
View File
@@ -0,0 +1,36 @@
%{
open Ast
%}
%token <int> INT
%token <float> DOUBLE
%token <string> SYM
%token <string> STR
%token LPAREN
%token RPAREN
%token QUOTE
%token DOT
%token EOF
%start <lisp_ast option> prog
%%
prog:
| EOF { None }
| e = expr { Some e }
;
expr:
| i = INT { LInt i }
| d = DOUBLE { LDouble d}
| s = SYM { LSymbol s }
| s = STR { LString (String.uppercase_ascii s) }
| LPAREN; l = lisp_list_rest { l }
| QUOTE; e = expr { LCons (LSymbol "quote", LCons (e, LNil)) }
;
lisp_list_rest:
| RPAREN { LNil }
| DOT; e = expr; RPAREN { e }
| e = expr; lr = lisp_list_rest { LCons (e, lr) }
;
+16
View File
@@ -0,0 +1,16 @@
let parse_one lb = Parse.prog (Lex.read) lb
let parse lb =
let rec helper () =
match parse_one lb with
| None -> []
| Some (t) -> t :: helper ()
in
helper ()
let parse_str s =
parse (Lexing.from_string s)
module Ast = Ast
module Parse = Parse