public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
* [PATCH olang v2 0/6] Remove symbol lookups from codegen
@ 2024-10-31  3:13 Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 1/6] ast: create the ast_ident_t and apply it to var_def and ref Carlos Maniero
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Until now, the codegen was responsible to make the symbol resolution
because we didn't have a semantics layer.

Now with the semantics, the symbols are already resolved and saved on
the AST. To avoid redundancy and code duplication, a new struct was
added to represent identifiers.

v2:
- rename ast_id_t to ast_ident_t

Carlos Maniero (6):
  ast: create the ast_ident_t and apply it to var_def and ref
  semantics: resolve variable symbols
  semantics: refactor: use the ast_ident_t into the fn_call node
  semantics: refactor: use the ast_ident_t into the fn_def.params
  type: refactor: rename type.id to type.name
  ast: remove dead code from var_assign ast node

 src/ast.c              |  14 ++--
 src/ast.h              |  32 ++++----
 src/codegen_x86_64.c   |  50 +++++--------
 src/pretty_print_ast.c |  18 +++--
 src/type.c             |   8 +-
 src/type.h             |  25 ++++---
 src/type_checker.c     | 164 ++++++++++++++++++++++++++++++++++++-----
 7 files changed, 213 insertions(+), 98 deletions(-)


base-commit: f87fb371a0105a458be07bd3f269bb45da913d16
-- 
2.46.1


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

