public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
* [PATCH olang v1 0/3] compiler: enable full compilation for vars
@ 2024-09-21  0:20 Johnny Richard
  2024-09-21  0:20 ` [PATCH olang v1 1/3] scope: create scope data structure Johnny Richard
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Johnny Richard @ 2024-09-21  0:20 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

The variables are consts and need more work to get fully functional.
This first patchset is a beginning of the work.

Johnny Richard (3):
  scope: create scope data structure
  checker: create checker and populate scope on ast nodes
  codegen: add support scopes and symbols lookups for var

 src/ast.h                                     |   4 +
 src/checker.c                                 | 125 +++++++
 src/checker.h                                 |  34 ++
 src/codegen_linux_x86_64.c                    | 347 ++++++++++--------
 src/codegen_linux_x86_64.h                    |  16 +-
 src/main.c                                    |  12 +-
 src/scope.c                                   | 101 +++++
 src/scope.h                                   |  54 +++
 .../integration/tests/0024_var_definition.ol  |   4 +
 9 files changed, 551 insertions(+), 146 deletions(-)
 create mode 100644 src/checker.c
 create mode 100644 src/checker.h
 create mode 100644 src/scope.c
 create mode 100644 src/scope.h


base-commit: 29cc9fc4a69e74987a1b6c216ff701a9eaf379b3
-- 
2.46.0


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

* [PATCH olang v1 1/3] scope: create scope data structure
  2024-09-21  0:20 [PATCH olang v1 0/3] compiler: enable full compilation for vars Johnny Richard
@ 2024-09-21  0:20 ` Johnny Richard
  2024-09-21  0:20 ` [PATCH olang v1 2/3] checker: create checker and populate scope on ast nodes Johnny Richard
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Johnny Richard @ 2024-09-21  0:20 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
---
 src/scope.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/scope.h |  54 ++++++++++++++++++++++++++++
 2 files changed, 155 insertions(+)
 create mode 100644 src/scope.c
 create mode 100644 src/scope.h

diff --git a/src/scope.c b/src/scope.c
new file mode 100644
index 0000000..3271856
--- /dev/null
+++ b/src/scope.c
@@ -0,0 +1,101 @@
+/*
+ * 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 <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scope.h"
+
+scope_t *
+scope_new(arena_t *arena)
+{
+    assert(arena);
+    scope_t *scope = (scope_t *)arena_alloc(arena, sizeof(scope_t));
+    if (scope == NULL) {
+        fprintf(stderr, "[FATAL] Out of memory: scope_new: %s\n", strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+    scope->arena = arena;
+    scope->symbols = map_new(arena);
+    return scope;
+}
+
+symbol_t *
+symbol_new(arena_t *arena, string_view_t id)
+{
+    assert(arena);
+    symbol_t *symbol = (symbol_t *)arena_alloc(arena, sizeof(symbol_t));
+    if (symbol == NULL) {
+        fprintf(stderr, "[FATAL] Out of memory: symbol_new: %s\n", strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+    symbol->id = id;
+    return symbol;
+}
+
+symbol_t *
+scope_lookup(scope_t *scope, string_view_t id)
+{
+    assert(scope);
+    while (scope != NULL) {
+
+        char cstr_id[id.size + 1];
+        cstr_id[id.size] = 0;
+        memcpy(cstr_id, id.chars, id.size);
+
+        symbol_t *symbol = (symbol_t *)map_get(scope->symbols, cstr_id);
+        if (symbol != NULL) {
+            return symbol;
+        }
+        scope = scope->parent;
+    }
+    return NULL;
+}
+
+void
+scope_insert(scope_t *scope, symbol_t *symbol)
+{
+    assert(scope);
+    assert(symbol);
+
+    char id[symbol->id.size + 1];
+    id[symbol->id.size] = 0;
+    memcpy(id, symbol->id.chars, symbol->id.size);
+
+    map_put(scope->symbols, id, symbol);
+}
+
+scope_t *
+scope_push(scope_t *scope)
+{
+    assert(scope);
+
+    scope_t *child = scope_new(scope->arena);
+    child->parent = scope;
+
+    return child;
+}
+
+scope_t *
+scope_pop(scope_t *scope)
+{
+    assert(scope);
+    assert(scope->parent);
+    return scope->parent;
+}
diff --git a/src/scope.h b/src/scope.h
new file mode 100644
index 0000000..ddb0cd0
--- /dev/null
+++ b/src/scope.h
@@ -0,0 +1,54 @@
+/*
+ * 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 SCOPE_H
+#define SCOPE_H
+
+#include "arena.h"
+#include "map.h"
+#include "string_view.h"
+
+typedef struct symbol
+{
+    string_view_t id;
+} symbol_t;
+
+typedef struct scope
+{
+    struct scope *parent;
+    arena_t *arena;
+    map_t *symbols;
+} scope_t;
+
+scope_t *
+scope_new(arena_t *arena);
+
+symbol_t *
+symbol_new(arena_t *arena, string_view_t id);
+
+symbol_t *
+scope_lookup(scope_t *scope, string_view_t id);
+
+void
+scope_insert(scope_t *scope, symbol_t *symbol);
+
+scope_t *
+scope_push(scope_t *scope);
+
+scope_t *
+scope_pop(scope_t *scope);
+
+#endif /* SCOPE_H */
-- 
2.46.0


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

* [PATCH olang v1 2/3] checker: create checker and populate scope on ast nodes
  2024-09-21  0:20 [PATCH olang v1 0/3] compiler: enable full compilation for vars Johnny Richard
  2024-09-21  0:20 ` [PATCH olang v1 1/3] scope: create scope data structure Johnny Richard
