public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
* [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64)
@ 2024-09-22  0:46 Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 1/4] parser: replace type enum to a string view Carlos Maniero
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Carlos Maniero @ 2024-09-22  0:46 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

The olang was supporting only u32 yet there was an inconsistency because
we were always using 8 bytes to store information on stack when u32
actually requires only 4 bytes. We were also using rax for these
operations when 32bits operation should use eax.

This patch enables all unsigned types and use the proper
instruction/register.

--
v2:
- primitive type's size is now computed during the checker step.
- several typos on the commit message
- we no longer walk thought the AST twice during the checker
- rename the *bytes_to_rax* function
- merge the latest two commits once the first one was pretty unfinished
  and had to still use 8 bytes because we were using rax to operate it.

Carlos Maniero (4):
  parser: replace type enum to a string view
  checker: scope: populate symbol's type
  codegen: fix map symbol list type
  codegen: operate mov instructions based on the symbol's type

 src/ast.c                                     |  4 +-
 src/ast.h                                     | 14 ++--
 src/checker.c                                 |  3 +-
 src/codegen_linux_x86_64.c                    | 64 +++++++++++++++----
 src/parser.c                                  | 35 ++++------
 src/pretty_print_ast.c                        |  4 +-
 src/scope.c                                   |  3 +-
 src/scope.h                                   |  4 +-
 src/type.c                                    | 51 +++++++++++++++
 src/type.h                                    | 51 +++++++++++++++
 tests/integration/tests/0001_main_exit.ol     |  2 +-
 tests/integration/tests/0020_if_statement.ol  |  2 +-
 .../integration/tests/0023_else_statement.ol  |  2 +-
 .../integration/tests/0024_var_definition.ol  |  2 +-
 .../tests/0026_primitive_unsigneds.ol         | 27 ++++++++
 tests/unit/parser_test.c                      |  2 +-
 16 files changed, 217 insertions(+), 53 deletions(-)
 create mode 100644 src/type.c
 create mode 100644 src/type.h
 create mode 100644 tests/integration/tests/0026_primitive_unsigneds.ol


base-commit: 0d9ff9cbb463f044c7d482a4045d7668664e0d35
-- 
2.34.1


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