* [PATCH olang v2 1/6] ast: create the ast_ident_t and apply it to var_def and ref
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
@ 2024-10-31  3:13 ` Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 2/6] semantics: resolve variable symbols Carlos Maniero
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

The ast_ident_t is a base structure that will be used for symbol
resolution. Instead of having the id string_view and the scope in all
nodes that need to be added to or resolved in the symbol table, these
fields were added into a single struct, this will help to remove the
redundancy into the semantics level which will lock to a common
structure for all nodes.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.c              |  6 +++---
 src/ast.h              | 14 +++++++++-----
 src/codegen_x86_64.c   | 14 ++++++++------
 src/pretty_print_ast.c |  5 +++--
 src/type_checker.c     | 22 +++++++++++++++-------
 5 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index b96a463..7bb5277 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -106,7 +106,7 @@ ast_new_node_var_def(arena_t *arena,
     node_var_def->loc = loc;
     ast_var_definition_t *var_def = &node_var_def->as_var_def;
 
-    var_def->id = id;
+    var_def->id.name = id;
     var_def->type = type;
     var_def->value = value;
 
@@ -167,14 +167,14 @@ ast_new_node_literal_u32(arena_t *arena, token_loc_t loc, uint32_t value)
 }
 
 ast_node_t *
-ast_new_node_ref(arena_t *arena, token_loc_t loc, string_view_t id)
+ast_new_node_ref(arena_t *arena, token_loc_t loc, string_view_t ident_name)
 {
     ast_node_t *node_ref = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t));
     assert(node_ref);
 
     node_ref->kind = AST_NODE_REF;
     node_ref->loc = loc;
-    node_ref->as_ref.id = id;
+    node_ref->as_ref.ident.name = ident_name;
 
     return node_ref;
 }
diff --git a/src/ast.h b/src/ast.h
index 7c5e9af..33496a8 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -68,6 +68,12 @@ typedef struct ast_block
     list_t *nodes;
 } ast_block_t;
 
+typedef struct ast_ident
+{
+    string_view_t name;
+    scope_t *scope;
+} ast_ident_t;
+
 typedef struct ast_translation_unit
 {
     AST_NODE_HEAD;
@@ -102,10 +108,9 @@ typedef struct ast_fn_call
 typedef struct ast_var_definition
 {
     AST_NODE_HEAD;
-    string_view_t id;
+    ast_ident_t id;
     type_t *type;
     ast_node_t *value;
-    scope_t *scope;
 } ast_var_definition_t;
 
 typedef enum
@@ -126,8 +131,7 @@ typedef struct ast_literal
 typedef struct ast_ref
 {
     AST_NODE_HEAD;
-    string_view_t id;
-    scope_t *scope;
+    ast_ident_t ident;
 } ast_ref_t;
 
 typedef enum ast_binary_op_kind
@@ -266,7 +270,7 @@ ast_node_t *
 ast_new_node_literal_u32(arena_t *arena, token_loc_t loc, uint32_t value);
 
 ast_node_t *
-ast_new_node_ref(arena_t *arena, token_loc_t loc, string_view_t id);
+ast_new_node_ref(arena_t *arena, token_loc_t loc, string_view_t ident_name);
 
 ast_node_t *
 ast_new_node_var_assign_stmt(arena_t *arena,
diff --git a/src/codegen_x86_64.c b/src/codegen_x86_64.c
index 9006250..b695cc0 100644
--- a/src/codegen_x86_64.c
+++ b/src/codegen_x86_64.c
@@ -143,7 +143,7 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
         case AST_NODE_REF: {
             ast_ref_t ref = expr_node->as_ref;
 
-            symbol_t *symbol = scope_lookup(ref.scope, ref.id);
+            symbol_t *symbol = scope_lookup(ref.ident.scope, ref.ident.name);
             assert(symbol);
 
             size_t offset = codegen_x86_64_get_stack_offset(codegen, symbol);
@@ -597,9 +597,10 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
                     switch (bin_op.lhs->kind) {
                         case AST_NODE_REF: {
                             ast_ref_t ref = bin_op.lhs->as_ref;
-                            scope_t *scope = ref.scope;
+                            scope_t *scope = ref.ident.scope;
 
-                            symbol_t *symbol = scope_lookup(scope, ref.id);
+                            symbol_t *symbol =
+                                scope_lookup(scope, ref.ident.name);
                             assert(symbol);
 
                             size_t offset = codegen_x86_64_get_stack_offset(
@@ -668,7 +669,8 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
 
                     ast_ref_t ref = unary_op.operand->as_ref;
 
-                    symbol_t *symbol = scope_lookup(ref.scope, ref.id);
+                    symbol_t *symbol =
+                        scope_lookup(ref.ident.scope, ref.ident.name);
                     assert(symbol);
 
                     size_t offset =
@@ -722,9 +724,9 @@ codegen_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
 
             case AST_NODE_VAR_DEF: {
                 ast_var_definition_t var_def = node->as_var_def;
-                scope_t *scope = var_def.scope;
+                scope_t *scope = var_def.id.scope;
 
-                symbol_t *symbol = scope_lookup(scope, var_def.id);
+                symbol_t *symbol = scope_lookup(scope, var_def.id.name);
                 assert(symbol);
 
                 size_t type_size = type_to_bytes(symbol->type);
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index bc5d119..9c0e607 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -288,7 +288,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
             char name[256];
             sprintf(name,
                     "Var_Definition <name:" SV_FMT "> <kind:" SV_FMT ">",
-                    SV_ARG(var.id),
+                    SV_ARG(var.id.name),
                     SV_ARG(var.type->id));
             node->name =
                 (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
@@ -305,7 +305,8 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
             ast_ref_t ref = ast->as_ref;
 
             char name[256];
-            sprintf(name, "Reference <name:" SV_FMT ">", SV_ARG(ref.id));
+            sprintf(
+                name, "Reference <name:" SV_FMT ">", SV_ARG(ref.ident.name));
             node->name =
                 (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
             strcpy(node->name, name);
diff --git a/src/type_checker.c b/src/type_checker.c
index 235d711..abf7ae9 100644
--- a/src/type_checker.c
+++ b/src/type_checker.c
@@ -102,6 +102,18 @@ checker_check(checker_t *checker, ast_node_t *ast)
     // TODO: traverse the ast tree to verify semantics
 }
 
+static void
+register_id(checker_t *checker,
+            scope_t *scope,
+            ast_ident_t *ident,
+            type_t *type)
+{
+    ident->scope = scope;
+    symbol_t *symbol = symbol_new(checker->arena, ident->name, type);
+
+    scope_insert(scope, symbol);
+}
+
 static void
 populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
 {
@@ -215,22 +227,18 @@ 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;
 
             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;
+            register_id(
+                checker, scope, &ast->as_var_def.id, ast->as_var_def.type);
 
             populate_scope(checker, scope, ast->as_var_def.value);
             return;
         }
 
         case AST_NODE_REF: {
-            ast->as_ref.scope = scope;
+            ast->as_ref.ident.scope = scope;
             return;
         }
 
-- 
2.46.1


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

* [PATCH olang v2 2/6] semantics: resolve variable symbols
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 1/6] ast: create the ast_ident_t and apply it to var_def and ref Carlos Maniero
@ 2024-10-31  3:13 ` Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 3/6] semantics: refactor: use the ast_ident_t into the fn_call node Carlos Maniero
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

This is a first step for semantics check. It introduces the symbol to
ast_ident_t. It still does not check if types match neither print helpful
errors.

Why to add the symbol into the ast_ident_t?
-------------------------------------------

The semantics is required to resolve the symbol in order to perform type
checking and to check if the reference can be resolved. So, checking if
the symbol exists and throw the found symbol away is a computational
waste.

Additionally, adding the symbol to the id removes complexity from
codegen, once symbol_lookups will be no longer required.

Why to create the resolve_symbols function?
-------------------------------------------