@ 2024-09-21  0:20 ` Johnny Richard
  2024-09-21  0:20 ` [PATCH olang v1 3/3] codegen: add support scopes and symbols lookups for var Johnny Richard
  2024-09-21  0:59 ` [PATCH olang v1 0/3] compiler: enable full compilation for vars Carlos Maniero
  3 siblings, 0 replies; 6+ messages in thread
From: Johnny Richard @ 2024-09-21  0:20 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

The checker will check semantic analysis in the future, now we want to
focus on create the scope (symbol table) and attach to a couple of ast
nodes.

We want the scope to be accessible from the ast nodes to easily resolve
scope on the next compiler pipeline steps.

Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
---
 src/ast.h     |   4 ++
 src/checker.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/checker.h |  34 ++++++++++++++
 src/main.c    |   4 ++
 4 files changed, 167 insertions(+)
 create mode 100644 src/checker.c
 create mode 100644 src/checker.h

diff --git a/src/ast.h b/src/ast.h
index 94ee6b4..7d065c6 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -21,6 +21,7 @@
 
 #include "arena.h"
 #include "list.h"
+#include "scope.h"
 #include "string_view.h"
 
 typedef struct ast_node ast_node_t;
@@ -66,6 +67,7 @@ typedef struct ast_var_definition
     string_view_t identifier;
     type_t type;
     ast_node_t *value;
+    scope_t *scope;
 } ast_var_definition_t;
 
 typedef enum
@@ -85,6 +87,7 @@ typedef struct ast_literal
 typedef struct ast_ref
 {
     string_view_t identifier;
+    scope_t *scope;
 } ast_ref_t;
 
 typedef enum ast_binary_op_kind
@@ -118,6 +121,7 @@ typedef struct ast_binary_op
 
 typedef struct ast_return_stmt
 {
+    // FIXME: rename to a meaningful name like expr
     ast_node_t *data;
 } ast_return_stmt_t;
 
diff --git a/src/checker.c b/src/checker.c
new file mode 100644
index 0000000..5925158
--- /dev/null
+++ b/src/checker.c
@@ -0,0 +1,125 @@
+/*
+ * 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 "checker.h"
+#include "scope.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+
+static void
+populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast);
+
+checker_t *
+checker_new(arena_t *arena)
+{
+    assert(arena);
+
+    checker_t *checker = (checker_t *)arena_alloc(arena, sizeof(checker_t));
+    if (checker == NULL) {
+        fprintf(stderr, "[FATAL] Out of memory: checker_new: %s\n", strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+    checker->arena = arena;
+    return checker;
+}
+
+void
+checker_check(checker_t *checker, ast_node_t *ast)
+{
+    assert(checker);
+    assert(ast);
+
+    scope_t *scope = scope_new(checker->arena);
+    populate_scope(checker, scope, ast);
+
+    // TODO: traverse the ast tree to verify semantics
+}
+
+static void
+populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
+{
+    switch (ast->kind) {
+        case AST_NODE_PROGRAM: {
+            populate_scope(checker, scope, ast->as_program.fn);
+            return;
+        }
+
+        case AST_NODE_FN_DEF: {
+            // FIXME: insert function symbol to scope
+            populate_scope(checker, scope, ast->as_fn_def.block);
+            return;
+        }
+
+        case AST_NODE_IF_STMT: {
+            populate_scope(checker, scope, ast->as_if_stmt.cond);
+            populate_scope(checker, scope, ast->as_if_stmt.then);
+
+            if (ast->as_if_stmt._else) {
+                populate_scope(checker, scope, ast->as_if_stmt._else);
+            }
+
+            return;
+        }
+
+        case AST_NODE_BINARY_OP: {
+            ast_binary_op_t bin_op = ast->as_bin_op;
+
+            populate_scope(checker, scope, bin_op.lhs);
+            populate_scope(checker, scope, bin_op.rhs);
+            return;
+        }
+
+        case AST_NODE_RETURN_STMT: {
+            ast_return_stmt_t return_stmt = ast->as_return_stmt;
+
+            populate_scope(checker, scope, return_stmt.data);
+            return;
+        }
+
+        case AST_NODE_BLOCK: {
+            ast_block_t block = ast->as_block;
+            scope = scope_push(scope);
+
+            list_item_t *item = list_head(block.nodes);
+
+            while (item != NULL) {
+                populate_scope(checker, scope, (ast_node_t *)item->value);
+                item = list_next(item);
+            }
+
+            return;
+        }
+
+        case AST_NODE_VAR_DEF: {
+            string_view_t id = ast->as_var_def.identifier;
+            symbol_t *symbol = symbol_new(checker->arena, id);
+
+            scope_insert(scope, symbol);
+            ast->as_var_def.scope = scope;
+            return;
+        }
+
+        case AST_NODE_REF: {
+            ast->as_ref.scope = scope;
+            return;
+        }
+
+        case AST_NODE_LITERAL:
+        case AST_NODE_UNKNOWN:
+            return;
+    }
+}
diff --git a/src/checker.h b/src/checker.h
new file mode 100644
index 0000000..681f405
--- /dev/null
+++ b/src/checker.h
@@ -0,0 +1,34 @@
+/*
+ * 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 CHECKER_H
+#define CHECKER_H
+
+#include "arena.h"
+#include "ast.h"
+
+typedef struct checker
+{
+    arena_t *arena;
+} checker_t;
+
+checker_t *
+checker_new(arena_t *arena);
+
+void
+checker_check(checker_t *checker, ast_node_t *ast);
+
+#endif /* CHECKER_H */
diff --git a/src/main.c b/src/main.c
index 030f34c..810bf2d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include "arena.h"
+#include "checker.h"
 #include "cli.h"
 #include "codegen_linux_aarch64.h"
 #include "codegen_linux_x86_64.h"
@@ -136,6 +137,9 @@ handle_codegen_linux(cli_opts_t *opts)
 
     ast_node_t *ast = parser_parse_program(&parser);
 
+    checker_t *checker = checker_new(&arena);
+    checker_check(checker, ast);
+
     char asm_file[opts->output_bin.size + 3];
     sprintf(asm_file, "" SV_FMT ".s", SV_ARG(opts->output_bin));
 
-- 
2.46.0


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

* [PATCH olang v1 3/3] codegen: add support scopes and symbols lookups for var
  2024-09-21  0:20 [PATCH olang v1 0/3] compiler: enable full compilation for vars Johnny Richard
  2024-09-21  0:20 ` [PATCH olang v1 1/3] scope: create scope data structure Johnny Richard
  2024-09-21  0:20 ` [PATCH olang v1 2/3] checker: create checker and populate scope on ast nodes Johnny Richard
@ 2024-09-21  0:20 ` Johnny Richard
  2024-09-21  0:23   ` [olang/patches/.build.yml] build success builds.sr.ht
  2024-09-21  0:59 ` [PATCH olang v1 0/3] compiler: enable full compilation for vars Carlos Maniero
  3 siblings, 1 reply; 6+ messages in thread
