* [PATCH olang] parser: returns an unknown type instead of a SV
@ 2024-10-09 11:24 Carlos Maniero
2024-10-09 11:24 ` [olang/patches/.build.yml] build success builds.sr.ht
2024-10-09 13:28 ` [PATCH olang] parser: returns an unknown type instead of a SV Johnny Richard
0 siblings, 2 replies; 3+ messages in thread
From: Carlos Maniero @ 2024-10-09 11:24 UTC (permalink / raw)
To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero
To support pointer, it is more convenient for the AST to have an
*type_t* structure instead of an string view, once the type_t can
support multiple shapes, such as pointers.
The parser is still not resolving the type which is a checker
responsibility. However, it returns a unknown type which is resolved by
the checker.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
src/ast.c | 8 +++---
src/ast.h | 12 ++++----
src/checker.c | 59 ++++++++++++++++++++++++++++++++++++--
src/codegen_linux_x86_64.c | 16 +++++++----
src/parser.c | 12 ++++++--
src/pretty_print_ast.c | 4 +--
src/scope.c | 2 +-
src/scope.h | 4 +--
src/type.c | 36 +++++------------------
src/type.h | 25 +++++++++++-----
10 files changed, 115 insertions(+), 63 deletions(-)
diff --git a/src/ast.c b/src/ast.c
index d6ec70c..79daca6 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -44,7 +44,7 @@ ast_new_node_fn_def(arena_t *arena,
token_loc_t loc,
string_view_t id,
list_t *params,
- string_view_t return_type,
+ type_t *return_type,
ast_node_t *block)
{
assert(arena);
@@ -86,7 +86,7 @@ ast_new_node_fn_call(arena_t *arena, token_loc_t loc, string_view_t id, list_t *
}
ast_node_t *
-ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, string_view_t type, ast_node_t *value)
+ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, type_t *type, ast_node_t *value)
{
ast_node_t *node_var_def = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t));
assert(node_var_def);
@@ -217,13 +217,13 @@ ast_new_node_block(arena_t *arena)
}
ast_fn_param_t *
-ast_new_fn_param(arena_t *arena, string_view_t id, string_view_t type_id)
+ast_new_fn_param(arena_t *arena, string_view_t id, type_t *type)
{
ast_fn_param_t *fn_param = (ast_fn_param_t *)arena_alloc(arena, sizeof(ast_fn_param_t));
assert(fn_param);
fn_param->id = id;
- fn_param->type_id = type_id;
+ fn_param->type = type;
return fn_param;
}
diff --git a/src/ast.h b/src/ast.h
index 238435e..fccc303 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -66,7 +66,7 @@ typedef struct ast_translation_unit
typedef struct ast_fn_param
{
string_view_t id;
- string_view_t type_id;
+ type_t *type;
} ast_fn_param_t;
typedef struct ast_fn_definition
@@ -74,7 +74,7 @@ typedef struct ast_fn_definition
ast_node_meta_t meta;
string_view_t id;
list_t *params;
- string_view_t return_type;
+ type_t *return_type;
ast_node_t *block;
scope_t *scope;
} ast_fn_definition_t;
@@ -91,7 +91,7 @@ typedef struct ast_var_definition
{
ast_node_meta_t meta;
string_view_t id;
- string_view_t type;
+ type_t *type;
ast_node_t *value;
scope_t *scope;
} ast_var_definition_t;
@@ -206,14 +206,14 @@ ast_new_node_fn_def(arena_t *arena,
token_loc_t loc,
string_view_t id,
list_t *params,
- string_view_t return_type,
+ type_t *return_type,
ast_node_t *block);
ast_node_t *
ast_new_node_fn_call(arena_t *arena, token_loc_t loc, string_view_t id, list_t *args);
ast_node_t *
-ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, string_view_t type, ast_node_t *value);
+ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, type_t *type, ast_node_t *value);
ast_node_t *
ast_new_node_bin_op(arena_t *arena, token_loc_t loc, ast_binary_op_kind_t kind, ast_node_t *lhs, ast_node_t *rhs);
@@ -240,6 +240,6 @@ ast_node_t *
ast_new_node_block(arena_t *arena);
ast_fn_param_t *
-ast_new_fn_param(arena_t *arena, string_view_t id, string_view_t type_id);
+ast_new_fn_param(arena_t *arena, string_view_t id, type_t *type);
#endif /* AST_H */
diff --git a/src/checker.c b/src/checker.c
index 36202bd..c688b7a 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -37,6 +37,55 @@ checker_new(arena_t *arena)
return checker;
}
+static type_t
+type_from_id(string_view_t id)
+{
+ type_t type = { 0 };
+ type.id = id;
+ if (string_view_eq_to_cstr(id, "u8")) {
+ type.kind = TYPE_PRIMITIVE;
+ type.as_primitive.size = 1;
+ type.as_primitive.kind = TYPE_U8;
+ return type;
+ }
+ if (string_view_eq_to_cstr(id, "u16")) {
+ type.kind = TYPE_PRIMITIVE;
+ type.as_primitive.size = 2;
+ type.as_primitive.kind = TYPE_U16;
+ return type;
+ }
+ if (string_view_eq_to_cstr(id, "u32")) {
+ type.kind = TYPE_PRIMITIVE;
+ type.as_primitive.size = 4;
+ type.as_primitive.kind = TYPE_U32;
+ return type;
+ }
+ if (string_view_eq_to_cstr(id, "u64")) {
+ type.kind = TYPE_PRIMITIVE;
+ type.as_primitive.size = 8;
+ type.as_primitive.kind = TYPE_U64;
+ return type;
+ }
+
+ // FIXME: handle user defined types
+ assert(0 && "unknown type");
+}
+
+/**
+ * transform unknown types into actual types
+ */
+static void
+type_resolve(type_t *type)
+{
+ switch (type->kind) {
+ case TYPE_UNKNOWN:
+ *type = type_from_id(type->as_unknown.id);
+ break;
+ case TYPE_PRIMITIVE:
+ break;
+ }
+}
+
void
checker_check(checker_t *checker, ast_node_t *ast)
{
@@ -67,7 +116,8 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
ast_fn_definition_t *fn_def = &ast->as_fn_def;
fn_def->scope = scope_push(scope);
- symbol_t *symbol = symbol_new(checker->arena, fn_def->id, type_from_id(fn_def->return_type));
+ type_resolve(fn_def->return_type);
+ symbol_t *symbol = symbol_new(checker->arena, fn_def->id, fn_def->return_type);
scope_insert(scope, symbol);
list_item_t *item = list_head(fn_def->params);
@@ -75,7 +125,8 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
while (item != NULL) {
ast_fn_param_t *param = (ast_fn_param_t *)item->value;
- symbol_t *symbol = symbol_new(checker->arena, param->id, type_from_id(param->type_id));
+ type_resolve(param->type);
+ symbol_t *symbol = symbol_new(checker->arena, param->id, param->type);
scope_insert(fn_def->scope, symbol);
item = list_next(item);
@@ -156,7 +207,9 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
case AST_NODE_VAR_DEF: {
string_view_t id = ast->as_var_def.id;
- symbol_t *symbol = symbol_new(checker->arena, id, type_from_id(ast->as_var_def.type));
+ type_resolve(ast->as_var_def.type);
+
+ symbol_t *symbol = symbol_new(checker->arena, id, ast->as_var_def.type);
scope_insert(scope, symbol);
ast->as_var_def.scope = scope;
diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
index 10005b9..703f3b5 100644
--- a/src/codegen_linux_x86_64.c
+++ b/src/codegen_linux_x86_64.c
@@ -165,7 +165,7 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr
size_t offset = codegen_linux_x86_64_get_stack_offset(codegen, symbol);
- size_t bytes = type_to_bytes(&symbol->type);
+ size_t bytes = type_to_bytes(symbol->type);
fprintf(codegen->out, " mov -%ld(%%rbp), %s\n", offset, get_reg_for(REG_ACCUMULATOR, bytes));
return bytes;
@@ -195,7 +195,7 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr
fprintf(codegen->out, " call " SV_FMT "\n", SV_ARG(fn_call.id));
- return type_to_bytes(&symbol->type);
+ return type_to_bytes(symbol->type);
}
case AST_NODE_BINARY_OP: {
ast_binary_op_t bin_op = expr_node->as_bin_op;
@@ -570,7 +570,7 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
codegen_linux_x86_64_emit_expression(codegen, var_def.value);
}
- size_t type_size = type_to_bytes(&symbol->type);
+ size_t type_size = type_to_bytes(symbol->type);
fprintf(codegen->out,
" mov %s, -%ld(%%rbp)\n",
@@ -593,7 +593,7 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
codegen_linux_x86_64_emit_expression(codegen, var_assign.expr);
- size_t type_size = type_to_bytes(&symbol->type);
+ size_t type_size = type_to_bytes(symbol->type);
fprintf(codegen->out, " mov %s, -%ld(%%rbp)\n", get_reg_for(REG_ACCUMULATOR, type_size), offset);
break;
@@ -682,6 +682,9 @@ type_to_bytes(type_t *type)
case TYPE_PRIMITIVE: {
return type->as_primitive.size;
}
+ case TYPE_UNKNOWN: {
+ assert(0 && "cannot calculate size of an unknown type: probably a parser issue.");
+ }
}
assert(0 && "unreachable");
@@ -702,7 +705,7 @@ calculate_fn_local_size(scope_t *scope)
for (size_t i = 0; i < scope->symbols->size; ++i) {
symbol_t *symbol = (symbol_t *)kvs[i]->value;
- local_size += type_to_bytes(&symbol->type);
+ local_size += type_to_bytes(symbol->type);
}
size_t max_child_local_size = 0;
@@ -748,7 +751,8 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_
fprintf(codegen->out,
" mov %s, -%ld(%%rbp)\n",
- get_reg_for(x86_call_args[i], symbol->type.as_primitive.size),
+ // FIXME: Type may not be an as_primitive
+ get_reg_for(x86_call_args[i], symbol->type->as_primitive.size),
offset);
// FIXME: add offset according to the param size
diff --git a/src/parser.c b/src/parser.c
index 5d6290b..6875b42 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -371,7 +371,7 @@ parser_parse_fn_params(parser_t *parser)
string_view_t type_id;
parser_parse_type(parser, &type_id);
- ast_fn_param_t *param = ast_new_fn_param(parser->arena, token.value, type_id);
+ ast_fn_param_t *param = ast_new_fn_param(parser->arena, token.value, type_new_unknown(parser->arena, type_id));
list_append(params, param);
skip_line_feeds(parser->lexer);
@@ -420,7 +420,12 @@ parser_parse_fn_definition(parser_t *parser)
return NULL;
}
- return ast_new_node_fn_def(parser->arena, fn_name_token.loc, fn_name_token.value, params, fn_return_type, block);
+ return ast_new_node_fn_def(parser->arena,
+ fn_name_token.loc,
+ fn_name_token.value,
+ params,
+ type_new_unknown(parser->arena, fn_return_type),
+ block);
}
static bool
@@ -652,7 +657,8 @@ parser_parse_var_def(parser_t *parser)
return NULL;
}
- ast_node_t *var_node = ast_new_node_var_def(parser->arena, token_id.loc, token_id.value, var_type, expr);
+ ast_node_t *var_node = ast_new_node_var_def(
+ parser->arena, token_id.loc, token_id.value, type_new_unknown(parser->arena, var_type), expr);
return var_node;
}
diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c
index 0c5d2d5..5feb270 100644
--- a/src/pretty_print_ast.c
+++ b/src/pretty_print_ast.c
@@ -113,7 +113,7 @@ pretty_print_new_fn_param(ast_fn_param_t *param, arena_t *arena)
{
pretty_print_node_t *node = pretty_print_node_new(arena);
char name[256];
- sprintf(name, "Param_Definition <name:" SV_FMT "> <type:" SV_FMT ">", SV_ARG(param->id), SV_ARG(param->type_id));
+ sprintf(name, "Param_Definition <name:" SV_FMT "> <type:" SV_FMT ">", SV_ARG(param->id), SV_ARG(param->type->id));
node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
strcpy(node->name, name);
return node;
@@ -148,7 +148,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena)
sprintf(name,
"Function_Definition <name:" SV_FMT "> <return:" SV_FMT ">",
SV_ARG(fn_def.id),
- SV_ARG(fn_def.return_type));
+ SV_ARG(fn_def.return_type->id));
node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1));
strcpy(node->name, name);
diff --git a/src/scope.c b/src/scope.c
index 81f610a..e483fbe 100644
--- a/src/scope.c
+++ b/src/scope.c
@@ -49,7 +49,7 @@ scope_new(arena_t *arena)
}
symbol_t *
-symbol_new(arena_t *arena, string_view_t id, type_t type)
+symbol_new(arena_t *arena, string_view_t id, type_t *type)
{
assert(arena);
symbol_t *symbol = (symbol_t *)arena_alloc(arena, sizeof(symbol_t));
diff --git a/src/scope.h b/src/scope.h
index 92a5a4f..08eb681 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -26,7 +26,7 @@
typedef struct symbol
{
string_view_t id;
- type_t type;
+ type_t *type;
} symbol_t;
typedef struct scope
@@ -41,7 +41,7 @@ scope_t *
scope_new(arena_t *arena);
symbol_t *
-symbol_new(arena_t *arena, string_view_t id, type_t type);
+symbol_new(arena_t *arena, string_view_t id, type_t *type);
symbol_t *
scope_lookup(scope_t *scope, string_view_t id);
diff --git a/src/type.c b/src/type.c
index 64147a2..9de5650 100644
--- a/src/type.c
+++ b/src/type.c
@@ -17,35 +17,13 @@
#include "type.h"
#include "assert.h"
-type_t
-type_from_id(string_view_t id)
+type_t *
+type_new_unknown(arena_t *arena, string_view_t id)
{
- type_t type = { 0 };
- if (string_view_eq_to_cstr(id, "u8")) {
- type.kind = TYPE_PRIMITIVE;
- type.as_primitive.size = 1;
- type.as_primitive.kind = TYPE_U8;
- return type;
- }
- if (string_view_eq_to_cstr(id, "u16")) {
- type.kind = TYPE_PRIMITIVE;
- type.as_primitive.size = 2;
- type.as_primitive.kind = TYPE_U16;
- return type;
- }
- if (string_view_eq_to_cstr(id, "u32")) {
- type.kind = TYPE_PRIMITIVE;
- type.as_primitive.size = 4;
- type.as_primitive.kind = TYPE_U32;
- return type;
- }
- if (string_view_eq_to_cstr(id, "u64")) {
- type.kind = TYPE_PRIMITIVE;
- type.as_primitive.size = 8;
- type.as_primitive.kind = TYPE_U64;
- return type;
- }
+ type_t *type = arena_alloc(arena, sizeof(type_t));
+ assert(type);
- // FIXME: handle user defined types
- assert(0 && "unknown type");
+ type->kind = TYPE_UNKNOWN;
+ type->as_unknown.id = id;
+ return type;
}
diff --git a/src/type.h b/src/type.h
index 1da3a11..97a2a41 100644
--- a/src/type.h
+++ b/src/type.h
@@ -16,9 +16,11 @@
*/
#ifndef TYPE_H
#define TYPE_H
+#include "arena.h"
#include "string_view.h"
typedef enum
{
+ TYPE_UNKNOWN,
TYPE_PRIMITIVE
} type_kind_t;
@@ -32,20 +34,29 @@ typedef enum
typedef struct type_primitive
{
- short size;
+ type_kind_t _type_kind;
+ string_view_t id;
type_primitive_kind_t kind;
+ short size;
} type_primitive_t;
-typedef struct type
+typedef struct type_unknown
{
+ type_kind_t _type_kind;
string_view_t id;
- type_kind_t kind;
- union
+} type_unknown_t;
+
+typedef union
+{
+ struct
{
- type_primitive_t as_primitive;
+ type_kind_t kind;
+ string_view_t id;
};
+ type_unknown_t as_unknown;
+ type_primitive_t as_primitive;
} type_t;
-type_t
-type_from_id(string_view_t id);
+type_t *
+type_new_unknown(arena_t *arena, string_view_t id);
#endif
base-commit: 2407c8150403c373df86e66b5886102c9f143193
--
2.46.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [olang/patches/.build.yml] build success
2024-10-09 11:24 [PATCH olang] parser: returns an unknown type instead of a SV Carlos Maniero
@ 2024-10-09 11:24 ` builds.sr.ht
2024-10-09 13:28 ` [PATCH olang] parser: returns an unknown type instead of a SV Johnny Richard
1 sibling, 0 replies; 3+ messages in thread
From: builds.sr.ht @ 2024-10-09 11:24 UTC (permalink / raw)
To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel
olang/patches/.build.yml: SUCCESS in 23s
[parser: returns an unknown type instead of a SV][0] from [Carlos Maniero][1]
[0]: https://lists.sr.ht/~johnnyrichard/olang-devel/patches/55397
[1]: mailto:carlos@maniero.me
✓ #1347623 SUCCESS olang/patches/.build.yml https://builds.sr.ht/~johnnyrichard/job/1347623
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH olang] parser: returns an unknown type instead of a SV
2024-10-09 11:24 [PATCH olang] parser: returns an unknown type instead of a SV Carlos Maniero
2024-10-09 11:24 ` [olang/patches/.build.yml] build success builds.sr.ht
@ 2024-10-09 13:28 ` Johnny Richard
1 sibling, 0 replies; 3+ messages in thread
From: Johnny Richard @ 2024-10-09 13:28 UTC (permalink / raw)
To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel
Thanks. Applied!
To git.sr.ht:~johnnyrichard/olang
2407c81..7f89684 main -> main
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-10-09 11:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-09 11:24 [PATCH olang] parser: returns an unknown type instead of a SV Carlos Maniero
2024-10-09 11:24 ` [olang/patches/.build.yml] build success builds.sr.ht
2024-10-09 13:28 ` [PATCH olang] parser: returns an unknown type instead of a SV Johnny Richard
Code repositories for project(s) associated with this public inbox
https://git.johnnyrichard.com/olang.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox