summaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
authorCarlos Maniero <carlos@maniero.me>2023-05-08 23:53:42 -0300
committerJohnny Richard <johnny@johnnyrichard.com>2023-05-09 21:46:51 +0200
commit35425aa5837543e4cc3fc82266dc2ae429cb2779 (patch)
tree1d7dec87dc17785162c20206371818f5e28fd99b /src/ast.c
parent3842de0e22d72075f06bd8cc44b8744e86c21725 (diff)
parser: Ensure the expression types
When assign a variable or returning a value it now ensures that the expression matches the expected type. To make this possible a %result_type% field was added to ast_node_t and this field is used whenever to make the comparison. Signed-off-by: Carlos Maniero <carlos@maniero.me> Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/ast.c b/src/ast.c
index 8a46034..4fd5a3f 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -73,6 +73,7 @@ ast_node_new_return_stmt(ast_node_t *argument)
ast_node_t *node = ast_node_new();
*node = (ast_node_t){
+ .result_type = TYPE_VOID,
.kind = AST_RETURN_STMT,
.data = { .return_stmt = { .argument = argument } },
};
@@ -106,6 +107,7 @@ ast_node_new_literal_integer(uint32_t number)
*node = (ast_node_t){
.kind = AST_LITERAL,
+ .result_type = TYPE_I32,
.data = {
.literal = {
.kind = AST_LITERAL_INTEGER,
@@ -124,6 +126,7 @@ ast_node_new_literal_bool(bool boolean)
*node = (ast_node_t){
.kind = AST_LITERAL,
+ .result_type = TYPE_BOOL,
.data = {
.literal = {
.kind = AST_LITERAL_BOOL,
@@ -136,12 +139,13 @@ ast_node_new_literal_bool(bool boolean)
}
ast_node_t *
-ast_node_new_binary_operation(ast_binary_operation_kind_t kind, ast_node_t *left, ast_node_t *right)
+ast_node_new_binary_operation(ast_binary_operation_kind_t kind, ast_node_t *left, ast_node_t *right, type_t result_type)
{
ast_node_t *node = ast_node_new();
*node = (ast_node_t){
.kind = AST_BINARY_OPERATION,
+ .result_type = result_type,
.data = {
.binary_operation = {
.kind = kind,
@@ -161,6 +165,7 @@ ast_node_new_variable_declaration(string_view_t variable_name, type_t type, ast_
*node = (ast_node_t){
.kind = AST_VARIABLE_DECLARATION,
+ .result_type = TYPE_VOID,
.data = {
.variable_declaration = {
.identifier = { .name = variable_name },
@@ -180,6 +185,7 @@ ast_node_new_variable_assignment(ast_identifier_t *identifier, ast_node_t *expre
*node = (ast_node_t){
.kind = AST_VARIABLE_ASSIGNMENT,
+ .result_type = TYPE_VOID,
.data = {
.variable_assignment = {
.identifier = identifier,
@@ -192,14 +198,29 @@ ast_node_new_variable_assignment(ast_identifier_t *identifier, ast_node_t *expre
}
ast_node_t *
-ast_node_new_variable(ast_identifier_t *identifier)
+ast_node_new_variable(ast_identifier_t *identifier, type_t result_type)
{
ast_node_t *node = ast_node_new();
*node = (ast_node_t){
.kind = AST_VARIABLE,
+ .result_type = result_type,
.data = { .variable = { .identifier = identifier } },
};
return node;
}
+
+char *
+ast_type_to_str(type_t type)
+{
+ switch (type) {
+ case TYPE_I32:
+ return "i32";
+ case TYPE_BOOL:
+ return "bool";
+ case TYPE_VOID:
+ return "void";
+ }
+ assert(false);
+}