feat: Add typecheck to the AST

This commit is contained in:
Lucàs
2024-07-05 00:06:32 +02:00
parent 0a42fbe3dc
commit d81b96779a
17 changed files with 234 additions and 39 deletions
+5
View File
@@ -3,4 +3,9 @@
(test
(name print)
(libraries alcotest ast)
)
(test
(name typecheck)
(libraries alcotest ast)
)
+25 -4
View File
@@ -1,4 +1,4 @@
(* test/print.ml *)
(* test/ast/print.ml *)
open Alcotest
open Ast.Syntax
@@ -9,6 +9,7 @@ module To_test = struct
let binary_operator = Ast.Print.string_of_binary_operator
let unary_operator = Ast.Print.string_of_unary_operator
let expression = Ast.Print.string_of_expression
let variable_declaration = Ast.Print.string_of_variable_declaration
let statement = Ast.Print.string_of_statement
let source_file = Ast.Print.string_of_source_file
end
@@ -50,7 +51,7 @@ let test_string_of_binary_operator () =
let tests =
[
("+", "Add", Add);
("-", "Substract", Substract);
("-", "Subtract", Subtract);
("*", "Multiply", Multiply);
("/", "Divide", Divide);
("&&", "AmpersandAmpersand", AmpersandAmpersand);
@@ -94,18 +95,33 @@ let test_string_of_expression () =
(check string) name expected (To_test.expression actual))
tests
let test_string_of_variable_declaration () =
let tests =
[
( "var x: int = 42;",
"VariableDeclaration(IntegerType, Identifier(\"x\"), \
Literal(Integer(42)))",
VariableDeclaration (IntegerType, Identifier "x", Literal (Integer 42))
);
]
in
List.iter
(fun (name, expected, actual) ->
(check string) name expected (To_test.variable_declaration actual))
tests
let test_string_of_statement () =
let tests =
[
( "42;",
"ExpressionStatement(Literal(Integer(42)))",
ExpressionStatement (Literal (Integer 42)) );
( "int x;",
( "var x: int;",
"VariableStatement([VariableDeclaration(IntegerType, \
Identifier(\"x\"), Literal(Null))])",
VariableStatement
[ VariableDeclaration (IntegerType, Identifier "x", Literal Null) ] );
( "int x = 42;",
( "var x: int = 42;",
"VariableStatement([VariableDeclaration(IntegerType, \
Identifier(\"x\"), Literal(Integer(42)))])",
VariableStatement
@@ -152,6 +168,11 @@ let () =
[ test_case "binary_operator" `Quick test_string_of_binary_operator ] );
( "string_of_expression",
[ test_case "expression" `Quick test_string_of_expression ] );
( "string_of_variable_declaration",
[
test_case "variable_declaration" `Quick
test_string_of_variable_declaration;
] );
( "string_of_statement",
[ test_case "statement" `Quick test_string_of_statement ] );
( "string_of_source_file",
+75
View File
@@ -0,0 +1,75 @@
(* test/ast/typecheck.ml *)
open Alcotest
open Ast.Syntax
open Ast.Typecheck
let should_be_valid function_to_test tests =
List.iter
(fun (name, expected, source) ->
let actual = function_to_test source in
check (of_pp Fmt.nop) name expected actual)
tests
let test_type_of_literal () =
let tests =
[
("1", IntegerType, Integer 1);
("1.0", FloatType, Float 1.0);
("true", BooleanType, Boolean true);
("false", BooleanType, Boolean false);
("\"hello\"", StringType, String "hello");
("'c'", CharacterType, Character 'c');
("null", VoidType, Null);
]
in
should_be_valid type_of_literal tests
let test_type_of_expression () =
let tests =
[
("42", IntegerType, Literal (Integer 42));
("foo", StringType, Identifier "foo");
(* TODO Add tests *)
]
and env : environment = { variables = [ ("foo", StringType) ] } in
should_be_valid (type_of_expression env) tests
(* TODO Tests errors *)
let test_type_of_variable_declaration () =
let tests =
[
( "var bar: booleen = true;",
{ variables = [ ("bar", BooleanType) ] },
VariableDeclaration
(BooleanType, Identifier "bar", Literal (Boolean true)) );
]
and env : environment = { variables = [] } in
should_be_valid (type_of_variable_declaration env) tests
(* TODO check other case should return an error *)
let test_type_of_statement () =
let tests = [ (* TODO Add Tests *) ] and env = { variables = [] } in
should_be_valid (type_of_statement env) tests
let test_type_of_source_file () =
let tests = [ (* TODO Add Tests *) ] in
should_be_valid type_of_source_file tests
let () =
run "ast.typecheck"
[
( "type_of_literal",
[ test_case "type_of_literal" `Quick test_type_of_literal ] );
( "type_of_expression",
[ test_case "type_of_expression" `Quick test_type_of_expression ] );
( "type_of_variable_declaration",
[
test_case "type_of_variable_declaration" `Quick
test_type_of_variable_declaration;
] );
( "type_of_statement",
[ test_case "type_of_statement" `Quick test_type_of_statement ] );
( "type_of_source_file",
[ test_case "type_of_source_file" `Quick test_type_of_source_file ] );
]
+1 -1
View File
@@ -1,3 +1,3 @@
/*Hello, World!*/
var a : entier = 1;
var a : chaine = "Hello World";