public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
* [PATCH olang] parser: returns an unknown type instead of a SV
@ 2024-10-09 11:24 Carlos Maniero
  2024-10-09 11:24 ` [olang/patches/.build.yml] build success builds.sr.ht
  2024-10-09 13:28 ` [PATCH olang] parser: returns an unknown type instead of a SV Johnny Richard
  0 siblings, 2 replies; 3+ messages in thread
From: Carlos Maniero @ 2024-10-09 11:24 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

To support pointer, it is more convenient for the AST to have an
*type_t* structure instead of an string view, once the type_t can
support multiple shapes, such as pointers.

The parser is still not resolving the type which is a checker
responsibility. However, it returns a unknown type which is resolved by
the checker.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.c                  |  8 +++---
 src/ast.h                  | 12 ++++----
 src/checker.c              | 59 ++++++++++++++++++++++++++++++++++++--
 src/codegen_linux_x86_64.c | 16 +++++++----
 src/parser.c               | 12 ++++++--
 src/pretty_print_ast.c     |  4 +--
 src/scope.c                |  2 +-
 src/scope.h                |  4 +--
 src/type.c                 | 36 +++++------------------
 src/type.h                 | 25 +++++++++++-----
 10 files changed, 115 insertions(+), 63 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index d6ec70c..79daca6 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -44,7 +44,7 @@ ast_new_node_fn_def(arena_t *arena,
                     token_loc_t loc,
                     string_view_t id,
                     list_t *params,
-                    string_view_t return_type,
+                    type_t *return_type,
                     ast_node_t *block)
 {
     assert(arena);
@@ -86,7 +86,7 @@ ast_new_node_fn_call(arena_t *arena, token_loc_t loc, string_view_t id, list_t *
 }
 
 ast_node_t *
-ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, string_view_t type, ast_node_t *value)
+ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, type_t *type, ast_node_t *value)
 {
     ast_node_t *node_var_def = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t));
     assert(node_var_def);
@@ -217,13 +217,13 @@ ast_new_node_block(arena_t *arena)
 }
 
 ast_fn_param_t *
-ast_new_fn_param(arena_t *arena, string_view_t id, string_view_t type_id)
+ast_new_fn_param(arena_t *arena, string_view_t id, type_t *type)
 {
     ast_fn_param_t *fn_param = (ast_fn_param_t *)arena_alloc(arena, sizeof(ast_fn_param_t));
     assert(fn_param);
 
     fn_param->id = id;
-    fn_param->type_id = type_id;
+    fn_param->type = type;
 
     return fn_param;
 }
diff --git a/src/ast.h b/src/ast.h
index 238435e..fccc303 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -66,7 +66,7 @@ typedef struct ast_translation_unit
 typedef struct ast_fn_param
 {
     string_view_t id;
-    string_view_t type_id;
+    type_t *type;
 } ast_fn_param_t;
 
 typedef struct ast_fn_definition
@@ -74,7 +74,7 @@ typedef struct ast_fn_definition
     ast_node_meta_t meta;
     string_view_t id;
     list_t *params;
-    string_view_t return_type;
+    type_t *return_type;
     ast_node_t *block;
     scope_t *scope;
 } ast_fn_definition_t;
@@ -91,7 +91,7 @@ typedef struct ast_var_definition
 {
     ast_node_meta_t meta;
     string_view_t id;
-    string_view_t type;
+    type_t *type;
     ast_node_t *value;
     scope_t *scope;
 } ast_var_definition_t;
@@ -206,14 +206,14 @@ ast_new_node_fn_def(arena_t *arena,
                     token_loc_t loc,
                     string_view_t id,
                     list_t *params,
-                    string_view_t return_type,
+                    type_t *return_type,
                     ast_node_t *block);
 
 ast_node_t *
 ast_new_node_fn_call(arena_t *arena, token_loc_t loc, string_view_t id, list_t *args);
 
 ast_node_t *
-ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, string_view_t type, ast_node_t *value);
+ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, type_t *type, ast_node_t *value);
 
 ast_node_t *
 ast_new_node_bin_op(arena_t *arena, token_loc_t loc, ast_binary_op_kind_t kind, ast_node_t *lhs, ast_node_t *rhs);
@@ -240,6 +240,6 @@ ast_node_t *
 ast_new_node_block(arena_t *arena);
 
 ast_fn_param_t *
-ast_new_fn_param(arena_t *arena, string_view_t id, string_view_t type_id);
+ast_new_fn_param(arena_t *arena, string_view_t id, type_t *type);
 
 #endif /* AST_H */
