public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
* [olang/patches/.build.yml] build success
  2024-09-11  1:03 ` [PATCH olang v1 2/2] parser: add var definition and reference support Johnny Richard
@ 2024-09-10 23:05   ` builds.sr.ht
  0 siblings, 0 replies; 5+ messages in thread
From: builds.sr.ht @ 2024-09-10 23:05 UTC (permalink / raw)
  To: Johnny Richard; +Cc: ~johnnyrichard/olang-devel

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

[parser: implement variable definition][0] from [Johnny Richard][1]

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

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

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

* Re: [PATCH olang v1 0/2] parser: implement variable definition
  2024-09-11  1:03 [PATCH olang v1 0/2] parser: implement variable definition Johnny Richard
@ 2024-09-10 23:15 ` Carlos Maniero
  2024-09-11  1:03 ` [PATCH olang v1 1/2] lexer: add support var keyword Johnny Richard
  2024-09-11  1:03 ` [PATCH olang v1 2/2] parser: add var definition and reference support Johnny Richard
  2 siblings, 0 replies; 5+ messages in thread
From: Carlos Maniero @ 2024-09-10 23:15 UTC (permalink / raw)
  To: Johnny Richard, ~johnnyrichard/olang-devel

> This lexer is soooo goood!! OMG...

We are flying so much because of this!

Applied!

To git.sr.ht:~johnnyrichard/olang
   8600ca3..3d4791a  main -> main

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

* [PATCH olang v1 0/2] parser: implement variable definition
@ 2024-09-11  1:03 Johnny Richard
  2024-09-10 23:15 ` Carlos Maniero
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Johnny Richard @ 2024-09-11  1:03 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

Johnny Richard (2):
  lexer: add support var keyword
  parser: add var definition and reference support

 src/ast.c                                     | 28 ++++++++++
 src/ast.h                                     | 22 ++++++++
 src/lexer.c                                   |  5 ++
 src/lexer.h                                   |  1 +
 src/parser.c                                  | 52 +++++++++++++++++++
 src/pretty_print_ast.c                        | 25 +++++++++
 .../integration/tests/0024_var_definition.ol  | 33 ++++++++++++
 7 files changed, 166 insertions(+)
 create mode 100644 tests/integration/tests/0024_var_definition.ol


base-commit: 8600ca34fb0fbae495a8737535aeffe4d44eb0ab
-- 
2.46.0


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