If you look at the resolve_symbols and the populate_scope you should
wonder "why there are two functions that traverse the entire ast?". The
main reason is that olang allows reference before definition. So if
something such as a function call refer to a function before it is
defined the checker will fail. Meaning that it is required to first to
populate the scope and make the symbols' registration for the entire AST
and afterwards check for symbols.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.c              |   2 +-
 src/ast.h              |   3 +-
 src/codegen_x86_64.c   |  34 ++++-------
 src/pretty_print_ast.c |   2 +-
 src/type_checker.c     | 125 ++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 137 insertions(+), 29 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index 7bb5277..e6b518e 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -106,7 +106,7 @@ ast_new_node_var_def(arena_t *arena,
     node_var_def->loc = loc;
     ast_var_definition_t *var_def = &node_var_def->as_var_def;
 
-    var_def->id.name = id;
+    var_def->ident.name = id;
     var_def->type = type;
     var_def->value = value;
 
diff --git a/src/ast.h b/src/ast.h
index 33496a8..9d128d7 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -72,6 +72,7 @@ typedef struct ast_ident
 {
     string_view_t name;
     scope_t *scope;
+    symbol_t *symbol;
 } ast_ident_t;
 
 typedef struct ast_translation_unit
@@ -108,7 +109,7 @@ typedef struct ast_fn_call
 typedef struct ast_var_definition
 {
     AST_NODE_HEAD;
-    ast_ident_t id;
+    ast_ident_t ident;
     type_t *type;
     ast_node_t *value;
 } ast_var_definition_t;
diff --git a/src/codegen_x86_64.c b/src/codegen_x86_64.c
index b695cc0..9b101f8 100644
--- a/src/codegen_x86_64.c
+++ b/src/codegen_x86_64.c
@@ -143,12 +143,10 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
         case AST_NODE_REF: {
             ast_ref_t ref = expr_node->as_ref;
 
-            symbol_t *symbol = scope_lookup(ref.ident.scope, ref.ident.name);
-            assert(symbol);
-
-            size_t offset = codegen_x86_64_get_stack_offset(codegen, symbol);
+            size_t offset =
+                codegen_x86_64_get_stack_offset(codegen, ref.ident.symbol);
 
-            size_t bytes = type_to_bytes(symbol->type);
+            size_t bytes = type_to_bytes(ref.ident.symbol->type);
 
             fprintf(codegen->out,
                     "    mov -%ld(%%rbp), %s\n",
@@ -597,18 +595,14 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
                     switch (bin_op.lhs->kind) {
                         case AST_NODE_REF: {
                             ast_ref_t ref = bin_op.lhs->as_ref;
-                            scope_t *scope = ref.ident.scope;
-
-                            symbol_t *symbol =
-                                scope_lookup(scope, ref.ident.name);
-                            assert(symbol);
 
                             size_t offset = codegen_x86_64_get_stack_offset(
-                                codegen, symbol);
+                                codegen, ref.ident.symbol);
 
                             codegen_x86_64_emit_expression(codegen, bin_op.rhs);
 
-                            size_t type_size = type_to_bytes(symbol->type);
+                            size_t type_size =
+                                type_to_bytes(ref.ident.symbol->type);
                             fprintf(codegen->out,
                                     "    mov %s, -%ld(%%rbp)\n",
                                     get_reg_for(REG_ACCUMULATOR, type_size),
@@ -669,12 +663,8 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
 
                     ast_ref_t ref = unary_op.operand->as_ref;
 
-                    symbol_t *symbol =
-                        scope_lookup(ref.ident.scope, ref.ident.name);
-                    assert(symbol);
-
-                    size_t offset =
-                        codegen_x86_64_get_stack_offset(codegen, symbol);
+                    size_t offset = codegen_x86_64_get_stack_offset(
+                        codegen, ref.ident.symbol);
 
                     fprintf(
                         codegen->out, "    lea -%ld(%%rbp), %%rax\n", offset);
@@ -724,16 +714,12 @@ codegen_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
 
             case AST_NODE_VAR_DEF: {
                 ast_var_definition_t var_def = node->as_var_def;
-                scope_t *scope = var_def.id.scope;
-
-                symbol_t *symbol = scope_lookup(scope, var_def.id.name);
-                assert(symbol);
 
-                size_t type_size = type_to_bytes(symbol->type);
+                size_t type_size = type_to_bytes(var_def.ident.symbol->type);
                 codegen->base_offset += type_size;
 
                 codegen_x86_64_put_stack_offset(
-                    codegen, symbol, codegen->base_offset);
+                    codegen, var_def.ident.symbol, codegen->base_offset);
 
                 if (var_def.value) {
                     codegen_x86_64_emit_expression(codegen, var_def.value);
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index 9c0e607..06b93f1 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -288,7 +288,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
             char name[256];
             sprintf(name,
                     "Var_Definition <name:" SV_FMT "> <kind:" SV_FMT ">",
-                    SV_ARG(var.id.name),
+                    SV_ARG(var.ident.name),
                     SV_ARG(var.type->id));
             node->name =
                 (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
diff --git a/src/type_checker.c b/src/type_checker.c
index abf7ae9..081034d 100644
--- a/src/type_checker.c
+++ b/src/type_checker.c
@@ -23,6 +23,9 @@
 static void
 populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast);
 
+static void
+resolve_symbols(checker_t *checker, ast_node_t *ast);
+
 checker_t *
 checker_new(arena_t *arena)
 {
@@ -98,6 +101,7 @@ checker_check(checker_t *checker, ast_node_t *ast)
 
     scope_t *scope = scope_new(checker->arena);
     populate_scope(checker, scope, ast);
+    resolve_symbols(checker, ast);
 
     // TODO: traverse the ast tree to verify semantics
 }
@@ -108,12 +112,27 @@ register_id(checker_t *checker,
             ast_ident_t *ident,
             type_t *type)
 {
-    ident->scope = scope;
     symbol_t *symbol = symbol_new(checker->arena, ident->name, type);
 
+    ident->scope = scope;
+    ident->symbol = symbol;
+
     scope_insert(scope, symbol);
 }
 
+static void
+resolve_id(checker_t *checker, ast_ident_t *id)
+{
+    assert(checker);
+
+    symbol_t *symbol = scope_lookup(id->scope, id->name);
+
+    // FIXME: assert types and print a friendly error message
+    assert(symbol);
+
+    id->symbol = symbol;
+}
+
 static void
 populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
 {
@@ -231,7 +250,7 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
             type_resolve(ast->as_var_def.type);
 
             register_id(
-                checker, scope, &ast->as_var_def.id, ast->as_var_def.type);
+                checker, scope, &ast->as_var_def.ident, ast->as_var_def.type);
 
             populate_scope(checker, scope, ast->as_var_def.value);
             return;
@@ -247,3 +266,105 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
             return;
     }
 }
+
+static void
+resolve_symbols(checker_t *checker, ast_node_t *ast)
+{
+    assert(checker);
+
+    switch (ast->kind) {
+        case AST_NODE_TRANSLATION_UNIT: {
+            list_item_t *item = list_head(ast->as_translation_unit.decls);
+
+            while (item != NULL) {
+                resolve_symbols(checker, (ast_node_t *)item->value);
+                item = list_next(item);
+            }
+            return;
+        }
+
+        case AST_NODE_FN_DEF: {
+            if (ast->as_fn_def.block != NULL) {
+                resolve_symbols(checker, ast->as_fn_def.block);
+            }
+            return;
+        }
+
+        case AST_NODE_FN_CALL: {
+            list_item_t *item = list_head(ast->as_fn_call.args);
+
+            while (item != NULL) {
+                resolve_symbols(checker, (ast_node_t *)item->value);
+                item = list_next(item);
+            }
+
+            return;
+        }
+
+        case AST_NODE_IF_STMT: {
+            resolve_symbols(checker, ast->as_if_stmt.cond);
+            resolve_symbols(checker, ast->as_if_stmt.then);
+
+            if (ast->as_if_stmt._else) {
+                resolve_symbols(checker, ast->as_if_stmt._else);
+            }
+
+            return;
+        }
+
+        case AST_NODE_WHILE_STMT: {
+            resolve_symbols(checker, ast->as_while_stmt.cond);
+            resolve_symbols(checker, ast->as_while_stmt.then);
+
+            return;
+        }
+
+        case AST_NODE_BINARY_OP: {
+            ast_binary_op_t bin_op = ast->as_bin_op;
+
+            resolve_symbols(checker, bin_op.lhs);
+            resolve_symbols(checker, bin_op.rhs);
+            return;
+        }
+
+        case AST_NODE_UNARY_OP: {
+            ast_unary_op_t unary_op = ast->as_unary_op;
+
+            resolve_symbols(checker, unary_op.operand);
+            return;
+        }
+
+        case AST_NODE_RETURN_STMT: {
+            ast_return_stmt_t return_stmt = ast->as_return_stmt;
+
+            resolve_symbols(checker, return_stmt.value);
+            return;
+        }
+
+        case AST_NODE_BLOCK: {
+            ast_block_t block = ast->as_block;
+
+            list_item_t *item = list_head(block.nodes);
+
+            while (item != NULL) {
+                resolve_symbols(checker, (ast_node_t *)item->value);
+                item = list_next(item);
+            }
+
+            return;
+        }
+
+        case AST_NODE_VAR_DEF: {
+            resolve_symbols(checker, ast->as_var_def.value);
+            return;
+        }
+
+        case AST_NODE_REF: {
+            resolve_id(checker, &ast->as_ref.ident);
+            return;
+        }
+        case AST_NODE_LITERAL:
+        case AST_NODE_UNKNOWN:
+            return;
+    }
+}
-- 
2.46.1


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

* [PATCH olang v2 3/6] semantics: refactor: use the ast_ident_t into the fn_call node
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 1/6] ast: create the ast_ident_t and apply it to var_def and ref Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 2/6] semantics: resolve variable symbols Carlos Maniero
@ 2024-10-31  3:13 ` Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 4/6] semantics: refactor: use the ast_ident_t into the fn_def.params Carlos Maniero
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.c              | 4 ++--
 src/ast.h              | 5 ++---
 src/codegen_x86_64.c   | 9 ++++-----
 src/pretty_print_ast.c | 5 +++--
 src/type_checker.c     | 3 ++-
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index e6b518e..443f0e2 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -71,7 +71,7 @@ ast_new_node_fn_def(arena_t *arena,
 ast_node_t *
 ast_new_node_fn_call(arena_t *arena,
                      token_loc_t loc,
-                     string_view_t id,
+                     string_view_t ident_name,
                      list_t *args)
 {
     assert(arena);
@@ -85,7 +85,7 @@ ast_new_node_fn_call(arena_t *arena,
     node_fn_call->loc = loc;
     ast_fn_call_t *fn_call = &node_fn_call->as_fn_call;
 
-    fn_call->id = id;
+    fn_call->ident.name = ident_name;
     fn_call->args = args;
 
     return node_fn_call;
diff --git a/src/ast.h b/src/ast.h
index 9d128d7..c679d7d 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -101,9 +101,8 @@ typedef struct ast_fn_definition
 typedef struct ast_fn_call
 {
     AST_NODE_HEAD;
-    string_view_t id;
+    ast_ident_t ident;
     list_t *args;
-    scope_t *scope;
 } ast_fn_call_t;
 
 typedef struct ast_var_definition
@@ -244,7 +243,7 @@ ast_new_node_fn_def(arena_t *arena,
 ast_node_t *
 ast_new_node_fn_call(arena_t *arena,
                      token_loc_t loc,
-                     string_view_t id,
+                     string_view_t ident_name,
                      list_t *args);
 
 ast_node_t *
diff --git a/src/codegen_x86_64.c b/src/codegen_x86_64.c
index 9b101f8..62511a1 100644
--- a/src/codegen_x86_64.c
+++ b/src/codegen_x86_64.c
@@ -157,9 +157,6 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
         case AST_NODE_FN_CALL: {
             ast_fn_call_t fn_call = expr_node->as_fn_call;
 
-            symbol_t *symbol = scope_lookup(fn_call.scope, fn_call.id);
-            assert(symbol);
-
             size_t i = 0;
             for (list_item_t *item = list_head(fn_call.args); item != NULL;
                  item = list_next(item)) {
@@ -182,9 +179,11 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
                         get_reg_for(x86_call_args[i - 1], 8));
             }
 
-            fprintf(codegen->out, "    call " SV_FMT "\n", SV_ARG(fn_call.id));
+            fprintf(codegen->out,
+                    "    call " SV_FMT "\n",
+                    SV_ARG(fn_call.ident.name));
 
-            return type_to_bytes(symbol->type);
+            return type_to_bytes(fn_call.ident.symbol->type);
         }
         case AST_NODE_BINARY_OP: {
             ast_binary_op_t bin_op = expr_node->as_bin_op;
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index 06b93f1..e717439 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -183,8 +183,9 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
             ast_fn_call_t fn_call = ast->as_fn_call;
 
             char name[256];
-            sprintf(
-                name, "Function_Call <name:" SV_FMT ">", SV_ARG(fn_call.id));
+            sprintf(name,
+                    "Function_Call <name:" SV_FMT ">",
+                    SV_ARG(fn_call.ident.name));
             node->name =
                 (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
             strcpy(node->name, name);
diff --git a/src/type_checker.c b/src/type_checker.c
index 081034d..6b09666 100644
--- a/src/type_checker.c
+++ b/src/type_checker.c
@@ -179,7 +179,7 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
         }
 
         case AST_NODE_FN_CALL: {
-            ast->as_fn_call.scope = scope;
+            ast->as_fn_call.ident.scope = scope;
 
             list_item_t *item = list_head(ast->as_fn_call.args);
 
@@ -291,6 +291,7 @@ resolve_symbols(checker_t *checker, ast_node_t *ast)
         }
 
         case AST_NODE_FN_CALL: {
+            resolve_id(checker, &ast->as_fn_call.ident);
             list_item_t *item = list_head(ast->as_fn_call.args);
 
             while (item != NULL) {
-- 
2.46.1


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

* [PATCH olang v2 4/6] semantics: refactor: use the ast_ident_t into the fn_def.params
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
                   ` (2 preceding siblings ...)
  2024-10-31  3:13 ` [PATCH olang v2 3/6] semantics: refactor: use the ast_ident_t into the fn_call node Carlos Maniero
@ 2024-10-31  3:13 ` Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 5/6] type: refactor: rename type.id to type.name Carlos Maniero
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

With this refactor the codegen no longer perform symbol_lookups by
receiving the symbols fully resolved at the semantics level.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.c              | 4 ++--
 src/ast.h              | 4 ++--
 src/codegen_x86_64.c   | 9 ++++-----
 src/pretty_print_ast.c | 2 +-
 src/type_checker.c     | 4 +---
 5 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index 443f0e2..f94f163 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -247,13 +247,13 @@ ast_new_node_block(arena_t *arena)
 }
 
 ast_fn_param_t *