From: Johnny Richard @ 2024-09-21  0:20 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

It introduces a new struct designed to maintain the stack offset for
local variables. This data structure facilitates the sharing of state
between function calls, including essential information such as the FILE
*out pointer.

Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
---
 src/codegen_linux_x86_64.c                    | 347 ++++++++++--------
 src/codegen_linux_x86_64.h                    |  16 +-
 src/main.c                                    |   8 +-
 .../integration/tests/0024_var_definition.ol  |   4 +
 4 files changed, 229 insertions(+), 146 deletions(-)

diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
index 8ed127c..4e0ea52 100644
--- a/src/codegen_linux_x86_64.c
+++ b/src/codegen_linux_x86_64.c
@@ -20,22 +20,38 @@
 
 #include "codegen_linux_x86_64.h"
 #include "list.h"
+#include "map.h"
+#include "scope.h"
 
 #define SYS_exit (60)
+#define PTR_HEX_CSTR_SIZE (18 + 1)
 
+// FIXME: move label_index to codegen_linux_x86_64_t structure
 size_t label_index;
 
 static void
-codegen_linux_x86_64_emit_start_entrypoint(FILE *out);
+codegen_linux_x86_64_emit_start_entrypoint(codegen_x86_64_t *codegen);
 
 static void
-codegen_linux_x86_64_emit_function(FILE *out, ast_fn_definition_t *fn);
+codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_t *fn);
 
 void
