From: Brendan Hansen Date: Tue, 26 May 2020 21:11:06 +0000 (-0500) Subject: Implemented #12 X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=4e3183fec096f7a35f3fc6fbee1b6705d5c25ce4;p=onyx.git Implemented #12 --- diff --git a/docs/thoughts b/docs/thoughts index ddf255fb..86a7ba5d 100644 --- a/docs/thoughts +++ b/docs/thoughts @@ -4,7 +4,7 @@ Type checking at parse time: * This requires that functions are declared in a particular order like C * This also requires immediate evaluation of external symbols (C #include style) - Don't like this at all - - Want a proper module system + - Want a proper module system <<<< /* foo.onyx */ foo :: proc (a i32) -> f32 { @@ -21,4 +21,4 @@ Type checking at parse time: foo(5) would have a left node of SYMBOL:foo This will be resolved in a later stage between the parsing and semantic pass - + Type checking and resolving would have to occur afterwards diff --git a/onyx b/onyx index 9015a7d8..07864693 100755 Binary files a/onyx and b/onyx differ diff --git a/onyx.c b/onyx.c index d91dd70e..27eeec05 100644 --- a/onyx.c +++ b/onyx.c @@ -54,9 +54,8 @@ int main(int argc, char *argv[]) { if (onyx_message_has_errors(&msgs)) { onyx_message_print(&msgs); } else { - // TODO: Make a better AST printer so there aren't infinite loops - // onyx_ast_print(program); - bh_printf("No errors.\n"); + onyx_ast_print(program, 0); + bh_printf("\nNo errors.\n"); } bh_file_contents_delete(&fc); diff --git a/onyxlex.c b/onyxlex.c index b7bf7a54..a922f7c8 100644 --- a/onyxlex.c +++ b/onyxlex.c @@ -230,7 +230,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { // Number literal if (char_is_num(*tokenizer->curr)) { - u64 len = 0; + u32 len = 1; while (char_is_num(*(tokenizer->curr + 1)) || *(tokenizer->curr + 1) == '.') { len++; INCREMENT_CURR_TOKEN(tokenizer); diff --git a/onyxparser.c b/onyxparser.c index 493527c5..77bc0c47 100644 --- a/onyxparser.c +++ b/onyxparser.c @@ -223,6 +223,7 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { OnyxAstNode* lit_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); lit_node->type = &builtin_types[ONYX_TYPE_INFO_KIND_INT64]; lit_node->token = expect(parser, TOKEN_TYPE_LITERAL_NUMERIC); + lit_node->flags |= ONYX_AST_FLAG_COMPTIME; return lit_node; } diff --git a/onyxparser.h b/onyxparser.h index 9b16c10b..dadf29f9 100644 --- a/onyxparser.h +++ b/onyxparser.h @@ -108,9 +108,10 @@ extern OnyxTypeInfo builtin_types[]; // only 32-bits of flags to play with typedef enum OnyxAstFlags { // Top-level flags - ONYX_AST_FLAG_EXPORTED = BH_BIT(1), - ONYX_AST_FLAG_LVAL = BH_BIT(2), - ONYX_AST_FLAG_CONST = BH_BIT(3), + ONYX_AST_FLAG_EXPORTED = BH_BIT(0), + ONYX_AST_FLAG_LVAL = BH_BIT(1), + ONYX_AST_FLAG_CONST = BH_BIT(2), + ONYX_AST_FLAG_COMPTIME = BH_BIT(3), } OnyxAstFlags; struct OnyxAstNodeLocal { diff --git a/onyxutils.c b/onyxutils.c index 5fdddcde..2a07f2a9 100644 --- a/onyxutils.c +++ b/onyxutils.c @@ -1,5 +1,109 @@ #include "onyxutils.h" +#include "onyxlex.h" +#include "onyxparser.h" -void onyx_ast_print(OnyxAstNode* node) { +#define print_indent { if (indent > 0) bh_printf("\n"); for (int i = 0; i < indent; i++) bh_printf(" "); } + +void onyx_ast_print(OnyxAstNode* node, i32 indent) { if (node == NULL) return; + + print_indent; + bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); + + switch (node->kind) { + case ONYX_AST_NODE_KIND_PROGRAM: { + if (node->next) + onyx_ast_print(node->next, indent + 1); + + break; + } + + case ONYX_AST_NODE_KIND_FUNCDEF: { + bh_printf("(%b) ", node->token->token, node->token->length); + OnyxAstNodeFuncDef* fd = &node->as_funcdef; + + print_indent; + bh_printf("Params "); + if (fd->params) + onyx_ast_print((OnyxAstNode *) fd->params, 0); + + print_indent; + bh_printf("Returns %s", fd->return_type->name); + + print_indent; + bh_printf("Body"); + if (fd->body) + onyx_ast_print((OnyxAstNode *) fd->body, indent + 1); + + if (fd->next) + onyx_ast_print((OnyxAstNode *) fd->next, indent); + + break; + } + + case ONYX_AST_NODE_KIND_PARAM: { + OnyxAstNodeParam* param = &node->as_param; + bh_printf("%b %s", param->token->token, param->token->length, param->type->name); + if (param->next && indent == 0) { + bh_printf(", "); + onyx_ast_print((OnyxAstNode *) param->next, 0); + } + + break; + } + + case ONYX_AST_NODE_KIND_BLOCK: { + OnyxAstNodeBlock* block = &node->as_block; + if (block->scope) { + onyx_ast_print((OnyxAstNode *) block->scope, indent + 1); + } + + if (block->body) { + onyx_ast_print((OnyxAstNode *) block->body, indent + 1); + } + + break; + } + + case ONYX_AST_NODE_KIND_SCOPE: { + OnyxAstNodeScope* scope = &node->as_scope; + if (scope->last_local) { + onyx_ast_print((OnyxAstNode *) scope->last_local, 0); + } + + break; + } + + case ONYX_AST_NODE_KIND_LOCAL: { + OnyxAstNodeLocal* local = &node->as_local; + bh_printf("%b %s", local->token->token, local->token->length, local->type->name); + if (local->prev_local && indent == 0) { + bh_printf(", "); + onyx_ast_print((OnyxAstNode *) local->prev_local, 0); + } + break; + } + + case ONYX_AST_NODE_KIND_RETURN: { + if (node->next) { + onyx_ast_print(node->next, indent + 1); + } + + break; + } + + case ONYX_AST_NODE_KIND_LITERAL: { + bh_printf("%b", node->token->token, node->token->length); + break; + } + + default: { + onyx_ast_print(node->left, indent + 1); + onyx_ast_print(node->right, indent + 1); + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; + } + } } diff --git a/onyxutils.h b/onyxutils.h index 4da320b5..63b6f601 100644 --- a/onyxutils.h +++ b/onyxutils.h @@ -2,4 +2,4 @@ #include "onyxparser.h" -void onyx_ast_print(OnyxAstNode* program); +void onyx_ast_print(OnyxAstNode* program, i32 indent); diff --git a/progs/minimal.onyx b/progs/minimal.onyx index ee2e6516..19173392 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -19,3 +19,18 @@ export mul :: proc (a i32, b i32) -> i32 { return c * d; } + +very_long_function_name :: proc () -> void { + a:i32; + b:i32; + c:i32; + d:i32; + e:i32; + f:i32; + g:i32; + h:i32; + i:i32 = 0 + 2; + j:i32; + k:i32; + l:i32; +}