diff --git a/src/checker.c b/src/checker.c
index 36202bd..c688b7a 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -37,6 +37,55 @@ checker_new(arena_t *arena)
     return checker;
 }
 
+static type_t
+type_from_id(string_view_t id)
+{
+    type_t type = { 0 };
+    type.id = id;
+    if (string_view_eq_to_cstr(id, "u8")) {
+        type.kind = TYPE_PRIMITIVE;
+        type.as_primitive.size = 1;
+        type.as_primitive.kind = TYPE_U8;
+        return type;
+    }
+    if (string_view_eq_to_cstr(id, "u16")) {
+        type.kind = TYPE_PRIMITIVE;
+        type.as_primitive.size = 2;
+        type.as_primitive.kind = TYPE_U16;
+        return type;
+    }
+    if (string_view_eq_to_cstr(id, "u32")) {
+        type.kind = TYPE_PRIMITIVE;
+        type.as_primitive.size = 4;
+        type.as_primitive.kind = TYPE_U32;
+        return type;
+    }
+    if (string_view_eq_to_cstr(id, "u64")) {
+        type.kind = TYPE_PRIMITIVE;
+        type.as_primitive.size = 8;
+        type.as_primitive.kind = TYPE_U64;
+        return type;
+    }
+
+    // FIXME: handle user defined types
+    assert(0 && "unknown type");
+}
+
+/**
+ * transform unknown types into actual types
+ */
+static void
+type_resolve(type_t *type)
+{
+    switch (type->kind) {
+        case TYPE_UNKNOWN:
+            *type = type_from_id(type->as_unknown.id);
+            break;
+        case TYPE_PRIMITIVE:
+            break;
+    }
+}
+
 void
 checker_check(checker_t *checker, ast_node_t *ast)
 {
@@ -67,7 +116,8 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
             ast_fn_definition_t *fn_def = &ast->as_fn_def;
             fn_def->scope = scope_push(scope);
 
-            symbol_t *symbol = symbol_new(checker->arena, fn_def->id, type_from_id(fn_def->return_type));
+            type_resolve(fn_def->return_type);
+            symbol_t *symbol = symbol_new(checker->arena, fn_def->id, fn_def->return_type);
             scope_insert(scope, symbol);
 
             list_item_t *item = list_head(fn_def->params);
@@ -75,7 +125,8 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
             while (item != NULL) {
                 ast_fn_param_t *param = (ast_fn_param_t *)item->value;
 
-                symbol_t *symbol = symbol_new(checker->arena, param->id, type_from_id(param->type_id));
+                type_resolve(param->type);
+                symbol_t *symbol = symbol_new(checker->arena, param->id, param->type);
                 scope_insert(fn_def->scope, symbol);
 
                 item = list_next(item);
@@ -156,7 +207,9 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
         case AST_NODE_VAR_DEF: {
             string_view_t id = ast->as_var_def.id;
 
-            symbol_t *symbol = symbol_new(checker->arena, id, type_from_id(ast->as_var_def.type));
+            type_resolve(ast->as_var_def.type);
+
+            symbol_t *symbol = symbol_new(checker->arena, id, ast->as_var_def.type);
 
             scope_insert(scope, symbol);
             ast->as_var_def.scope = scope;
diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
index 10005b9..703f3b5 100644
--- a/src/codegen_linux_x86_64.c
+++ b/src/codegen_linux_x86_64.c
@@ -165,7 +165,7 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr
 
             size_t offset = codegen_linux_x86_64_get_stack_offset(codegen, symbol);
 
-            size_t bytes = type_to_bytes(&symbol->type);
+            size_t bytes = type_to_bytes(symbol->type);
 
             fprintf(codegen->out, "    mov -%ld(%%rbp), %s\n", offset, get_reg_for(REG_ACCUMULATOR, bytes));
             return bytes;
@@ -195,7 +195,7 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr
 
             fprintf(codegen->out, "    call " SV_FMT "\n", SV_ARG(fn_call.id));
 
-            return type_to_bytes(&symbol->type);
+            return type_to_bytes(symbol->type);
         }
         case AST_NODE_BINARY_OP: {
             ast_binary_op_t bin_op = expr_node->as_bin_op;
@@ -570,7 +570,7 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
                     codegen_linux_x86_64_emit_expression(codegen, var_def.value);
                 }
 
-                size_t type_size = type_to_bytes(&symbol->type);
+                size_t type_size = type_to_bytes(symbol->type);
 
                 fprintf(codegen->out,
                         "    mov %s, -%ld(%%rbp)\n",
@@ -593,7 +593,7 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
 
                 codegen_linux_x86_64_emit_expression(codegen, var_assign.expr);
 
-                size_t type_size = type_to_bytes(&symbol->type);
+                size_t type_size = type_to_bytes(symbol->type);
                 fprintf(codegen->out, "    mov %s, -%ld(%%rbp)\n", get_reg_for(REG_ACCUMULATOR, type_size), offset);
 
                 break;
@@ -682,6 +682,9 @@ type_to_bytes(type_t *type)
         case TYPE_PRIMITIVE: {
             return type->as_primitive.size;
         }
+        case TYPE_UNKNOWN: {
+            assert(0 && "cannot calculate size of an unknown type: probably a parser issue.");
+        }
     }
 
     assert(0 && "unreachable");
@@ -702,7 +705,7 @@ calculate_fn_local_size(scope_t *scope)
 
     for (size_t i = 0; i < scope->symbols->size; ++i) {
         symbol_t *symbol = (symbol_t *)kvs[i]->value;
-        local_size += type_to_bytes(&symbol->type);
+        local_size += type_to_bytes(symbol->type);
     }
 
     size_t max_child_local_size = 0;
@@ -748,7 +751,8 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_
 
         fprintf(codegen->out,
                 "    mov %s, -%ld(%%rbp)\n",
-                get_reg_for(x86_call_args[i], symbol->type.as_primitive.size),
+                // FIXME: Type may not be an as_primitive
+                get_reg_for(x86_call_args[i], symbol->type->as_primitive.size),
                 offset);
 
         // FIXME: add offset according to the param size
diff --git a/src/parser.c b/src/parser.c
index 5d6290b..6875b42 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -371,7 +371,7 @@ parser_parse_fn_params(parser_t *parser)
         string_view_t type_id;
         parser_parse_type(parser, &type_id);
 
-        ast_fn_param_t *param = ast_new_fn_param(parser->arena, token.value, type_id);
+        ast_fn_param_t *param = ast_new_fn_param(parser->arena, token.value, type_new_unknown(parser->arena, type_id));
         list_append(params, param);
 
         skip_line_feeds(parser->lexer);
@@ -420,7 +420,12 @@ parser_parse_fn_definition(parser_t *parser)
         return NULL;
     }
 
-    return ast_new_node_fn_def(parser->arena, fn_name_token.loc, fn_name_token.value, params, fn_return_type, block);
+    return ast_new_node_fn_def(parser->arena,
+                               fn_name_token.loc,
+                               fn_name_token.value,
+                               params,
+                               type_new_unknown(parser->arena, fn_return_type),
+                               block);
 }
 
 static bool