-codegen_linux_x86_64_emit_program(FILE *out, ast_node_t *node)
+codegen_linux_x86_64_init(codegen_x86_64_t *codegen, arena_t *arena, FILE *out)
+{
+    assert(codegen);
+    assert(arena);
+    assert(codegen);
+    codegen->base_offset = 0;
+    codegen->symbols_stack_offset = map_new(arena);
+    codegen->out = out;
+    codegen->arena = arena;
+}
+
+void
+codegen_linux_x86_64_emit_program(codegen_x86_64_t *codegen, ast_node_t *node)
 {
     label_index = 0;
-    codegen_linux_x86_64_emit_start_entrypoint(out);
+    codegen_linux_x86_64_emit_start_entrypoint(codegen);
 
     assert(node->kind == AST_NODE_PROGRAM);
     ast_program_t program = node->as_program;
@@ -43,20 +59,20 @@ codegen_linux_x86_64_emit_program(FILE *out, ast_node_t *node)
     ast_fn_definition_t fn = program.fn->as_fn_def;
 
     assert(string_view_eq_to_cstr(fn.identifier, "main"));
-    codegen_linux_x86_64_emit_function(out, &fn);
+    codegen_linux_x86_64_emit_function(codegen, &fn);
 }
 
 static void
-codegen_linux_x86_64_emit_start_entrypoint(FILE *out)
+codegen_linux_x86_64_emit_start_entrypoint(codegen_x86_64_t *codegen)
 {
-    fprintf(out, ".text\n");
-    fprintf(out, ".globl _start\n\n");
-
-    fprintf(out, "_start:\n");
-    fprintf(out, "    call main\n");
-    fprintf(out, "    mov %%eax, %%edi\n");
-    fprintf(out, "    mov $%d, %%eax\n", SYS_exit);
-    fprintf(out, "    syscall\n");
+    fprintf(codegen->out, ".text\n");
+    fprintf(codegen->out, ".globl _start\n\n");
+
+    fprintf(codegen->out, "_start:\n");
+    fprintf(codegen->out, "    call main\n");
+    fprintf(codegen->out, "    mov %%eax, %%edi\n");
+    fprintf(codegen->out, "    mov $%d, %%eax\n", SYS_exit);
+    fprintf(codegen->out, "    syscall\n");
 }
 
 static size_t
@@ -66,7 +82,7 @@ codegen_linux_x86_64_get_next_label(void)
 }
 
 static void