* [PATCH olang v1 1/2] lexer: add support var keyword
  2024-09-11  1:03 [PATCH olang v1 0/2] parser: implement variable definition Johnny Richard
  2024-09-10 23:15 ` Carlos Maniero
@ 2024-09-11  1:03 ` Johnny Richard
  2024-09-11  1:03 ` [PATCH olang v1 2/2] parser: add var definition and reference support Johnny Richard
  2 siblings, 0 replies; 5+ messages in thread
From: Johnny Richard @ 2024-09-11  1:03 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
---
This lexer is soooo goood!! OMG...

 src/lexer.c                                   |  5 ++++
 src/lexer.h                                   |  1 +
 .../integration/tests/0024_var_definition.ol  | 23 +++++++++++++++++++
 3 files changed, 29 insertions(+)
 create mode 100644 tests/integration/tests/0024_var_definition.ol

diff --git a/src/lexer.c b/src/lexer.c
index 2129788..12b4719 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -284,6 +284,7 @@ static char *token_kind_str_table[] = {
     [TOKEN_RETURN] = "return",
     [TOKEN_IF] = "if",
     [TOKEN_ELSE] = "else",
+    [TOKEN_VAR] = "var",
     [TOKEN_LF] = "line_feed",
     [TOKEN_OPAREN] = "(",
     [TOKEN_CPAREN] = ")",
@@ -419,6 +420,10 @@ lexer_str_to_token_kind(string_view_t text)
         return TOKEN_ELSE;
     }
 
+    if (string_view_eq_to_cstr(text, "var")) {
+        return TOKEN_VAR;
+    }
+
     if (string_view_eq_to_cstr(text, "return")) {
         return TOKEN_RETURN;
     }
diff --git a/src/lexer.h b/src/lexer.h
index 98a6d87..4a0e2e1 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -40,6 +40,7 @@ typedef enum token_kind
     TOKEN_RETURN,
     TOKEN_IF,
     TOKEN_ELSE,
+    TOKEN_VAR,
 
     // Equality operators
     TOKEN_CMP_EQ,
diff --git a/tests/integration/tests/0024_var_definition.ol b/tests/integration/tests/0024_var_definition.ol
new file mode 100644
index 0000000..d0b68da
--- /dev/null
+++ b/tests/integration/tests/0024_var_definition.ol
@@ -0,0 +1,23 @@
+# 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(): u32 {
+  var code: u32 = 0;
+  return code;
+}
+
+# TEST test_contains_tokens WITH
+# ./tests/0024_var_definition.ol:17:3: <var>
+# END
-- 
2.46.0


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

* [PATCH olang v1 2/2] parser: add var definition and reference support
  2024-09-11  1:03 [PATCH olang v1 0/2] parser: implement variable definition Johnny Richard
  2024-09-10 23:15 ` Carlos Maniero
  2024-09-11  1:03 ` [PATCH olang v1 1/2] lexer: add support var keyword Johnny Richard
@ 2024-09-11  1:03 ` Johnny Richard
  2024-09-10 23:05   ` [olang/patches/.build.yml] build success builds.sr.ht
  2 siblings, 1 reply; 5+ messages in thread
From: Johnny Richard @ 2024-09-11  1:03 UTC (permalink / raw)
  To: ~johnnyrichard/olang-devel; +Cc: Johnny Richard

In order to get the var definition parsed we also introduce the
reference node to get a functional ast test.

This first implementation assumes that all variables will be of type u32
and we don't allow variable definitions without assignment, this
assignment issue will be addressed in the future.

Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
---
 src/ast.c                                     | 28 ++++++++++
 src/ast.h                                     | 22 ++++++++
 src/parser.c                                  | 52 +++++++++++++++++++
 src/pretty_print_ast.c                        | 25 +++++++++
 .../integration/tests/0024_var_definition.ol  | 14 ++++-
 5 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/src/ast.c b/src/ast.c
index 4b252ae..d2fd2fa 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -52,6 +52,22 @@ ast_new_node_fn_def(arena_t *arena, string_view_t identifier, type_t return_type
     return node_fn_def;
 }
 
+ast_node_t *
+ast_new_node_var_def(arena_t *arena, string_view_t identifier, type_t type, ast_node_t *value)
+{
+    ast_node_t *node_var_def = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t));
+    assert(node_var_def);
+
+    node_var_def->kind = AST_NODE_VAR_DEF;
+    ast_var_definition_t *var_def = &node_var_def->as_var_def;
+
+    var_def->identifier = identifier;
+    var_def->type = type;
+    var_def->value = value;
+
+    return node_var_def;
+}
+
 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)
 {
@@ -79,6 +95,18 @@ ast_new_node_literal_u32(arena_t *arena, uint32_t value)
     return node_literal;
 }
 
+ast_node_t *
+ast_new_node_ref(arena_t *arena, string_view_t identifier)
+{
+    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->as_ref.identifier = identifier;
+
+    return node_ref;
+}
+
 ast_node_t *
 ast_new_node_return_stmt(arena_t *arena)
 {
diff --git a/src/ast.h b/src/ast.h
index 9bf3723..94ee6b4 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -30,10 +30,12 @@ typedef enum
     AST_NODE_PROGRAM,
     AST_NODE_BLOCK,
     AST_NODE_FN_DEF,
+    AST_NODE_VAR_DEF,
     AST_NODE_BINARY_OP,
     AST_NODE_RETURN_STMT,
     AST_NODE_IF_STMT,
     AST_NODE_LITERAL,
+    AST_NODE_REF,
     AST_NODE_UNKNOWN
 } ast_node_kind_t;
 
@@ -59,6 +61,13 @@ typedef struct ast_fn_definition
     ast_node_t *block;
 } ast_fn_definition_t;
 
+typedef struct ast_var_definition
+{
+    string_view_t identifier;
+    type_t type;
+    ast_node_t *value;
+} ast_var_definition_t;
+
 typedef enum
 {
     AST_LITERAL_U32
@@ -73,6 +82,11 @@ typedef struct ast_literal
     };
 } ast_literal_t;
 
+typedef struct ast_ref
+{
+    string_view_t identifier;
+} ast_ref_t;
+
 typedef enum ast_binary_op_kind
 {
     AST_BINOP_ADDITION,
@@ -121,8 +135,10 @@ typedef struct ast_node
     {
         ast_program_t as_program;
         ast_fn_definition_t as_fn_def;
+        ast_var_definition_t as_var_def;
         ast_binary_op_t as_bin_op;
         ast_literal_t as_literal;
+        ast_ref_t as_ref;
         ast_block_t as_block;
         ast_return_stmt_t as_return_stmt;
         ast_if_stmt_t as_if_stmt;
@@ -135,12 +151,18 @@ 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_node_t *
+ast_new_node_var_def(arena_t *arena, string_view_t identifier, type_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);
 
 ast_node_t *
 ast_new_node_literal_u32(arena_t *arena, uint32_t value);
 
+ast_node_t *
+ast_new_node_ref(arena_t *arena, string_view_t identifier);
+
 ast_node_t *
 ast_new_node_return_stmt(arena_t *arena);
 
diff --git a/src/parser.c b/src/parser.c
index 8f49f5e..d71500f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -45,6 +45,9 @@ parser_parse_return_stmt(parser_t *parser);
 static ast_node_t *
 parser_parse_if_stmt(parser_t *parser);
 
+static ast_node_t *
+parser_parse_var_def(parser_t *parser);
+
 ast_node_t *
 parser_parse_fn_definition(parser_t *parser);
 
@@ -233,6 +236,9 @@ parser_parse_factor(parser_t *parser)
         case TOKEN_NUMBER:
             return ast_new_node_literal_u32(parser->arena, string_view_to_u32(token.value));
 
+        case TOKEN_IDENTIFIER:
+            return ast_new_node_ref(parser->arena, token.value);
+
         case TOKEN_OPAREN: {
             ast_node_t *expr = parser_parse_expr(parser);
             if (expr == NULL) {
@@ -348,7 +354,15 @@ StartLoop:
             node = parser_parse_if_stmt(parser);
             break;
         }
+        case TOKEN_VAR: {
+            node = parser_parse_var_def(parser);
+            break;
+        }
+        case TOKEN_CCURLY: {
+            goto EndLoop;
+        }
         default: {
+            // FIXME: write a better error message
             goto EndLoop;
         }
     }
@@ -443,6 +457,44 @@ parser_parse_if_stmt(parser_t *parser)
     return node_if_stmt;
 }
 
+static ast_node_t *
+parser_parse_var_def(parser_t *parser)
+{
+    if (!skip_expected_token(parser, TOKEN_VAR)) {
+        return NULL;
+    }
+
+    token_t identifier_token;
+    if (!expected_next_token(parser, &identifier_token, TOKEN_IDENTIFIER)) {
+        return NULL;
+    }
+
+    if (!skip_expected_token(parser, TOKEN_COLON)) {
+        return NULL;
+    }
+
+    type_t var_type;
+    if (!parser_parse_type(parser, &var_type)) {
+        return NULL;
+    }
+
+    // FIXME: assignment must be optional according to the spec
+    if (!skip_expected_token(parser, TOKEN_EQ)) {
+        return NULL;
+    }
+
+    ast_node_t *expr = parser_parse_expr(parser);
+    if (expr == NULL) {
+        return NULL;
+    }
+
+    ast_node_t *var_node = ast_new_node_var_def(parser->arena, identifier_token.value, var_type, expr);
+
+    skip_line_feeds(parser->lexer);
+
+    return var_node;
+}
+
 static bool
 skip_expected_token(parser_t *parser, token_kind_t expected_kind)
 {
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index 3c12716..d6eef67 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -198,6 +198,31 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
 
             return node;
         }
+        case AST_NODE_VAR_DEF: {
+            pretty_print_node_t *node = pretty_print_node_new(arena);
+            ast_var_definition_t var = ast->as_var_def;
+
+            char name[256];
+            sprintf(name, "Var_Definition <name:" SV_FMT "> <kind:u32>", SV_ARG(var.identifier));
+            node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
+            strcpy(node->name, name);
+
+            pretty_print_node_t *child = ast_node_to_pretty_print_node(var.value, arena);
+            list_append(node->children, child);
+
+            return node;
+        }
+        case AST_NODE_REF: {
+            pretty_print_node_t *node = pretty_print_node_new(arena);
+            ast_ref_t ref = ast->as_ref;
+
+            char name[256];
+            sprintf(name, "Reference <name:" SV_FMT ">", SV_ARG(ref.identifier));
+            node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
+            strcpy(node->name, name);
+
+            return node;
+        }
         case AST_NODE_BINARY_OP: {
             pretty_print_node_t *node = pretty_print_node_new(arena);
             ast_binary_op_t binop = ast->as_bin_op;
diff --git a/tests/integration/tests/0024_var_definition.ol b/tests/integration/tests/0024_var_definition.ol
index d0b68da..241fc1a 100644
--- a/tests/integration/tests/0024_var_definition.ol
+++ b/tests/integration/tests/0024_var_definition.ol
@@ -14,10 +14,20 @@
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 fn main(): u32 {
-  var code: u32 = 0;
-  return code;
+  var code: u32 = 0
+  return code
 }
 
 # TEST test_contains_tokens WITH
 # ./tests/0024_var_definition.ol:17:3: <var>
 # END
+
+# TEST test_ast WITH
+# Translation_Unit
+# `-Function_Definition <name:main> <return:0>
+#   `-Block
+#     |-Var_Definition <name:code> <kind:u32>
+#     | `-Literal <kind:u32> <value:0>
+#     `-Return_Statement
+#       `-Reference <name:code>
+# END
-- 
2.46.0


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

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

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-09-11  1:03 [PATCH olang v1 0/2] parser: implement variable definition Johnny Richard
2024-09-10 23:15 ` Carlos Maniero
2024-09-11  1:03 ` [PATCH olang v1 1/2] lexer: add support var keyword Johnny Richard
2024-09-11  1:03 ` [PATCH olang v1 2/2] parser: add var definition and reference support Johnny Richard
2024-09-10 23:05   ` [olang/patches/.build.yml] build success builds.sr.ht

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