@@ -652,7 +657,8 @@ parser_parse_var_def(parser_t *parser)
         return NULL;
     }
 
-    ast_node_t *var_node = ast_new_node_var_def(parser->arena, token_id.loc, token_id.value, var_type, expr);
+    ast_node_t *var_node = ast_new_node_var_def(
+        parser->arena, token_id.loc, token_id.value, type_new_unknown(parser->arena, var_type), expr);
 
     return var_node;
 }
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index 0c5d2d5..5feb270 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -113,7 +113,7 @@ pretty_print_new_fn_param(ast_fn_param_t *param, arena_t *arena)
 {
     pretty_print_node_t *node = pretty_print_node_new(arena);
     char name[256];
-    sprintf(name, "Param_Definition <name:" SV_FMT "> <type:" SV_FMT ">", SV_ARG(param->id), SV_ARG(param->type_id));
+    sprintf(name, "Param_Definition <name:" SV_FMT "> <type:" SV_FMT ">", SV_ARG(param->id), SV_ARG(param->type->id));
     node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
     strcpy(node->name, name);
     return node;
@@ -148,7 +148,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
             sprintf(name,
                     "Function_Definition <name:" SV_FMT "> <return:" SV_FMT ">",
                     SV_ARG(fn_def.id),
-                    SV_ARG(fn_def.return_type));
+                    SV_ARG(fn_def.return_type->id));
             node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
             strcpy(node->name, name);
 
diff --git a/src/scope.c b/src/scope.c
index 81f610a..e483fbe 100644
--- a/src/scope.c
+++ b/src/scope.c
@@ -49,7 +49,7 @@ scope_new(arena_t *arena)
 }
 
 symbol_t *
