feat: support variable declaration statement

This commit is contained in:
Lucàs
2024-07-03 00:18:17 +02:00
parent 69e88fd5fd
commit 9d3fa71e34
6 changed files with 131 additions and 4 deletions
+17
View File
@@ -2,6 +2,15 @@
open Syntax
(** [string_of_type t] returns a string representation of the type [t]. *)
let string_of_type = function
| Type_Integer -> "Type_Integer"
| Type_Float -> "Type_Float"
| Type_Character -> "Type_Character"
| Type_String -> "Type_String"
| Type_Boolean -> "Type_Boolean"
| Type_Void -> "Type_Void"
(** [string_of_binary_operator op] returns a string representation of the binary operator [op]. *)
let string_of_binary_operator = function
| Add -> "Add"
@@ -42,10 +51,18 @@ let rec string_of_expression = function
^ string_of_binary_operator op
^ ", " ^ string_of_expression e1 ^ ", " ^ string_of_expression e2 ^ ")"
let string_of_variable_declaration = function
| VariableDeclaration (t, id, e) ->
"VariableDeclaration(" ^ string_of_type t ^ ", " ^ string_of_expression id
^ ", " ^ string_of_expression e ^ ")"
(** [string_of_statement s] returns a string representation of the statement [s]. *)
let string_of_statement = function
| ExpressionStatement e ->
"ExpressionStatement(" ^ string_of_expression e ^ ")"
| VariableStatement decls ->
let decl_strings = List.map string_of_variable_declaration decls in
"VariableStatement([" ^ String.concat ", " decl_strings ^ "])"
(** [string_of_source_file f] returns a string representation of the source file [f]. *)
let string_of_source_file = function
+15 -1
View File
@@ -1,5 +1,13 @@
(* lib/ast/syntax.ml *)
type _type =
| Type_Integer
| Type_Float
| Type_Character
| Type_String
| Type_Boolean
| Type_Void
type literal =
| Integer of int
| Float of float
@@ -30,5 +38,11 @@ type expression =
| UnaryExpression of unary_operator * expression
| BinaryExpression of binary_operator * expression * expression
type statement = ExpressionStatement of expression
type variable_declaration =
| VariableDeclaration of _type * expression * expression
type statement =
| ExpressionStatement of expression
| VariableStatement of variable_declaration list
type source_file = SourceFile of statement list
+17 -3
View File
@@ -5,6 +5,8 @@
}
let line_comment = "//" [^ '\n']*
let block_comment = "/*" [^'.']* "*/"
let comment = line_comment | block_comment
let letter = ['a'-'z' 'A'-'Z']
let digit = ['0'-'9']
@@ -18,14 +20,13 @@ let char = "'" [^'.'] "'"
let string = '"' [^'.']* '"'
rule token = parse
| [' ' '\t'] | line_comment { token lexbuf }
| [' ' '\t'] | comment { token lexbuf }
| ['\n'] { Lexing.new_line lexbuf; token lexbuf }
| '+' { PLUS }
| '-' { MINUS }
| '*' { TIMES }
| '/' { DIVIDE }
| ';' { SEMICOLON }
| "&&" { AMPERSAND_AMPERSAND }
| "||" { BAR_BAR }
| "==" { EQUALS_EQUALS }
@@ -34,15 +35,28 @@ rule token = parse
| "<=" { LESS_THAN_EQUALS }
| '>' { GREATER_THAN }
| ">=" { GREATER_THAN_EQUALS }
| '=' { EQUALS }
| "!" { EXCLAMATION }
| ';' { SEMICOLON }
| ':' { COLON }
| ',' { COMMA }
| '(' { LPAREN }
| ')' { RPAREN }
| "var" { VAR }
| "vrai" { BOOLEAN(true) }
| "faux" { BOOLEAN(false) }
| "vide" { NULL }
| "nul" { NULL }
| "entier" { INTEGER_TYPE }
| "reel" { FLOAT_TYPE }
| "caractere" { CHARACTER_TYPE }
| "chaine" { STRING_TYPE }
| "booleen" { BOOLEAN_TYPE }
| "vide" { VOID_TYPE }
| integer as lxm { INTEGER(int_of_string lxm) }
| float as lxm { FLOAT(float_of_string lxm) }
| char as lxm { CHARACTER(lxm.[1]) }
+29
View File
@@ -11,6 +11,13 @@
%token <string> IDENTIFIER
%token NULL
%token INTEGER_TYPE
%token FLOAT_TYPE
%token CHARACTER_TYPE
%token STRING_TYPE
%token BOOLEAN_TYPE
%token VOID_TYPE
%token PLUS "+"
%token MINUS "-"
%token TIMES "*"
@@ -24,11 +31,16 @@
%token LESS_THAN_EQUALS "<="
%token GREATER_THAN ">"
%token GREATER_THAN_EQUALS ">="
%token EQUALS "="
%token LPAREN "("
%token RPAREN ")"
%token SEMICOLON ";"
%token COLON ":"
%token COMMA ","
%token VAR "var"
%token EOF
@@ -52,6 +64,23 @@ statements:
statement:
| expression { ExpressionStatement($1) }
| "var" variable_declaration_list { VariableStatement($2) }
variable_declaration_list:
| variable_declaration { [$1] }
| variable_declaration "," variable_declaration_list { $1 :: $3 }
variable_declaration:
| IDENTIFIER ":" tp "=" expression { VariableDeclaration($3, Identifier($1), $5) }
| IDENTIFIER ":" tp { VariableDeclaration($3, Identifier($1), Literal(Null)) }
tp:
| INTEGER_TYPE { Type_Integer }
| FLOAT_TYPE { Type_Float }
| CHARACTER_TYPE { Type_Character }
| STRING_TYPE { Type_String }
| BOOLEAN_TYPE { Type_Boolean }
| VOID_TYPE { Type_Void }
expression:
| literal { Literal($1) }
+27
View File
@@ -4,6 +4,14 @@ open Alcotest
open Ast.Syntax
open Ast.Print
let test_string_of_type () =
check string "int" "Type_Integer" (string_of_type Type_Integer);
check string "float" "Type_Float" (string_of_type Type_Float);
check string "bool" "Type_Boolean" (string_of_type Type_Boolean);
check string "string" "Type_String" (string_of_type Type_String);
check string "char" "Type_Character" (string_of_type Type_Character);
check string "void" "Type_Void" (string_of_type Type_Void)
let test_string_of_literal () =
check string "42" "Integer(42)" (string_of_literal (Integer 42));
check string "3.14" "Float(3.14)" (string_of_literal (Float 3.14));
@@ -50,6 +58,24 @@ let test_string_of_expression () =
let test_string_of_statement () =
let stmt = ExpressionStatement (Literal (Integer 42)) in
check string "42;" "ExpressionStatement(Literal(Integer(42)))"
(string_of_statement stmt);
let stmt =
VariableStatement
[ VariableDeclaration (Type_Integer, Identifier "x", Literal Null) ]
in
check string "int x;"
"VariableStatement([VariableDeclaration(Type_Integer, Identifier(\"x\"), \
Literal(Null))])"
(string_of_statement stmt);
let stmt =
VariableStatement
[
VariableDeclaration (Type_Integer, Identifier "x", Literal (Integer 42));
]
in
check string "int x = 42;"
"VariableStatement([VariableDeclaration(Type_Integer, Identifier(\"x\"), \
Literal(Integer(42)))])"
(string_of_statement stmt)
let test_string_of_source_file () =
@@ -71,6 +97,7 @@ let () =
let open Alcotest in
run "AST tests"
[
("string_of_type", [ test_case "type" `Quick test_string_of_type ]);
( "string_of_literal",
[ test_case "literal" `Quick test_string_of_literal ] );
( "string_of_unary_operator",
+26
View File
@@ -0,0 +1,26 @@
// Déclaration d'une variable de type entier
var a: entier = 4 + 2 + 3 * 1;
/*
SourceFile([
VariableStatement([
VariableDeclaration(
Type_Integer,
Identifier("a"),
BinaryExpression(
Add,
BinaryExpression(
Add,
Literal(Integer(4)
),
Literal(Integer(2))
),
BinaryExpression(
Multiply,
Literal(Integer(3)),
Literal(Integer(1))
))
)]
)]
)
*/