-ast_new_fn_param(arena_t *arena, string_view_t id, type_t *type)
+ast_new_fn_param(arena_t *arena, string_view_t ident_name, 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->ident.name = ident_name;
     fn_param->type = type;
 
     return fn_param;
diff --git a/src/ast.h b/src/ast.h
index c679d7d..316f921 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -83,7 +83,7 @@ typedef struct ast_translation_unit
 
 typedef struct ast_fn_param
 {
-    string_view_t id;
+    ast_ident_t ident;
     type_t *type;
 } ast_fn_param_t;
 
@@ -298,6 +298,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, type_t *type);
+ast_new_fn_param(arena_t *arena, string_view_t ident_name, type_t *type);
 
 #endif /* AST_H */
diff --git a/src/codegen_x86_64.c b/src/codegen_x86_64.c
index 62511a1..5077d91 100644
--- a/src/codegen_x86_64.c
+++ b/src/codegen_x86_64.c
@@ -895,19 +895,18 @@ codegen_x86_64_emit_function(codegen_x86_64_t *codegen,
 
         ast_fn_param_t *param = item->value;
 
-        symbol_t *symbol = scope_lookup(fn_def->scope, param->id);
-        assert(symbol);
-
         // FIXME: add offset according to the param size
         codegen->base_offset += 8;
         size_t offset = codegen->base_offset;
 
-        codegen_x86_64_put_stack_offset(codegen, symbol, codegen->base_offset);
+        codegen_x86_64_put_stack_offset(
+            codegen, param->ident.symbol, codegen->base_offset);
 
         fprintf(codegen->out,
                 "    mov %s, -%ld(%%rbp)\n",
                 // FIXME: Type may not be an as_primitive
-                get_reg_for(x86_call_args[i], symbol->type->as_primitive.size),
+                get_reg_for(x86_call_args[i],
+                            param->ident.symbol->type->as_primitive.size),
                 offset);
 
         ++i;
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index e717439..9501159 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -120,7 +120,7 @@ pretty_print_new_fn_param(ast_fn_param_t *param, arena_t *arena)
     char name[256];
     sprintf(name,
             "Param_Definition <name:" SV_FMT "> <type:" SV_FMT ">",
-            SV_ARG(param->id),
+            SV_ARG(param->ident.name),
             SV_ARG(param->type->id));
     node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
     strcpy(node->name, name);
diff --git a/src/type_checker.c b/src/type_checker.c
index 6b09666..ad51002 100644
--- a/src/type_checker.c
+++ b/src/type_checker.c
@@ -165,9 +165,7 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
                 ast_fn_param_t *param = (ast_fn_param_t *)item->value;
 
                 type_resolve(param->type);
-                symbol_t *symbol =
-                    symbol_new(checker->arena, param->id, param->type);
-                scope_insert(fn_def->scope, symbol);
+                register_id(checker, scope, &param->ident, param->type);
 
                 item = list_next(item);
             }