* [PATCH olang v2 1/4] parser: replace type enum to a string view
  2024-09-22  0:46 [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Carlos Maniero
@ 2024-09-22  0:46 ` Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 2/4] checker: scope: populate symbol's type Carlos Maniero
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Carlos Maniero @ 2024-09-22  0:46 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Ensuring the type is correct is a semantics/checker role. Instead of
trying to convert it to an enum on the parser, it just stores the
identifier of the given type.

Once our spec always expects a TOKEN_COLON (:) before the type
identifier, this constraint was moved to the type parser function.

The string_view is enough until we decide how we gonna handle pointers
and arrays.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.c                                     |  4 +--
 src/ast.h                                     | 13 +++----
 src/parser.c                                  | 35 ++++++++-----------
 src/pretty_print_ast.c                        |  4 +--
 tests/integration/tests/0001_main_exit.ol     |  2 +-
 tests/integration/tests/0020_if_statement.ol  |  2 +-
 .../integration/tests/0023_else_statement.ol  |  2 +-
 .../integration/tests/0024_var_definition.ol  |  2 +-
 tests/unit/parser_test.c                      |  2 +-
 9 files changed, 27 insertions(+), 39 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index d2fd2fa..02b938e 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -37,7 +37,7 @@ ast_new_program(arena_t *arena, ast_node_t *fn_def)
 }
 
 ast_node_t *
-ast_new_node_fn_def(arena_t *arena, string_view_t identifier, type_t return_type, ast_node_t *block)
+ast_new_node_fn_def(arena_t *arena, string_view_t identifier, string_view_t return_type, ast_node_t *block)
 {
     ast_node_t *node_fn_def = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t));
     assert(node_fn_def);
@@ -53,7 +53,7 @@ ast_new_node_fn_def(arena_t *arena, string_view_t identifier, type_t return_type
 }
 
 ast_node_t *
-ast_new_node_var_def(arena_t *arena, string_view_t identifier, type_t type, ast_node_t *value)
+ast_new_node_var_def(arena_t *arena, string_view_t identifier, string_view_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);
diff --git a/src/ast.h b/src/ast.h
index a45a271..ff26ed8 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -40,11 +40,6 @@ typedef enum
     AST_NODE_UNKNOWN
 } ast_node_kind_t;
 
-typedef enum
-{
-    TYPE_U32
-} type_t;
-
 typedef struct ast_block
 {
     list_t *nodes;
@@ -58,7 +53,7 @@ typedef struct ast_program
 typedef struct ast_fn_definition
 {
     string_view_t identifier;
-    type_t return_type;
+    string_view_t return_type;
     ast_node_t *block;
     scope_t *scope;
 } ast_fn_definition_t;
@@ -66,7 +61,7 @@ typedef struct ast_fn_definition
 typedef struct ast_var_definition
 {
     string_view_t identifier;
-    type_t type;
+    string_view_t type;
     ast_node_t *value;
     scope_t *scope;
 } ast_var_definition_t;
@@ -154,10 +149,10 @@ ast_node_t *
 ast_new_program(arena_t *arena, ast_node_t *fn_def);
 
 ast_node_t *
-ast_new_node_fn_def(arena_t *arena, string_view_t identifier, type_t return_type, ast_node_t *block);
+ast_new_node_fn_def(arena_t *arena, string_view_t identifier, string_view_t return_type, ast_node_t *block);
 
 ast_node_t *
-ast_new_node_var_def(arena_t *arena, string_view_t identifier, type_t type, ast_node_t *value);
+ast_new_node_var_def(arena_t *arena, string_view_t identifier, string_view_t type, ast_node_t *value);
 
 ast_node_t *
 ast_new_node_bin_op(arena_t *arena, ast_binary_op_kind_t kind, ast_node_t *lhs, ast_node_t *rhs);
diff --git a/src/parser.c b/src/parser.c
index d71500f..e4d0c56 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -34,7 +34,7 @@ static bool
 expected_token(parser_t *parser, token_t *token, token_kind_t kind);
 
 static bool
-parser_parse_type(parser_t *parser, type_t *type);
+parser_parse_type(parser_t *parser, string_view_t *type);
 
 static ast_node_t *
 parser_parse_block(parser_t *parser);
@@ -285,15 +285,7 @@ parser_parse_fn_definition(parser_t *parser)
         return NULL;
     }
 
-    skip_line_feeds(parser->lexer);
-
-    if (!skip_expected_token(parser, TOKEN_COLON)) {
-        return NULL;
-    }
-
-    skip_line_feeds(parser->lexer);
-
-    type_t fn_return_type;
+    string_view_t fn_return_type;
     if (!parser_parse_type(parser, &fn_return_type)) {
         return NULL;
     }
@@ -309,20 +301,25 @@ parser_parse_fn_definition(parser_t *parser)
 }
 
 static bool
-parser_parse_type(parser_t *parser, type_t *type)
+parser_parse_type(parser_t *parser, string_view_t *type)
 {
+    skip_line_feeds(parser->lexer);
+
+    if (!skip_expected_token(parser, TOKEN_COLON)) {
+        return false;
+    }
+
+    skip_line_feeds(parser->lexer);
+
     token_t token;
 
     if (!expected_next_token(parser, &token, TOKEN_IDENTIFIER)) {
         return false;
     }
 
-    if (string_view_eq_to_cstr(token.value, "u32")) {
-        *type = TYPE_U32;
-        return true;
-    }
+    *type = token.value;
 
-    return false;
+    return true;
 }
 
 static ast_node_t *
@@ -469,11 +466,7 @@ parser_parse_var_def(parser_t *parser)
         return NULL;
     }
 
-    if (!skip_expected_token(parser, TOKEN_COLON)) {
-        return NULL;
-    }
-
-    type_t var_type;
+    string_view_t var_type;
     if (!parser_parse_type(parser, &var_type)) {
         return NULL;
     }
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index d6eef67..1fc6dff 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -126,9 +126,9 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
 
             char name[256];
             sprintf(name,
-                    "Function_Definition <name:" SV_FMT "> <return:%d>",
+                    "Function_Definition <name:" SV_FMT "> <return:" SV_FMT ">",
                     SV_ARG(fn_def.identifier),
-                    fn_def.return_type);
+                    SV_ARG(fn_def.return_type));
             node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
             strcpy(node->name, name);
 
diff --git a/tests/integration/tests/0001_main_exit.ol b/tests/integration/tests/0001_main_exit.ol
index f446eb9..9068434 100644
--- a/tests/integration/tests/0001_main_exit.ol
+++ b/tests/integration/tests/0001_main_exit.ol
@@ -24,7 +24,7 @@ fn main(): u32 {
 #
 # TEST test_ast WITH
 # Translation_Unit
-# `-Function_Definition <name:main> <return:0>
+# `-Function_Definition <name:main> <return:u32>
 #   `-Block
 #     `-Return_Statement
 #       `-Literal <kind:u32> <value:0>
diff --git a/tests/integration/tests/0020_if_statement.ol b/tests/integration/tests/0020_if_statement.ol
index d48122f..460a05e 100644
--- a/tests/integration/tests/0020_if_statement.ol
+++ b/tests/integration/tests/0020_if_statement.ol
@@ -29,7 +29,7 @@ fn main(): u32 {
 
 # TEST test_ast WITH
 # Translation_Unit
-# `-Function_Definition <name:main> <return:0>
+# `-Function_Definition <name:main> <return:u32>
 #   `-Block
 #     |-If_Statement
 #     | |-Binary_Operation (==)
diff --git a/tests/integration/tests/0023_else_statement.ol b/tests/integration/tests/0023_else_statement.ol
index fafb22e..f3ddc64 100644
--- a/tests/integration/tests/0023_else_statement.ol
+++ b/tests/integration/tests/0023_else_statement.ol
@@ -31,7 +31,7 @@ fn main(): u32 {
 
 # TEST test_ast WITH
 # Translation_Unit
-# `-Function_Definition <name:main> <return:0>
+# `-Function_Definition <name:main> <return:u32>
 #   `-Block
 #     `-If_Statement
 #       |-Binary_Operation (!=)
diff --git a/tests/integration/tests/0024_var_definition.ol b/tests/integration/tests/0024_var_definition.ol
index 5c23449..ebbcda4 100644
--- a/tests/integration/tests/0024_var_definition.ol
+++ b/tests/integration/tests/0024_var_definition.ol
@@ -28,7 +28,7 @@ fn main(): u32 {
 
 # TEST test_ast WITH
 # Translation_Unit
-# `-Function_Definition <name:main> <return:0>
+# `-Function_Definition <name:main> <return:u32>
 #   `-Block
 #     |-Var_Definition <name:code> <kind:u32>
 #     | `-Literal <kind:u32> <value:0>
diff --git a/tests/unit/parser_test.c b/tests/unit/parser_test.c
index 3cdac41..2256ffd 100644
--- a/tests/unit/parser_test.c
+++ b/tests/unit/parser_test.c
@@ -51,7 +51,7 @@ parse_program_test(const MunitParameter params[], void *user_data_or_fixture)
 
     ast_fn_definition_t fn = program.fn->as_fn_def;
     assert_memory_equal(fn.identifier.size, fn.identifier.chars, "main");
-    assert_uint(fn.return_type, ==, TYPE_U32);
+    assert_memory_equal(fn.return_type.size, fn.return_type.chars, "u32");
 
     ast_node_t *block = fn.block;
     assert_not_null(block);
-- 
2.34.1


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

* [PATCH olang v2 2/4] checker: scope: populate symbol's type
  2024-09-22  0:46 [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 1/4] parser: replace type enum to a string view Carlos Maniero
@ 2024-09-22  0:46 ` Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 3/4] codegen: fix map symbol list type Carlos Maniero
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Carlos Maniero @ 2024-09-22  0:46 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Persisting the symbol type will be very convenient for codegen once it
can be used to determine which register it will use to operate this
type.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/ast.h     |  1 +
 src/checker.c |  3 ++-
 src/scope.c   |  3 ++-
 src/scope.h   |  4 +++-
 src/type.c    | 33 +++++++++++++++++++++++++++++++++
 src/type.h    | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 89 insertions(+), 3 deletions(-)
 create mode 100644 src/type.c
 create mode 100644 src/type.h

diff --git a/src/ast.h b/src/ast.h
index ff26ed8..7cb2ceb 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -23,6 +23,7 @@
 #include "list.h"
 #include "scope.h"
 #include "string_view.h"
+#include "type.h"
 
 typedef struct ast_node ast_node_t;
 
diff --git a/src/checker.c b/src/checker.c
index 3b713f7..6ffdc72 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -107,7 +107,8 @@ 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.identifier;
-            symbol_t *symbol = symbol_new(checker->arena, id);
+
+            symbol_t *symbol = symbol_new(checker->arena, id, type_from_id(ast->as_var_def.type));
 
             scope_insert(scope, symbol);
             ast->as_var_def.scope = scope;
diff --git a/src/scope.c b/src/scope.c
index b23e865..81f610a 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)
+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));
@@ -58,6 +58,7 @@ symbol_new(arena_t *arena, string_view_t id)
         exit(EXIT_FAILURE);
     }
     symbol->id = id;
+    symbol->type = type;
     return symbol;
 }
 
diff --git a/src/scope.h b/src/scope.h
index 7f7eaae..92a5a4f 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -21,10 +21,12 @@
 #include "list.h"
 #include "map.h"
 #include "string_view.h"
+#include "type.h"
 
 typedef struct symbol
 {
     string_view_t id;
+    type_t type;
 } symbol_t;
 
 typedef struct scope
@@ -39,7 +41,7 @@ scope_t *
 scope_new(arena_t *arena);
 
 symbol_t *
-symbol_new(arena_t *arena, string_view_t id);
+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
new file mode 100644
index 0000000..cbdfbde
--- /dev/null
+++ b/src/type.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 olang maintainers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include "type.h"
+#include "assert.h"
+
+type_t
+type_from_id(string_view_t id)
+{
+    type_t type = { 0 };
+    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;
+    }
+
+    // FIXME: handle user defined types
+    assert(0 && "unknown type");
+}
diff --git a/src/type.h b/src/type.h
new file mode 100644
index 0000000..b431171
--- /dev/null
+++ b/src/type.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 olang maintainers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef TYPE_H
+#define TYPE_H
+#include "string_view.h"
+typedef enum
+{
+    TYPE_PRIMITIVE
+} type_kind_t;
+
+typedef enum
+{
+    TYPE_U32
+} type_primitive_kind_t;
+
+typedef struct type_primitive
+{
+    short size;
+    type_primitive_kind_t kind;
+} type_primitive_t;
+
+typedef struct type
+{
+    string_view_t id;
+    type_kind_t kind;
+    union
+    {
+        type_primitive_t as_primitive;
+    };
+} type_t;
+
+type_t
+type_from_id(string_view_t id);
+#endif
-- 
2.34.1


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

* [PATCH olang v2 3/4] codegen: fix map symbol list type
  2024-09-22  0:46 [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 1/4] parser: replace type enum to a string view Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 2/4] checker: scope: populate symbol's type Carlos Maniero
@ 2024-09-22  0:46 ` Carlos Maniero
  2024-09-22  0:46 ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Carlos Maniero
  2024-09-22 14:19 ` [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Johnny Richard
  4 siblings, 0 replies; 8+ messages in thread
From: Carlos Maniero @ 2024-09-22  0:46 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

It was supposed to be an array of pointers.

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/codegen_linux_x86_64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
index 3ce11a7..1fa6c58 100644
--- a/src/codegen_linux_x86_64.c
+++ b/src/codegen_linux_x86_64.c
@@ -426,9 +426,9 @@ calculate_fn_local_size(scope_t *scope)
 
     size_t local_size = 0;
 
-    map_kv_t kvs[scope->symbols->size];
+    map_kv_t *kvs[scope->symbols->size];
 
-    map_get_kvs(scope->symbols, (map_kv_t **)kvs);
+    map_get_kvs(scope->symbols, kvs);
 
     for (size_t i = 0; i < scope->symbols->size; ++i) {
         // FIXME: symbols must have their types. Since we just have 8bytes
-- 
2.34.1


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

* [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type
  2024-09-22  0:46 [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Carlos Maniero
                   ` (2 preceding siblings ...)
  2024-09-22  0:46 ` [PATCH olang v2 3/4] codegen: fix map symbol list type Carlos Maniero
@ 2024-09-22  0:46 ` Carlos Maniero
  2024-09-22  0:47   ` [olang/patches/.build.yml] build success builds.sr.ht
  2024-09-22 14:15   ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Johnny Richard
  2024-09-22 14:19 ` [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Johnny Richard
  4 siblings, 2 replies; 8+ messages in thread
From: Carlos Maniero @ 2024-09-22  0:46 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero

Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
 src/codegen_linux_x86_64.c                    | 60 ++++++++++++++++---
 src/type.c                                    | 18 ++++++
 src/type.h                                    |  5 +-
 .../tests/0026_primitive_unsigneds.ol         | 27 +++++++++
 4 files changed, 100 insertions(+), 10 deletions(-)
 create mode 100644 tests/integration/tests/0026_primitive_unsigneds.ol

diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
index 1fa6c58..25cda2d 100644
--- a/src/codegen_linux_x86_64.c
+++ b/src/codegen_linux_x86_64.c
@@ -26,6 +26,10 @@
 #define SYS_exit (60)
 #define PTR_HEX_CSTR_SIZE (18 + 1)
 
+// The call instruction pushes EIP into stack so the first 8 bytes from stack
+// must be preserved else the ret instruction will jump to nowere.
+#define X86_CALL_EIP_STACK_OFFSET (8)
+
 // FIXME: move label_index to codegen_linux_x86_64_t structure
 size_t label_index;
 
@@ -35,6 +39,12 @@ codegen_linux_x86_64_emit_start_entrypoint(codegen_x86_64_t *codegen);
 static void
 codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_t *fn);
 
+static size_t
+type_to_bytes(type_t *type);
+
+static char *
+get_accumulator_reg_for(size_t bytes);
+
 void
 codegen_linux_x86_64_init(codegen_x86_64_t *codegen, arena_t *arena, FILE *out)
 {
@@ -105,7 +115,10 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr
             size_t *offset = (size_t *)map_get(codegen->symbols_stack_offset, symbol_ptr);
             assert(offset);
 
-            fprintf(codegen->out, "    mov -%ld(%%rbp), %%rax\n", *offset);
+            fprintf(codegen->out,
+                    "    mov -%ld(%%rbp), %s\n",
+                    *offset,
+                    get_accumulator_reg_for(type_to_bytes(&symbol->type)));
             return;
         }
         case AST_NODE_BINARY_OP: {
@@ -366,12 +379,18 @@ 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);
                 }
 
-                codegen->base_offset += 8;
                 size_t *offset = arena_alloc(codegen->arena, sizeof(size_t));
                 *offset = codegen->base_offset;
 
                 map_put(codegen->symbols_stack_offset, symbol_ptr, offset);
-                fprintf(codegen->out, "    mov %%rax, -%ld(%%rbp)\n", codegen->base_offset);
+
+                size_t type_size = type_to_bytes(&symbol->type);
+
+                fprintf(codegen->out,
+                        "    mov %s, -%ld(%%rbp)\n",
+                        get_accumulator_reg_for(type_size),
+                        codegen->base_offset);
+                codegen->base_offset += type_size;
 
                 break;
             }
@@ -419,6 +438,18 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
     codegen->base_offset = block_offset;
 }
 
+static size_t
+type_to_bytes(type_t *type)
+{
+    switch (type->kind) {
+        case TYPE_PRIMITIVE: {
+            return type->as_primitive.size;
+        }
+    }
+
+    assert(0 && "unreachable");
+}
+
 static size_t
 calculate_fn_local_size(scope_t *scope)
 {
@@ -431,9 +462,8 @@ calculate_fn_local_size(scope_t *scope)
     map_get_kvs(scope->symbols, kvs);
 
     for (size_t i = 0; i < scope->symbols->size; ++i) {
-        // FIXME: symbols must have their types. Since we just have 8bytes
-        //        variables it is hard coded.
-        local_size += 8;
+        symbol_t *symbol = (symbol_t *)kvs[i]->value;
+        local_size += type_to_bytes(&symbol->type);
     }
 
     size_t max_child_local_size = 0;
@@ -456,7 +486,8 @@ calculate_fn_local_size(scope_t *scope)
 static void
 codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_t *fn)
 {
-    codegen->base_offset = 0;
+    codegen->base_offset = X86_CALL_EIP_STACK_OFFSET;
+
     ast_node_t *block_node = fn->block;
     fprintf(codegen->out, "" SV_FMT ":\n", SV_ARG(fn->identifier));
 
@@ -464,8 +495,6 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_
 
     size_t local_size = calculate_fn_local_size(fn->scope);
 
-    // TODO: get the local_size from function scope
-
     if (local_size != 0) {
         fprintf(codegen->out, "    sub $%ld, %%rsp\n", local_size);
     }
@@ -475,3 +504,16 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_
 
     codegen_linux_x86_64_emit_block(codegen, &block);
 }
+
+static char *
+get_accumulator_reg_for(size_t bytes)
+{
+    if (bytes <= 1) {
+        return "%ah";
+    } else if (bytes <= 2) {
+        return "%ax";
+    } else if (bytes <= 4) {
+        return "%eax";
+    }
+    return "%rax";
+}
diff --git a/src/type.c b/src/type.c
index cbdfbde..64147a2 100644
--- a/src/type.c
+++ b/src/type.c
@@ -21,12 +21,30 @@ type_t
 type_from_id(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;
+    }
 
     // FIXME: handle user defined types
     assert(0 && "unknown type");
diff --git a/src/type.h b/src/type.h
index b431171..1da3a11 100644
--- a/src/type.h
+++ b/src/type.h
@@ -24,7 +24,10 @@ typedef enum
 
 typedef enum
 {
-    TYPE_U32
+    TYPE_U8,
+    TYPE_U16,
+    TYPE_U32,
+    TYPE_U64
 } type_primitive_kind_t;
 
 typedef struct type_primitive
diff --git a/tests/integration/tests/0026_primitive_unsigneds.ol b/tests/integration/tests/0026_primitive_unsigneds.ol
new file mode 100644
index 0000000..25f0f7e
--- /dev/null
+++ b/tests/integration/tests/0026_primitive_unsigneds.ol
@@ -0,0 +1,27 @@
+# Copyright (C) 2024 olang mantainers
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+fn main(): u64 {
+  var a: u8 = 255
+  var b: u16 = 65535
+  var c: u32 = 4294967295
+  var d: u64 = 4294967296
+
+  return a + b + c + d - a - b - c - d
+}
+
+# TEST test_compile(exit_code=0)
+
+# TEST test_run_binary(exit_code=0)
-- 
2.34.1


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

* [olang/patches/.build.yml] build success
  2024-09-22  0:46 ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Carlos Maniero
@ 2024-09-22  0:47   ` builds.sr.ht
  2024-09-22 14:15   ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Johnny Richard
  1 sibling, 0 replies; 8+ messages in thread
From: builds.sr.ht @ 2024-09-22  0:47 UTC (permalink / raw)
  To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel

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

[extend unsined integers types (u8, u16, u64)][0] v2 from [Carlos Maniero][1]

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

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

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

* Re: [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type
  2024-09-22  0:46 ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Carlos Maniero
  2024-09-22  0:47   ` [olang/patches/.build.yml] build success builds.sr.ht
@ 2024-09-22 14:15   ` Johnny Richard
  1 sibling, 0 replies; 8+ messages in thread
From: Johnny Richard @ 2024-09-22 14:15 UTC (permalink / raw)
  To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel

Great work! Pretty solid patch!

On Sun, Sep 22, 2024 at 12:46:43AM GMT, Carlos Maniero wrote:
> Signed-off-by: Carlos Maniero <carlos@maniero.me>
> ---
>  src/codegen_linux_x86_64.c                    | 60 ++++++++++++++++---
>  src/type.c                                    | 18 ++++++
>  src/type.h                                    |  5 +-
>  .../tests/0026_primitive_unsigneds.ol         | 27 +++++++++
>  4 files changed, 100 insertions(+), 10 deletions(-)
>  create mode 100644 tests/integration/tests/0026_primitive_unsigneds.ol
> 
> diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
> index 1fa6c58..25cda2d 100644
> --- a/src/codegen_linux_x86_64.c
> +++ b/src/codegen_linux_x86_64.c
> @@ -26,6 +26,10 @@
>  #define SYS_exit (60)
>  #define PTR_HEX_CSTR_SIZE (18 + 1)
>  
> +// The call instruction pushes EIP into stack so the first 8 bytes from stack
> +// must be preserved else the ret instruction will jump to nowere.
> +#define X86_CALL_EIP_STACK_OFFSET (8)

Nice improvement here as well!


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

* Re: [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64)
  2024-09-22  0:46 [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Carlos Maniero
                   ` (3 preceding siblings ...)
  2024-09-22  0:46 ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Carlos Maniero
@ 2024-09-22 14:19 ` Johnny Richard
  4 siblings, 0 replies; 8+ messages in thread
From: Johnny Richard @ 2024-09-22 14:19 UTC (permalink / raw)
  To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel

Super kudos for this work, thanks! Applied!

To git.sr.ht:~johnnyrichard/olang
   0d9ff9c..e35d883  main -> main



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

end of thread, other threads:[~2024-09-22 14:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-09-22  0:46 [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) Carlos Maniero
2024-09-22  0:46 ` [PATCH olang v2 1/4] parser: replace type enum to a string view Carlos Maniero
2024-09-22  0:46 ` [PATCH olang v2 2/4] checker: scope: populate symbol's type Carlos Maniero
2024-09-22  0:46 ` [PATCH olang v2 3/4] codegen: fix map symbol list type Carlos Maniero
2024-09-22  0:46 ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Carlos Maniero
2024-09-22  0:47   ` [olang/patches/.build.yml] build success builds.sr.ht
2024-09-22 14:15   ` [PATCH olang v2 4/4] codegen: operate mov instructions based on the symbol's type Johnny Richard
2024-09-22 14:19 ` [PATCH olang v2 0/4] extend unsined integers types (u8, u16, u64) 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