feat: Support basic expression

This commit is contained in:
Lucàs
2024-07-02 15:33:58 +02:00
parent c91951308f
commit e563bce4f5
12 changed files with 231 additions and 25 deletions
+34
View File
@@ -0,0 +1,34 @@
(* lib/ast.ml *)
type binary_operator = Add | Substract | Multiply | Divide
type expression =
| IntegerLiteral of int
| BinaryExpression of binary_operator * expression * expression
type statement = ExpressionStatement of expression
type source_file = SourceFile of statement list
(* Print AST *)
let string_of_binary_operator = function
| Add -> "Add"
| Substract -> "Substract"
| Multiply -> "Multiply"
| Divide -> "Divide"
let rec string_of_expression = function
| IntegerLiteral i -> "IntegerLiteral(" ^ string_of_int i ^ ")"
| BinaryExpression (op, e1, e2) ->
"BinaryExpression("
^ string_of_binary_operator op
^ ", " ^ string_of_expression e1 ^ ", " ^ string_of_expression e2 ^ ")"
let string_of_statement = function
| ExpressionStatement e ->
"ExpressionStatement(" ^ string_of_expression e ^ ")"
let string_of_source_file = function
| SourceFile stmts ->
let stmt_strings = List.map string_of_statement stmts in
"SourceFile([" ^ String.concat ", " stmt_strings ^ "])"
+20 -1
View File
@@ -1,2 +1,21 @@
;lib/dune
(library
(name croissant))
(name lexer)
(modules lexer)
(libraries parser))
(library
(name parser)
(modules parser)
(libraries ast))
(library
(name ast)
(modules ast))
(menhir
(modules parser))
(ocamllex
(modules lexer))
+28
View File
@@ -0,0 +1,28 @@
(* lib/lexer.mll *)
{
open Parser
exception Error of char
}
let line_comment = "//" [^ '\n']*
let digit = ['0'-'9']
let integer = digit+
rule token = parse
| [' ' '\t'] | line_comment { token lexbuf }
| ['\n'] { Lexing.new_line lexbuf; token lexbuf }
| '+' { PLUS }
| '-' { MINUS }
| '*' { TIMES }
| '/' { DIVIDE }
| ';' { SEMICOLON }
| integer as lxm { INT(int_of_string lxm) }
| '(' { LPAREN }
| ')' { RPAREN }
| eof { EOF }
| _ as c { raise (Error c) }
+51
View File
@@ -0,0 +1,51 @@
/* lib/parser.mly */
%{
open Ast
%}
%token <int> INT
%token PLUS "+"
%token MINUS "-"
%token TIMES "*"
%token DIVIDE "/"
%token LPAREN "("
%token RPAREN ")"
%token SEMICOLON ";"
%token EOF
%left "+" "-"
%left "*" "/"
//%nonassoc UMINUS
%start main
%type <source_file> main
%%
main:
| statements EOF { SourceFile($1) }
statements:
| statement ";" { [$1] }
| statement ";" statements { $1 :: $3 }
statement:
| expression { ExpressionStatement($1) }
expression:
| literal { $1 }
| binary_expression { $1 }
| "(" expression ")" { $2 }
literal:
| INT { IntegerLiteral($1) }
binary_expression:
| e1=expression PLUS e2=expression { BinaryExpression(Add, e1, e2) }
| e1=expression MINUS e2=expression { BinaryExpression(Substract, e1, e2) }
| e1=expression TIMES e2=expression { BinaryExpression(Multiply, e1, e2) }
| e1=expression DIVIDE e2=expression { BinaryExpression(Divide, e1, e2) }