-- 
2.46.1


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

* [PATCH olang v2 5/6] type: refactor: rename type.id to type.name
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
                   ` (3 preceding siblings ...)
  2024-10-31  3:13 ` [PATCH olang v2 4/6] semantics: refactor: use the ast_ident_t into the fn_def.params Carlos Maniero
@ 2024-10-31  3:13 ` Carlos Maniero
  2024-10-31  3:13 ` [PATCH olang v2 6/6] ast: remove dead code from var_assign ast node Carlos Maniero
  2024-11-01  2:17 ` [PATCH olang v2 0/6] Remove symbol lookups from codegen Johnny Richard
  6 siblings, 0 replies; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Now that there is a struct called ast_ident_t the type.id may be
interpreted as an ast_id, to avoid confusion, it was renamed to name
which also is more meaningful since the id is not actually the type id
(as per TOKEN_ID) but the full type string representation. ie: "u8***".

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/pretty_print_ast.c |  6 +++---
 src/type.c             |  8 ++++----
 src/type.h             | 25 ++++++++++++++-----------
 src/type_checker.c     | 14 +++++++-------
 4 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index 9501159..7fbed75 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -121,7 +121,7 @@ pretty_print_new_fn_param(ast_fn_param_t *param, arena_t *arena)
     sprintf(name,
             "Param_Definition <name:" SV_FMT "> <type:" SV_FMT ">",
             SV_ARG(param->ident.name),
-            SV_ARG(param->type->id));
+            SV_ARG(param->type->name));
     node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
     strcpy(node->name, name);
     return node;
@@ -158,7 +158,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
                     "Function_Definition <name:" SV_FMT "> <return:" SV_FMT
                     ">%s",
                     SV_ARG(fn_def.id),
-                    SV_ARG(fn_def.return_type->id),
+                    SV_ARG(fn_def.return_type->name),
                     fn_def._extern ? " <extern>" : "");
             node->name =
                 (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
@@ -290,7 +290,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
             sprintf(name,
                     "Var_Definition <name:" SV_FMT "> <kind:" SV_FMT ">",
                     SV_ARG(var.ident.name),
-                    SV_ARG(var.type->id));
+                    SV_ARG(var.type->name));
             node->name =
                 (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
             strcpy(node->name, name);
diff --git a/src/type.c b/src/type.c
index 4a8d6f4..b146fb7 100644
--- a/src/type.c
+++ b/src/type.c
@@ -18,24 +18,24 @@
 #include "assert.h"
 
 type_t *
-type_new_unknown(arena_t *arena, string_view_t id)
+type_new_unknown(arena_t *arena, string_view_t name)
 {
     type_t *type = arena_alloc(arena, sizeof(type_t));
     assert(type);
 
     type->kind = TYPE_UNKNOWN;
-    type->id = id;
+    type->name = name;
     return type;
 }
 
 type_t *
-type_new_ptr(arena_t *arena, string_view_t id, type_t *ref_type)
+type_new_ptr(arena_t *arena, string_view_t name, type_t *ref_type)
 {
     type_t *type = arena_alloc(arena, sizeof(type_t));
     assert(type);
 
     type->kind = TYPE_PTR;
-    type->id = id;
+    type->name = name;
     type->as_ptr.type = ref_type;
     return type;
 }
diff --git a/src/type.h b/src/type.h
index d930a88..e5f2481 100644
--- a/src/type.h
+++ b/src/type.h
@@ -19,6 +19,16 @@
 #include "arena.h"
 #include "string_view.h"
 
+#define TYPE_BASE                                                              \
+    {                                                                          \
+        type_kind_t kind;                                                      \
+        string_view_t name;                                                    \
+    }
+
+#define TYPE_HEAD                                                              \
+    type_kind_t base_kind;                                                     \
+    string_view_t name
+
 typedef union type type_t;
 
 typedef enum
@@ -38,32 +48,25 @@ typedef enum
 
 typedef struct type_primitive
 {
-    type_kind_t _type_kind;
-    string_view_t id;
+    TYPE_HEAD;
     type_primitive_kind_t kind;
     short size;
 } type_primitive_t;
 
 typedef struct type_unknown
 {
-    type_kind_t _type_kind;
-    string_view_t id;
+    TYPE_HEAD;
 } type_unknown_t;
 
 typedef struct type_ptr
 {
-    type_kind_t _type_kind;
-    string_view_t id;
+    TYPE_HEAD;
     type_t *type;
 } type_ptr_t;
 
 typedef union type
 {
-    struct
-    {
-        type_kind_t kind;
-        string_view_t id;
-    };
+    struct TYPE_BASE;
     type_unknown_t as_unknown;
     type_primitive_t as_primitive;
     type_ptr_t as_ptr;
diff --git a/src/type_checker.c b/src/type_checker.c
index ad51002..34a8d05 100644
--- a/src/type_checker.c
+++ b/src/type_checker.c
@@ -43,29 +43,29 @@ checker_new(arena_t *arena)
 }
 
 static type_t
-type_from_id(string_view_t id)
+type_from_id(string_view_t name)
 {
     type_t type = { 0 };
-    type.id = id;
-    if (string_view_eq_to_cstr(id, "u8")) {
+    type.name = name;
+    if (string_view_eq_to_cstr(name, "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")) {
+    if (string_view_eq_to_cstr(name, "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")) {
+    if (string_view_eq_to_cstr(name, "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")) {
+    if (string_view_eq_to_cstr(name, "u64")) {
         type.kind = TYPE_PRIMITIVE;
         type.as_primitive.size = 8;
         type.as_primitive.kind = TYPE_U64;
@@ -84,7 +84,7 @@ type_resolve(type_t *type)
 {
     switch (type->kind) {
         case TYPE_UNKNOWN:
-            *type = type_from_id(type->as_unknown.id);
+            *type = type_from_id(type->as_unknown.name);
             break;
         case TYPE_PTR:
             type_resolve(type->as_ptr.type);
-- 
2.46.1


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

* [PATCH olang v2 6/6] ast: remove dead code from var_assign ast node
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
                   ` (4 preceding siblings ...)
  2024-10-31  3:13 ` [PATCH olang v2 5/6] type: refactor: rename type.id to type.name Carlos Maniero
@ 2024-10-31  3:13 ` Carlos Maniero
  2024-10-31  3:14   ` [olang/patches/.build.yml] build success builds.sr.ht
  2024-11-01  2:17 ` [PATCH olang v2 0/6] Remove symbol lookups from codegen Johnny Richard
  6 siblings, 1 reply; 9+ messages in thread
From: Carlos Maniero @ 2024-10-31  3:13 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Previously, the var_assign was a ast_node but it was replaced to be an
binop. The previous struct was not removed tho.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/src/ast.h b/src/ast.h
index 316f921..6ca70e9 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -182,13 +182,6 @@ typedef struct ast_unary_op
     ast_node_t *operand;
 } ast_unary_op_t;
 
-typedef struct ast_var_assign_stmt
-{
-    AST_NODE_HEAD;
-    ast_node_t *ref;
-    ast_node_t *value;
-} ast_var_assign_stmt_t;
-
 typedef struct ast_return_stmt
 {
     AST_NODE_HEAD;
@@ -222,7 +215,6 @@ typedef union ast_node
     ast_literal_t as_literal;
     ast_ref_t as_ref;
     ast_block_t as_block;
-    ast_var_assign_stmt_t as_var_assign_stmt;
     ast_return_stmt_t as_return_stmt;
     ast_if_stmt_t as_if_stmt;
     ast_while_stmt_t as_while_stmt;
-- 
2.46.1


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

* [olang/patches/.build.yml] build success
  2024-10-31  3:13 ` [PATCH olang v2 6/6] ast: remove dead code from var_assign ast node Carlos Maniero
@ 2024-10-31  3:14   ` builds.sr.ht
  0 siblings, 0 replies; 9+ messages in thread
From: builds.sr.ht @ 2024-10-31  3:14 UTC (permalink / raw)
  To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel

olang/patches/.build.yml: SUCCESS in 29s

[Remove symbol lookups from codegen][0] v2 from [Carlos Maniero][1]

[0]: https://lists.sr.ht/~johnnyrichard/olang-devel/patches/55719
[1]: mailto:carlos@maniero.me

✓ #1359588 SUCCESS olang/patches/.build.yml https://builds.sr.ht/~johnnyrichard/job/1359588

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

* Re: [PATCH olang v2 0/6] Remove symbol lookups from codegen
  2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
                   ` (5 preceding siblings ...)
  2024-10-31  3:13 ` [PATCH olang v2 6/6] ast: remove dead code from var_assign ast node Carlos Maniero
@ 2024-11-01  2:17 ` Johnny Richard
  6 siblings, 0 replies; 9+ messages in thread
From: Johnny Richard @ 2024-11-01  2:17 UTC (permalink / raw)
  To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel

Thanks! applied.

To git.sr.ht:~johnnyrichard/olang
   f87fb37..9800d80  main -> main


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

end of thread, other threads:[~2024-11-01  0:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-31  3:13 [PATCH olang v2 0/6] Remove symbol lookups from codegen Carlos Maniero
2024-10-31  3:13 ` [PATCH olang v2 1/6] ast: create the ast_ident_t and apply it to var_def and ref Carlos Maniero
2024-10-31  3:13 ` [PATCH olang v2 2/6] semantics: resolve variable symbols Carlos Maniero
2024-10-31  3:13 ` [PATCH olang v2 3/6] semantics: refactor: use the ast_ident_t into the fn_call node Carlos Maniero
2024-10-31  3:13 ` [PATCH olang v2 4/6] semantics: refactor: use the ast_ident_t into the fn_def.params Carlos Maniero
2024-10-31  3:13 ` [PATCH olang v2 5/6] type: refactor: rename type.id to type.name Carlos Maniero
2024-10-31  3:13 ` [PATCH olang v2 6/6] ast: remove dead code from var_assign ast node Carlos Maniero
2024-10-31  3:14   ` [olang/patches/.build.yml] build success builds.sr.ht
2024-11-01  2:17 ` [PATCH olang v2 0/6] Remove symbol lookups from codegen 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