Reorganized project

This commit is contained in:
2025-12-08 22:25:36 +03:00
parent 8e980a8f1b
commit adbf083c3d
15 changed files with 621 additions and 0 deletions

9
lib/parser/ast.ml Normal file
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

7
lib/parser/dune Normal file
View File

@@ -0,0 +1,7 @@
(library
(name parser)
(modules parser lex parse ast)
(package ollisp))
(menhir (modules parse))
(ocamllex lex)

35
lib/parser/lex.mll Normal file
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
lib/parser/parse.mly Normal file
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
lib/parser/parser.ml Normal file
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