-codegen_linux_x86_64_emit_expression(FILE *out, ast_node_t *expr_node)
+codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node)
 {
     switch (expr_node->kind) {
         case AST_NODE_LITERAL: {
@@ -74,200 +90,215 @@ codegen_linux_x86_64_emit_expression(FILE *out, ast_node_t *expr_node)
             assert(literal_u32.kind == AST_LITERAL_U32);
             uint32_t n = literal_u32.as_u32;
 
-            fprintf(out, "    mov $%d, %%rax\n", n);
+            fprintf(codegen->out, "    mov $%d, %%rax\n", n);
+            return;
+        }
+        case AST_NODE_REF: {
+            ast_ref_t ref = expr_node->as_ref;
+
+            symbol_t *symbol = scope_lookup(ref.scope, ref.identifier);
+            assert(symbol);
+
+            char symbol_ptr[PTR_HEX_CSTR_SIZE];
+            sprintf(symbol_ptr, "%p", (void *)symbol);
+
+            size_t *offset = (size_t *)map_get(codegen->symbols_stack_offset, symbol_ptr);
+            assert(offset);
+
+            fprintf(codegen->out, "    mov -%ld(%%rbp), %%rax\n", *offset);
             return;
         }
         case AST_NODE_BINARY_OP: {
             ast_binary_op_t bin_op = expr_node->as_bin_op;
             switch (bin_op.kind) {
                 case AST_BINOP_ADDITION: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    add %%rcx, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    add %%rcx, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_MULTIPLICATION: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    mul %%rcx\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    mul %%rcx\n");
 
                     return;
                 }
                 case AST_BINOP_DIVISION: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    xor %%rdx, %%rdx\n");
-                    fprintf(out, "    div %%rcx\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    xor %%rdx, %%rdx\n");
+                    fprintf(codegen->out, "    div %%rcx\n");
 
                     return;
                 }
                 case AST_BINOP_REMINDER: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
-                    fprintf(out, "    xor %%edx, %%edx\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
+                    fprintf(codegen->out, "    xor %%edx, %%edx\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    xor %%rdx, %%rdx\n");
-                    fprintf(out, "    div %%rcx\n");
-                    fprintf(out, "    mov %%edx, %%eax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    xor %%rdx, %%rdx\n");
+                    fprintf(codegen->out, "    div %%rcx\n");
+                    fprintf(codegen->out, "    mov %%edx, %%eax\n");
 
                     return;
                 }
                 case AST_BINOP_SUBTRACTION: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    sub %%rcx, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    sub %%rcx, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_CMP_EQ: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    cmp %%rcx, %%rax\n");
-                    fprintf(out, "    sete %%al\n");
-                    fprintf(out, "    movzb %%al, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    cmp %%rcx, %%rax\n");
+                    fprintf(codegen->out, "    sete %%al\n");
+                    fprintf(codegen->out, "    movzb %%al, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_CMP_LT: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    cmp %%rcx, %%rax\n");
-                    fprintf(out, "    setl %%al\n");
-                    fprintf(out, "    movzb %%al, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    cmp %%rcx, %%rax\n");
+                    fprintf(codegen->out, "    setl %%al\n");
+                    fprintf(codegen->out, "    movzb %%al, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_CMP_GT: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    cmp %%rcx, %%rax\n");
-                    fprintf(out, "    setg %%al\n");
-                    fprintf(out, "    movzb %%al, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    cmp %%rcx, %%rax\n");
+                    fprintf(codegen->out, "    setg %%al\n");
+                    fprintf(codegen->out, "    movzb %%al, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_CMP_NEQ: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    cmp %%rcx, %%rax\n");
-                    fprintf(out, "    setne %%al\n");
-                    fprintf(out, "    movzb %%al, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    cmp %%rcx, %%rax\n");
+                    fprintf(codegen->out, "    setne %%al\n");
+                    fprintf(codegen->out, "    movzb %%al, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_CMP_LEQ: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    cmp %%rcx, %%rax\n");
-                    fprintf(out, "    setle %%al\n");
-                    fprintf(out, "    movzb %%al, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    cmp %%rcx, %%rax\n");
+                    fprintf(codegen->out, "    setle %%al\n");
+                    fprintf(codegen->out, "    movzb %%al, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_CMP_GEQ: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    cmp %%rcx, %%rax\n");
-                    fprintf(out, "    setge %%al\n");
-                    fprintf(out, "    movzb %%al, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    cmp %%rcx, %%rax\n");
+                    fprintf(codegen->out, "    setge %%al\n");
+                    fprintf(codegen->out, "    movzb %%al, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_BITWISE_LSHIFT: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    shl %%cl, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    shl %%cl, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_BITWISE_RSHIFT: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    shr %%cl, %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    shr %%cl, %%rax\n");
 
                     return;
                 }
                 case AST_BINOP_BITWISE_XOR: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    xor %%ecx, %%eax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    xor %%ecx, %%eax\n");
 
                     return;
                 }
                 case AST_BINOP_BITWISE_AND: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    and %%ecx, %%eax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    and %%ecx, %%eax\n");
 
                     return;
                 }
                 case AST_BINOP_BITWISE_OR: {
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    push %%rax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    push %%rax\n");
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    pop %%rcx\n");
-                    fprintf(out, "    or %%ecx, %%eax\n");
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    pop %%rcx\n");
+                    fprintf(codegen->out, "    or %%ecx, %%eax\n");
 
                     return;
                 }
                 case AST_BINOP_LOGICAL_AND: {
                     size_t label_exit = codegen_linux_x86_64_get_next_label();
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    cmp $0, %%rax\n");
-                    fprintf(out, "    je .L%ld\n", label_exit);
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    cmp $0, %%rax\n");
+                    fprintf(codegen->out, "    je .L%ld\n", label_exit);
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    cmp $0, %%rax\n");
-                    fprintf(out, "    je .L%ld\n", label_exit);
-                    fprintf(out, "    mov $1, %%rax\n");
-                    fprintf(out, ".L%ld:\n", label_exit);
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    cmp $0, %%rax\n");
+                    fprintf(codegen->out, "    je .L%ld\n", label_exit);
+                    fprintf(codegen->out, "    mov $1, %%rax\n");
+                    fprintf(codegen->out, ".L%ld:\n", label_exit);
 
                     return;
                 }