-symbol_new(arena_t *arena, string_view_t id, type_t type)
+symbol_new(arena_t *arena, string_view_t id, type_t *type)
 {
     assert(arena);
     symbol_t *symbol = (symbol_t *)arena_alloc(arena, sizeof(symbol_t));
diff --git a/src/scope.h b/src/scope.h
index 92a5a4f..08eb681 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -26,7 +26,7 @@
 typedef struct symbol
 {
     string_view_t id;
-    type_t type;
+    type_t *type;
 } symbol_t;
 
 typedef struct scope
@@ -41,7 +41,7 @@ scope_t *
 scope_new(arena_t *arena);
 
 symbol_t *
-symbol_new(arena_t *arena, string_view_t id, type_t type);
+symbol_new(arena_t *arena, string_view_t id, type_t *type);
 
 symbol_t *
 scope_lookup(scope_t *scope, string_view_t id);
diff --git a/src/type.c b/src/type.c
index 64147a2..9de5650 100644
--- a/src/type.c
+++ b/src/type.c
@@ -17,35 +17,13 @@
 #include "type.h"
 #include "assert.h"
 
-type_t
-type_from_id(string_view_t id)
+type_t *
+type_new_unknown(arena_t *arena, string_view_t id)
 {
-    type_t type = { 0 };
-    if (string_view_eq_to_cstr(id, "u8")) {
-        type.kind = TYPE_PRIMITIVE;
-        type.as_primitive.size = 1;
-        type.as_primitive.kind = TYPE_U8;
-        return type;
-    }
-    if (string_view_eq_to_cstr(id, "u16")) {
-        type.kind = TYPE_PRIMITIVE;
-        type.as_primitive.size = 2;
-        type.as_primitive.kind = TYPE_U16;
-        return type;
-    }
-    if (string_view_eq_to_cstr(id, "u32")) {
-        type.kind = TYPE_PRIMITIVE;
-        type.as_primitive.size = 4;
-        type.as_primitive.kind = TYPE_U32;
-        return type;
-    }
-    if (string_view_eq_to_cstr(id, "u64")) {
-        type.kind = TYPE_PRIMITIVE;
-        type.as_primitive.size = 8;
-        type.as_primitive.kind = TYPE_U64;
-        return type;
-    }
+    type_t *type = arena_alloc(arena, sizeof(type_t));
+    assert(type);
 
-    // FIXME: handle user defined types
-    assert(0 && "unknown type");
+    type->kind = TYPE_UNKNOWN;
+    type->as_unknown.id = id;
+    return type;
 }
diff --git a/src/type.h b/src/type.h
index 1da3a11..97a2a41 100644
--- a/src/type.h
+++ b/src/type.h
@@ -16,9 +16,11 @@
  */
 #ifndef TYPE_H
 #define TYPE_H
+#include "arena.h"
 #include "string_view.h"
 typedef enum
 {
+    TYPE_UNKNOWN,
     TYPE_PRIMITIVE
 } type_kind_t;
 
@@ -32,20 +34,29 @@ typedef enum
 
 typedef struct type_primitive
 {
-    short size;
+    type_kind_t _type_kind;
+    string_view_t id;
     type_primitive_kind_t kind;
+    short size;
 } type_primitive_t;
 
-typedef struct type
+typedef struct type_unknown
 {
+    type_kind_t _type_kind;
     string_view_t id;
-    type_kind_t kind;
-    union
+} type_unknown_t;
+
+typedef union
+{
+    struct
     {
-        type_primitive_t as_primitive;
+        type_kind_t kind;
+        string_view_t id;
     };
+    type_unknown_t as_unknown;
+    type_primitive_t as_primitive;
 } type_t;
 
-type_t
-type_from_id(string_view_t id);
+type_t *
+type_new_unknown(arena_t *arena, string_view_t id);
 #endif

base-commit: 2407c8150403c373df86e66b5886102c9f143193
-- 
2.46.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-10-09 11:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-09 11:24 [PATCH olang] parser: returns an unknown type instead of a SV Carlos Maniero
2024-10-09 11:24 ` [olang/patches/.build.yml] build success builds.sr.ht
2024-10-09 13:28 ` [PATCH olang] parser: returns an unknown type instead of a SV Johnny Richard

Code repositories for project(s) associated with this public inbox

	https://git.johnnyrichard.com/olang.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox