From: Brendan Hansen Date: Fri, 3 Jul 2020 16:02:17 +0000 (-0500) Subject: Moved the AST nodes to another file X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=38d513c3f844be81b75228d973636b0d8810417f;p=onyx.git Moved the AST nodes to another file --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h new file mode 100644 index 00000000..a46ef31d --- /dev/null +++ b/include/onyxastnodes.h @@ -0,0 +1,254 @@ +#ifndef ONYXASTNODES_H +#define ONYXASTNODES_H + +#include "onyxlex.h" + +typedef struct AstNode AstNode; +typedef struct AstNodeTyped AstNodeTyped; +typedef struct AstNodeUnaryOp AstNodeUnaryOp; +typedef struct AstNodeBinOp AstNodeBinOp; +typedef struct AstNodeAssign AstNodeAssign; +typedef struct AstNodeNumLit AstNodeNumLit; +typedef struct AstNodeLocal AstNodeLocal; +typedef struct AstNodeScope AstNodeScope; +typedef struct AstNodeReturn AstNodeReturn; +typedef struct AstNodeBlock AstNodeBlock; +typedef struct AstNodeIf AstNodeIf; +typedef struct AstNodeWhile AstNodeWhile; +typedef struct AstNodeFunction AstNodeFunction; +typedef struct AstNodeForeign AstNodeForeign; +typedef struct AstNodeGlobal AstNodeGlobal; +typedef struct AstNodeCall AstNodeCall; +typedef struct AstNodeArgument AstNodeArgument; +typedef struct AstNodeUse AstNodeUse; + +typedef enum AstNodeKind { + AST_NODE_KIND_ERROR, + AST_NODE_KIND_PROGRAM, + AST_NODE_KIND_USE, + + AST_NODE_KIND_FUNCTION, + AST_NODE_KIND_FOREIGN, + AST_NODE_KIND_BLOCK, + AST_NODE_KIND_SCOPE, + AST_NODE_KIND_LOCAL, + AST_NODE_KIND_GLOBAL, + AST_NODE_KIND_SYMBOL, + + AST_NODE_KIND_UNARY_OP, + AST_NODE_KIND_BIN_OP, + + AST_NODE_KIND_TYPE, + AST_NODE_KIND_LITERAL, + AST_NODE_KIND_PARAM, + AST_NODE_KIND_ARGUMENT, + AST_NODE_KIND_CALL, + AST_NODE_KIND_ASSIGNMENT, + AST_NODE_KIND_RETURN, + + AST_NODE_KIND_IF, + AST_NODE_KIND_WHILE, + AST_NODE_KIND_BREAK, + AST_NODE_KIND_CONTINUE, + + AST_NODE_KIND_COUNT +} AstNodeKind; + +typedef enum TypeInfoKind { + TYPE_INFO_KIND_UNKNOWN, + TYPE_INFO_KIND_VOID, + TYPE_INFO_KIND_BOOL, + + TYPE_INFO_KIND_UINT32, + TYPE_INFO_KIND_UINT64, + + TYPE_INFO_KIND_INT32, + TYPE_INFO_KIND_INT64, + + TYPE_INFO_KIND_FLOAT32, + TYPE_INFO_KIND_FLOAT64, + TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit +} TypeInfoKind; + +typedef struct TypeInfo { + TypeInfoKind kind; + u32 size; // in bytes + const char* name; + u32 is_int : 1; + u32 is_unsigned : 1; + u32 is_float : 1; + u32 is_bool : 1; + u32 is_known : 1; +} TypeInfo; + +extern TypeInfo builtin_types[]; + +// NOTE: Some of these flags will overlap since there are +// only 32-bits of flags to play with +typedef enum OnyxAstFlags { + // Top-level flags + 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; + +typedef enum OnyxUnaryOp { + ONYX_UNARY_OP_NEGATE, + ONYX_UNARY_OP_NOT, + ONYX_UNARY_OP_CAST, +} OnyxUnaryOp; + +typedef enum OnyxBinaryOp { + ONYX_BINARY_OP_ADD = 0, + ONYX_BINARY_OP_MINUS = 1, + ONYX_BINARY_OP_MULTIPLY = 2, + ONYX_BINARY_OP_DIVIDE = 3, + ONYX_BINARY_OP_MODULUS = 4, + + ONYX_BINARY_OP_EQUAL = 5, + ONYX_BINARY_OP_NOT_EQUAL = 6, + ONYX_BINARY_OP_LESS = 7, + ONYX_BINARY_OP_LESS_EQUAL = 8, + ONYX_BINARY_OP_GREATER = 9, + ONYX_BINARY_OP_GREATER_EQUAL = 10, +} OnyxBinaryOp; + +// NOTE: AstNode and AstNodeTyped need to be EXACTLY the same for +// all arguments existing in AstNode. I do this to avoid a nested +// "inheiritance" where you would have to say node.base.base.next +// for example +struct AstNode { + AstNodeKind kind; + u32 flags; + OnyxToken *token; + AstNode *next; +}; + +struct AstNodeTyped { + AstNodeKind kind; + u32 flags; + OnyxToken *token; + AstNode *next; + TypeInfo *type; +}; + +struct AstNodeBinOp { + AstNodeTyped base; + + OnyxBinaryOp operation; + + AstNodeTyped *left, *right; +}; + +struct AstNodeUnaryOp { + AstNodeTyped base; + + OnyxUnaryOp operation; + + AstNodeTyped *expr; +}; + +struct AstNodeAssign { + AstNode base; + + AstNodeTyped* lval; + AstNodeTyped* expr; +}; + +struct AstNodeNumLit { + AstNodeTyped base; + + union { i32 i; i64 l; f32 f; f64 d; } value; +}; + +struct AstNodeLocal { + AstNodeTyped base; + + AstNodeLocal *prev_local; +}; + +struct AstNodeReturn { + AstNode base; + + AstNodeTyped* expr; +}; + +struct AstNodeScope { + AstNode base; + + AstNodeScope *prev_scope; + AstNodeLocal *last_local; +}; + +struct AstNodeBlock { + AstNode base; + + AstNode *body; + AstNodeScope *scope; +}; + +struct AstNodeIf { + AstNode base; + + AstNodeTyped *cond; + AstNode *true_block; + AstNode *false_block; +}; + +struct AstNodeWhile { + AstNode base; + + AstNodeTyped *cond; + AstNodeBlock *body; +}; + +struct AstNodeFunction { + AstNodeTyped base; + + AstNodeBlock *body; + AstNodeLocal *params; +}; + +struct AstNodeForeign { + AstNode base; + + OnyxToken *mod_token, *name_token; + AstNode *import; +}; + +struct AstNodeGlobal { + AstNodeTyped base; + + AstNodeTyped *initial_value; +}; + +struct AstNodeCall { + AstNodeTyped base; + + AstNode *callee; // NOTE: Function definition node + AstNodeArgument *arguments; // NOTE: Expressions that form the actual param list + // They will be chained down using the "next" property + // unless this becomes used by something else +}; + +struct AstNodeArgument { + AstNodeTyped base; + + AstNodeTyped *value; +}; + +struct AstNodeUse { + AstNode base; + + OnyxToken *filename; +}; + +typedef struct OnyxProgram { + bh_arr(AstNodeUse *) uses; + bh_arr(AstNodeGlobal *) globals; + bh_arr(AstNodeFunction *) functions; + bh_arr(AstNodeForeign *) foreigns; +} OnyxProgram; + +#endif // #ifndef ONYXASTNODES_H diff --git a/include/onyxparser.h b/include/onyxparser.h index 095797a4..76886e14 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -5,25 +5,7 @@ #include "onyxlex.h" #include "onyxmsgs.h" - -typedef struct AstNode AstNode; -typedef struct AstNodeTyped AstNodeTyped; -typedef struct AstNodeUnaryOp AstNodeUnaryOp; -typedef struct AstNodeBinOp AstNodeBinOp; -typedef struct AstNodeAssign AstNodeAssign; -typedef struct AstNodeNumLit AstNodeNumLit; -typedef struct AstNodeLocal AstNodeLocal; -typedef struct AstNodeScope AstNodeScope; -typedef struct AstNodeReturn AstNodeReturn; -typedef struct AstNodeBlock AstNodeBlock; -typedef struct AstNodeIf AstNodeIf; -typedef struct AstNodeWhile AstNodeWhile; -typedef struct AstNodeFunction AstNodeFunction; -typedef struct AstNodeForeign AstNodeForeign; -typedef struct AstNodeGlobal AstNodeGlobal; -typedef struct AstNodeCall AstNodeCall; -typedef struct AstNodeArgument AstNodeArgument; -typedef struct AstNodeUse AstNodeUse; +#include "onyxastnodes.h" typedef struct OnyxParser { OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts @@ -38,235 +20,6 @@ typedef struct OnyxParser { bh_allocator allocator; } OnyxParser; -typedef enum AstNodeKind { - AST_NODE_KIND_ERROR, - AST_NODE_KIND_PROGRAM, - AST_NODE_KIND_USE, - - AST_NODE_KIND_FUNCTION, - AST_NODE_KIND_FOREIGN, - AST_NODE_KIND_BLOCK, - AST_NODE_KIND_SCOPE, - AST_NODE_KIND_LOCAL, - AST_NODE_KIND_GLOBAL, - AST_NODE_KIND_SYMBOL, - - AST_NODE_KIND_UNARY_OP, - AST_NODE_KIND_BIN_OP, - - AST_NODE_KIND_TYPE, - AST_NODE_KIND_LITERAL, - AST_NODE_KIND_PARAM, - AST_NODE_KIND_ARGUMENT, - AST_NODE_KIND_CALL, - AST_NODE_KIND_ASSIGNMENT, - AST_NODE_KIND_RETURN, - - AST_NODE_KIND_IF, - AST_NODE_KIND_WHILE, - AST_NODE_KIND_BREAK, - AST_NODE_KIND_CONTINUE, - - AST_NODE_KIND_COUNT -} AstNodeKind; - -typedef enum TypeInfoKind { - TYPE_INFO_KIND_UNKNOWN, - TYPE_INFO_KIND_VOID, - TYPE_INFO_KIND_BOOL, - - TYPE_INFO_KIND_UINT32, - TYPE_INFO_KIND_UINT64, - - TYPE_INFO_KIND_INT32, - TYPE_INFO_KIND_INT64, - - TYPE_INFO_KIND_FLOAT32, - TYPE_INFO_KIND_FLOAT64, - TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit -} TypeInfoKind; - -typedef struct TypeInfo { - TypeInfoKind kind; - u32 size; // in bytes - const char* name; - u32 is_int : 1; - u32 is_unsigned : 1; - u32 is_float : 1; - u32 is_bool : 1; - u32 is_known : 1; -} TypeInfo; - -extern TypeInfo builtin_types[]; - -// NOTE: Some of these flags will overlap since there are -// only 32-bits of flags to play with -typedef enum OnyxAstFlags { - // Top-level flags - 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; - -typedef enum OnyxUnaryOp { - ONYX_UNARY_OP_NEGATE, - ONYX_UNARY_OP_NOT, - ONYX_UNARY_OP_CAST, -} OnyxUnaryOp; - -typedef enum OnyxBinaryOp { - ONYX_BINARY_OP_ADD = 0, - ONYX_BINARY_OP_MINUS = 1, - ONYX_BINARY_OP_MULTIPLY = 2, - ONYX_BINARY_OP_DIVIDE = 3, - ONYX_BINARY_OP_MODULUS = 4, - - ONYX_BINARY_OP_EQUAL = 5, - ONYX_BINARY_OP_NOT_EQUAL = 6, - ONYX_BINARY_OP_LESS = 7, - ONYX_BINARY_OP_LESS_EQUAL = 8, - ONYX_BINARY_OP_GREATER = 9, - ONYX_BINARY_OP_GREATER_EQUAL = 10, -} OnyxBinaryOp; - -// NOTE: AstNode and AstNodeTyped need to be EXACTLY the same for -// all arguments existing in AstNode. I do this to avoid a nested -// "inheiritance" where you would have to say node.base.base.next -// for example -struct AstNode { - AstNodeKind kind; - u32 flags; - OnyxToken *token; - AstNode *next; -}; - -struct AstNodeTyped { - AstNodeKind kind; - u32 flags; - OnyxToken *token; - AstNode *next; - TypeInfo *type; -}; - -struct AstNodeBinOp { - AstNodeTyped base; - - OnyxBinaryOp operation; - - AstNodeTyped *left, *right; -}; - -struct AstNodeUnaryOp { - AstNodeTyped base; - - OnyxUnaryOp operation; - - AstNodeTyped *expr; -}; - -struct AstNodeAssign { - AstNode base; - - AstNodeTyped* lval; - AstNodeTyped* expr; -}; - -struct AstNodeNumLit { - AstNodeTyped base; - - union { i32 i; i64 l; f32 f; f64 d; } value; -}; - -struct AstNodeLocal { - AstNodeTyped base; - - AstNodeLocal *prev_local; -}; - -struct AstNodeReturn { - AstNode base; - - AstNodeTyped* expr; -}; - -struct AstNodeScope { - AstNode base; - - AstNodeScope *prev_scope; - AstNodeLocal *last_local; -}; - -struct AstNodeBlock { - AstNode base; - - AstNode *body; - AstNodeScope *scope; -}; - -struct AstNodeIf { - AstNode base; - - AstNodeTyped *cond; - AstNode *true_block; - AstNode *false_block; -}; - -struct AstNodeWhile { - AstNode base; - - AstNodeTyped *cond; - AstNodeBlock *body; -}; - -struct AstNodeFunction { - AstNodeTyped base; - - AstNodeBlock *body; - AstNodeLocal *params; -}; - -struct AstNodeForeign { - AstNode base; - - OnyxToken *mod_token, *name_token; - AstNode *import; -}; - -struct AstNodeGlobal { - AstNodeTyped base; - - AstNodeTyped *initial_value; -}; - -struct AstNodeCall { - AstNodeTyped base; - - AstNode *callee; // NOTE: Function definition node - AstNodeArgument *arguments; // NOTE: Expressions that form the actual param list - // They will be chained down using the "next" property - // unless this becomes used by something else -}; - -struct AstNodeArgument { - AstNodeTyped base; - - AstNodeTyped *value; -}; - -struct AstNodeUse { - AstNode base; - - OnyxToken *filename; -}; - -typedef struct OnyxProgram { - bh_arr(AstNodeUse *) uses; - bh_arr(AstNodeGlobal *) globals; - bh_arr(AstNodeFunction *) functions; - bh_arr(AstNodeForeign *) foreigns; -} OnyxProgram; - const char* onyx_ast_node_kind_string(AstNodeKind kind); void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind); OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs); diff --git a/include/onyxsempass.h b/include/onyxsempass.h index 2e4b1d22..a2bb7918 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -4,7 +4,7 @@ #include "bh.h" #include "onyxlex.h" -#include "onyxparser.h" +#include "onyxastnodes.h" #include "onyxmsgs.h" typedef struct SemPassSymbol { diff --git a/include/onyxutils.h b/include/onyxutils.h index fa325d8c..86cac2fa 100644 --- a/include/onyxutils.h +++ b/include/onyxutils.h @@ -1,6 +1,6 @@ #include "bh.h" -#include "onyxparser.h" +#include "onyxastnodes.h" extern bh_scratch global_scratch; extern bh_allocator global_scratch_allocator; @@ -8,4 +8,6 @@ extern bh_allocator global_scratch_allocator; extern bh_managed_heap global_heap; extern bh_allocator global_heap_allocator; +const char* onyx_ast_node_kind_string(AstNodeKind kind); + void onyx_ast_print(AstNode* program, i32 indent); diff --git a/include/onyxwasm.h b/include/onyxwasm.h index 1e6dcb90..8ac9bf07 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -3,7 +3,7 @@ #include "bh.h" -#include "onyxparser.h" +#include "onyxastnodes.h" #include "onyxmsgs.h" typedef u8 WasmType; diff --git a/onyx b/onyx index abdad2c4..1ca270bf 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyxparser.c b/src/onyxparser.c index 55d84acb..0d203444 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -6,38 +6,6 @@ // NOTE: The one weird define you need to know before read the code below #define make_node(nclass, kind) onyx_ast_node_new(parser->allocator, sizeof(nclass), kind) -static const char* ast_node_names[] = { - "ERROR", - "PROGRAM", - "USE", - - "FUNCTION", - "FOREIGN", - "BLOCK", - "SCOPE", - "LOCAL", - "GLOBAL", - "SYMBOL", - - "UN_OP", - "BIN_OP", - - "TYPE", - "LITERAL", - "PARAM", - "ARGUMENT", - "CALL", - "ASSIGN", - "RETURN", - - "IF", - "WHILE", - "BREAK", - "CONTINUE", - - "AST_NODE_KIND_COUNT", -}; - struct TypeInfo builtin_types[] = { { TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, { TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, @@ -526,6 +494,7 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { AstNodeAssign* assign_node = make_node(AstNodeAssign, AST_NODE_KIND_ASSIGNMENT); + // TODO: Maybe I don't need to make another lval node? AstNode* lval = make_node(AstNode, AST_NODE_KIND_SYMBOL); lval->token = symbol; assign_node->lval = (AstNodeTyped *) lval; @@ -885,10 +854,6 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) { -const char* onyx_ast_node_kind_string(AstNodeKind kind) { - return ast_node_names[kind]; -} - // NOTE: This returns a void* so I don't need to cast it everytime I use it void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind) { void* node = bh_alloc(alloc, size); diff --git a/src/onyxutils.c b/src/onyxutils.c index b5537cb4..53c2f0ff 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -1,6 +1,6 @@ #include "onyxutils.h" #include "onyxlex.h" -#include "onyxparser.h" +#include "onyxastnodes.h" bh_scratch global_scratch; bh_allocator global_scratch_allocator; @@ -8,6 +8,44 @@ bh_allocator global_scratch_allocator; bh_managed_heap global_heap; bh_allocator global_heap_allocator; +static const char* ast_node_names[] = { + "ERROR", + "PROGRAM", + "USE", + + "FUNCTION", + "FOREIGN", + "BLOCK", + "SCOPE", + "LOCAL", + "GLOBAL", + "SYMBOL", + + "UN_OP", + "BIN_OP", + + "TYPE", + "LITERAL", + "PARAM", + "ARGUMENT", + "CALL", + "ASSIGN", + "RETURN", + + "IF", + "WHILE", + "BREAK", + "CONTINUE", + + "AST_NODE_KIND_COUNT", +}; + +const char* onyx_ast_node_kind_string(AstNodeKind kind) { + return ast_node_names[kind]; +} + + + #define print_indent { if (indent > 0) bh_printf("\n"); for (int i = 0; i < indent; i++) bh_printf(" "); } void onyx_ast_print(AstNode* node, i32 indent) {