@@ -275,17 +306,17 @@ codegen_linux_x86_64_emit_expression(FILE *out, ast_node_t *expr_node)
                     size_t label_t = codegen_linux_x86_64_get_next_label();
                     size_t label_f = codegen_linux_x86_64_get_next_label();
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.lhs);
-                    fprintf(out, "    cmp $0, %%rax\n");
-                    fprintf(out, "    jne .L%ld\n", label_t);
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs);
+                    fprintf(codegen->out, "    cmp $0, %%rax\n");
+                    fprintf(codegen->out, "    jne .L%ld\n", label_t);
 
-                    codegen_linux_x86_64_emit_expression(out, bin_op.rhs);
-                    fprintf(out, "    cmp $0, %%rax\n");
-                    fprintf(out, "    je .L%ld\n", label_f);
+                    codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs);
+                    fprintf(codegen->out, "    cmp $0, %%rax\n");
+                    fprintf(codegen->out, "    je .L%ld\n", label_f);
 
-                    fprintf(out, ".L%ld:\n", label_t);
-                    fprintf(out, "    mov $1, %%rax\n");
-                    fprintf(out, ".L%ld:\n", label_f);
+                    fprintf(codegen->out, ".L%ld:\n", label_t);
+                    fprintf(codegen->out, "    mov $1, %%rax\n");
+                    fprintf(codegen->out, ".L%ld:\n", label_f);
 
                     return;
                 }
@@ -300,7 +331,7 @@ codegen_linux_x86_64_emit_expression(FILE *out, ast_node_t *expr_node)
     }
 }
 static void
-codegen_linux_x86_64_emit_block(FILE *out, ast_block_t *block)
+codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
 {
 
     size_t nodes_len = list_size(block->nodes);
@@ -313,12 +344,37 @@ codegen_linux_x86_64_emit_block(FILE *out, ast_block_t *block)
 
                 ast_node_t *expr = return_stmt.data;
 
-                codegen_linux_x86_64_emit_expression(out, expr);
+                codegen_linux_x86_64_emit_expression(codegen, expr);
+
+                fprintf(codegen->out, "    ret\n");
 
-                fprintf(out, "    ret\n");
+                break;
+            }
+
+            case AST_NODE_VAR_DEF: {
+                ast_var_definition_t var_def = node->as_var_def;
+                scope_t *scope = var_def.scope;
+
+                symbol_t *symbol = scope_lookup(scope, var_def.identifier);
+                assert(symbol);
+
+                char symbol_ptr[PTR_HEX_CSTR_SIZE];
+                sprintf(symbol_ptr, "%p", (void *)symbol);
+
+                if (var_def.value) {
+                    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);
 
                 break;
             }
+
             case AST_NODE_IF_STMT: {
                 ast_if_stmt_t if_stmt = node->as_if_stmt;
 
@@ -329,28 +385,30 @@ codegen_linux_x86_64_emit_block(FILE *out, ast_block_t *block)
                 size_t end_if_label = codegen_linux_x86_64_get_next_label();
                 size_t end_else_label = codegen_linux_x86_64_get_next_label();
 
-                codegen_linux_x86_64_emit_expression(out, cond);
-                fprintf(out, "    cmp $1, %%rax\n");
-                fprintf(out, "    jnz .L%ld\n", end_if_label);
+                codegen_linux_x86_64_emit_expression(codegen, cond);
+                fprintf(codegen->out, "    cmp $1, %%rax\n");
+                fprintf(codegen->out, "    jnz .L%ld\n", end_if_label);
 
                 assert(then->kind == AST_NODE_BLOCK && "invalid if-then block");
                 ast_block_t then_block = then->as_block;
 
-                codegen_linux_x86_64_emit_block(out, &then_block);
-                fprintf(out, "    jmp .L%ld\n", end_else_label);
+                codegen_linux_x86_64_emit_block(codegen, &then_block);
+                fprintf(codegen->out, "    jmp .L%ld\n", end_else_label);
 
-                fprintf(out, ".L%ld:\n", end_if_label);
+                fprintf(codegen->out, ".L%ld:\n", end_if_label);
 
                 if (_else != NULL) {
                     ast_block_t else_block = _else->as_block;
-                    codegen_linux_x86_64_emit_block(out, &else_block);
+                    codegen_linux_x86_64_emit_block(codegen, &else_block);
                 }
 
-                fprintf(out, ".L%ld:\n", end_else_label);
+                fprintf(codegen->out, ".L%ld:\n", end_else_label);
 
                 break;
             }
             default: {
+                // FIXME: improve error: replace the node->kind to a string representation
+                fprintf(stderr, "node kind %d not supported\n", node->kind);
                 assert(0 && "unsupported block statement");
                 break;
             }
@@ -359,13 +417,16 @@ codegen_linux_x86_64_emit_block(FILE *out, ast_block_t *block)
 }
 
 static void
-codegen_linux_x86_64_emit_function(FILE *out, ast_fn_definition_t *fn)
+codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_t *fn)
 {
+    codegen->base_offset = 0;
     ast_node_t *block_node = fn->block;
-    fprintf(out, "" SV_FMT ":\n", SV_ARG(fn->identifier));
+    fprintf(codegen->out, "" SV_FMT ":\n", SV_ARG(fn->identifier));
+
+    fprintf(codegen->out, "    mov %%rsp, %%rbp\n");
 
     assert(block_node->kind == AST_NODE_BLOCK);
     ast_block_t block = block_node->as_block;
 
-    codegen_linux_x86_64_emit_block(out, &block);
+    codegen_linux_x86_64_emit_block(codegen, &block);
 }
diff --git a/src/codegen_linux_x86_64.h b/src/codegen_linux_x86_64.h
index 2050c91..cad530a 100644
--- a/src/codegen_linux_x86_64.h
+++ b/src/codegen_linux_x86_64.h
@@ -17,9 +17,23 @@
 #ifndef CODEGEN_X86_64_H
 #define CODEGEN_X86_64_H
 
+#include "arena.h"
 #include "ast.h"
+#include "map.h"
+#include <stdio.h>
+
+typedef struct codegen_x86_64
+{
+    arena_t *arena;
+    size_t base_offset;
+    map_t *symbols_stack_offset;
+    FILE *out;
+} codegen_x86_64_t;
+
+void
+codegen_linux_x86_64_init(codegen_x86_64_t *codegen, arena_t *arena, FILE *out);
 
 void
-codegen_linux_x86_64_emit_program(FILE *out, ast_node_t *prog);
+codegen_linux_x86_64_emit_program(codegen_x86_64_t *codegen, ast_node_t *prog);
 
 #endif /* CODEGEN_X86_64_H */
diff --git a/src/main.c b/src/main.c
index 810bf2d..312b0c1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -147,10 +147,14 @@ handle_codegen_linux(cli_opts_t *opts)
     assert(out);
 
     if (!(opts->options & CLI_OPT_ARCH)) {
-        codegen_linux_x86_64_emit_program(out, ast);
+        codegen_x86_64_t codegen = { 0 };
+        codegen_linux_x86_64_init(&codegen, &arena, out);
+        codegen_linux_x86_64_emit_program(&codegen, ast);
     } else {
         if (strcmp(opts->arch, "x86_64") == 0) {
-            codegen_linux_x86_64_emit_program(out, ast);
+            codegen_x86_64_t codegen = { 0 };
+            codegen_linux_x86_64_init(&codegen, &arena, out);
+            codegen_linux_x86_64_emit_program(&codegen, ast);
         } else if (strcmp(opts->arch, "aarch64") == 0) {
             codegen_linux_aarch64_emit_program(out, ast);
         } else {
diff --git a/tests/integration/tests/0024_var_definition.ol b/tests/integration/tests/0024_var_definition.ol
index 241fc1a..5c23449 100644
--- a/tests/integration/tests/0024_var_definition.ol
+++ b/tests/integration/tests/0024_var_definition.ol
@@ -18,6 +18,10 @@ fn main(): u32 {
   return code
 }
 
+# TEST test_compile(exit_code=0)
+
+# TEST test_run_binary(exit_code=0)
+
 # TEST test_contains_tokens WITH
 # ./tests/0024_var_definition.ol:17:3: <var>
 # END
-- 
2.46.0


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

* [olang/patches/.build.yml] build success
  2024-09-21  0:20 ` [PATCH olang v1 3/3] codegen: add support scopes and symbols lookups for var Johnny Richard
@ 2024-09-21  0:23   ` builds.sr.ht
  0 siblings, 0 replies; 6+ messages in thread
From: builds.sr.ht @ 2024-09-21  0:23 UTC (permalink / raw)
  To: Johnny Richard; +Cc: ~johnnyrichard/olang-devel

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

[compiler: enable full compilation for vars][0] from [Johnny Richard][1]

[0]: https://lists.sr.ht/~johnnyrichard/olang-devel/patches/55131
[1]: mailto:johnny@johnnyrichard.com

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

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

* Re: [PATCH olang v1 0/3] compiler: enable full compilation for vars
  2024-09-21  0:20 [PATCH olang v1 0/3] compiler: enable full compilation for vars Johnny Richard
                   ` (2 preceding siblings ...)
  2024-09-21  0:20 ` [PATCH olang v1 3/3] codegen: add support scopes and symbols lookups for var Johnny Richard
@ 2024-09-21  0:59 ` Carlos Maniero
  3 siblings, 0 replies; 6+ messages in thread
From: Carlos Maniero @ 2024-09-21  0:59 UTC (permalink / raw)
  To: Johnny Richard, ~johnnyrichard/olang-devel

We did it! Applied!

To git.sr.ht:~johnnyrichard/olang
   29cc9fc..cb4b63f  main -> main

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

end of thread, other threads:[~2024-09-21  0:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-09-21  0:20 [PATCH olang v1 0/3] compiler: enable full compilation for vars Johnny Richard
2024-09-21  0:20 ` [PATCH olang v1 1/3] scope: create scope data structure Johnny Richard
2024-09-21  0:20 ` [PATCH olang v1 2/3] checker: create checker and populate scope on ast nodes Johnny Richard
2024-09-21  0:20 ` [PATCH olang v1 3/3] codegen: add support scopes and symbols lookups for var Johnny Richard
2024-09-21  0:23   ` [olang/patches/.build.yml] build success builds.sr.ht
2024-09-21  0:59 ` [PATCH olang v1 0/3] compiler: enable full compilation for vars Carlos Maniero

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