diff options
author | Supercip971 <supercyp971@gmail.com> | 2022-05-26 17:15:49 +0000 |
---|---|---|
committer | Supercip971 <supercyp971@gmail.com> | 2022-05-26 17:15:49 +0000 |
commit | 4ba593e588f6ba25118e9dc80f47eec7f3db5150 (patch) | |
tree | 9b3e242e256ff098d47ff8ff2c62329e50cc9fe5 | |
parent | 23543b80fea663d929c5a5621466412ad2bf9459 (diff) |
udfore: improved ast + ast dumpudfore
-rw-r--r-- | sources/libs/udfore/ast/ast.c (renamed from sources/libs/udfore/ast.c) | 27 | ||||
-rw-r--r-- | sources/libs/udfore/ast/ast.h (renamed from sources/libs/udfore/ast.h) | 53 | ||||
-rw-r--r-- | sources/libs/udfore/ast/dump.c | 53 | ||||
-rw-r--r-- | sources/libs/udfore/ast/dump.h | 7 | ||||
-rw-r--r-- | sources/libs/udfore/ast/type/decl.h | 9 | ||||
-rw-r--r-- | sources/libs/udfore/ast/type/expr.h | 51 | ||||
-rw-r--r-- | sources/libs/udfore/ast/type/type.h | 13 | ||||
-rw-r--r-- | sources/libs/udfore/ast/type/val.h | 9 | ||||
-rw-r--r-- | sources/libs/udfore/ast/types.c | 11 | ||||
-rw-r--r-- | sources/libs/udfore/ast/types.h | 24 |
10 files changed, 238 insertions, 19 deletions
diff --git a/sources/libs/udfore/ast.c b/sources/libs/udfore/ast/ast.c index 588c684e..94384610 100644 --- a/sources/libs/udfore/ast.c +++ b/sources/libs/udfore/ast/ast.c @@ -17,12 +17,12 @@ void ud_ast_deinit(UdAst *self) UdAstPtr ud_ast_push(UdAst *self, UdAstNode node, UdAstInfo info) { - UdAstPtr r = vec_len(&self->nodes); + int r = vec_len(&self->nodes); vec_push(&self->nodes, node); vec_push(&self->infos, info); - return r; + return ud_ast_ptr_node$(r); } UdAstPtr ud_ast_push_no_info(UdAst *self, UdAstNode node) @@ -38,44 +38,46 @@ UdAstPtr ud_ast_push_no_info(UdAst *self, UdAstNode node) UdAstPtr ud_ast_push_data(UdAst *self, UdAstData data) { - UdAstPtr r = vec_len(&self->nodes); + int r = vec_len(&self->nodes); vec_push(&self->datas, data); - return r; + return ud_ast_ptr_data$(r); } UdAstNode *ud_ast_node(UdAst *self, UdAstPtr ptr) { - return &self->nodes.data[ptr]; + assert_falsity((bool)ptr.is_data); + return &self->nodes.data[ptr.index]; } UdAstInfo *ud_ast_info(UdAst *self, UdAstPtr ptr) { - return &self->infos.data[ptr]; + assert_falsity((bool)ptr.is_data); + return &self->infos.data[ptr.index]; } UdAstPtr ud_ast_push_list(UdAst *self, UdAstPtr list_node, int list_type, UdAstPtr pushed_index) { UdAstNode *current = ud_ast_node(self, list_node); - int current_id = list_node; + UdAstPtr current_id = list_node; - assert_not_equal(pushed_index, 0); + assert_not_equal((int)pushed_index.index, 0); while (true) { assert_equal(current->type, list_type); - if (current->left == 0) + if (current->left.index == 0) { current->left = pushed_index; return pushed_index; } - else if (current->right == 0) + else if (current->right.index == 0) { UdAstNode next = { .type = list_type, - .right = 0, + .right = ud_ast_ptr_null$(), .left = pushed_index, }; @@ -96,5 +98,6 @@ UdAstPtr ud_ast_push_list(UdAst *self, UdAstPtr list_node, int list_type, UdAstP UdAstData *ud_ast_data(UdAst *self, UdAstPtr ptr) { - return &self->datas.data[ptr]; + assert_truth((bool)ptr.is_data); + return &self->datas.data[ptr.index]; } diff --git a/sources/libs/udfore/ast.h b/sources/libs/udfore/ast/ast.h index 8d1c0cf3..5445da54 100644 --- a/sources/libs/udfore/ast.h +++ b/sources/libs/udfore/ast/ast.h @@ -2,7 +2,32 @@ #pragma once #include <brutal-ds> -typedef int UdAstPtr; +// this is used because this will be extracted and put in an other library +// and the library don't know if the child is a value or a node, making dumping way more complicated than it need to be +// There is not really a difference in performance, because the parser of a language already know depending on +// the node if it is a value or not. This is only for the AST lib, and for error cheking (you don't want to read +// a data node as a ast node). + +typedef struct +{ + bool is_data : 1; // FALSE = node TRUE = data + int index : 31; +} UdAstPtr; + +#define ud_ast_ptr_node$(idx) \ + ((UdAstPtr){.is_data = false, .index = (idx)}) + +#define ud_ast_ptr_data$(idx) \ + ((UdAstPtr){.is_data = true, .index = (idx)}) + +#define ud_ast_ptr_null$() \ + ((UdAstPtr){.is_data = false, .index = 0}) + +#define is_ud_ast_null$(ptr) \ + ((ptr).index == 0 && (ptr).is_data == false) + +#define ud_ast_root$() \ + (ud_ast_ptr_node$(0)) typedef struct { @@ -24,12 +49,26 @@ typedef struct typedef Vec(UdAstInfo) UdAstInfos; -typedef union +typedef enum +{ + UD_AST_DATA_NULL, + UD_AST_DATA_BOOL, + UD_AST_DATA_CHAR, + UD_AST_DATA_STR, + UD_AST_DATA_INTEGER, + UD_AST_DATA_FLOATING, +} UdAstDataTypes; + +typedef struct { - // int data_type; - Str string; - int integer; - float floating; + char data_type; + union + { + bool boolean; + Str string; + int integer; + float floating; + }; } UdAstData; typedef Vec(UdAstData) UdAstDatas; @@ -46,7 +85,7 @@ typedef struct } UdAst; // note: the root must not have parent. -#define UD_AST_ROOT ((UdAstPtr)0) +#define UD_AST_ROOT (ud_ast_ptr_node$(0)) void ud_ast_init(UdAst *self, Alloc *alloc); diff --git a/sources/libs/udfore/ast/dump.c b/sources/libs/udfore/ast/dump.c new file mode 100644 index 00000000..30f83b3d --- /dev/null +++ b/sources/libs/udfore/ast/dump.c @@ -0,0 +1,53 @@ +#include "dump.h" + +#include "types.h" +Json ast_dump_val(UdAstData *data) +{ + + switch (data->data_type) + { + case UD_AST_DATA_BOOL: + return json_bool(data->boolean); + case UD_AST_DATA_STR: + return json_str(data->string); + case UD_AST_DATA_CHAR: + return json_str(data->string); + case UD_AST_DATA_FLOATING: + return json_str(str$("floating")); + case UD_AST_DATA_INTEGER: + return json_number(data->integer); + case UD_AST_DATA_NULL: + default: + return json_str(str$("null")); + } +} + +Json ast_dump_impl(UdAst *ast, UdAstPtr ptr, Alloc *alloc) +{ + if (ptr.is_data) + { + return ast_dump_val(ud_ast_data(ast, ptr)); + } + + UdAstNode *node = ud_ast_node(ast, ptr); + + Json res = json_object(alloc); + json_put(&res, str$("type"), json_str(udast_type_to_str(node->type))); + + if (!is_ud_ast_null$(node->left)) + { + json_put(&res, str$("left"), ast_dump_impl(ast, node->left, alloc)); + } + + if (!is_ud_ast_null$(node->right)) + { + json_put(&res, str$("right"), ast_dump_impl(ast, node->right, alloc)); + } + + return res; +} + +Json ast_dump(UdAst *ast, Alloc *alloc) +{ + return ast_dump_impl(ast, ud_ast_root$(), alloc); +} diff --git a/sources/libs/udfore/ast/dump.h b/sources/libs/udfore/ast/dump.h new file mode 100644 index 00000000..65ab4992 --- /dev/null +++ b/sources/libs/udfore/ast/dump.h @@ -0,0 +1,7 @@ +#pragma once + +#include <json> + +#include "ast.h" + +Json ast_dump(UdAst *ast, Alloc *alloc); diff --git a/sources/libs/udfore/ast/type/decl.h b/sources/libs/udfore/ast/type/decl.h new file mode 100644 index 00000000..023e9216 --- /dev/null +++ b/sources/libs/udfore/ast/type/decl.h @@ -0,0 +1,9 @@ +#pragma once + +#define FOREACH_UD_DECL_AST(DACTION) \ + DACTION(DECL_NONE) \ + DACTION(DECL_VAR) \ + DACTION(DECL_FUNC) \ + DACTION(DECL_TYPE) \ + DACTION(DECL_EXPR) \ + DACTION(DECL_LIST) diff --git a/sources/libs/udfore/ast/type/expr.h b/sources/libs/udfore/ast/type/expr.h new file mode 100644 index 00000000..71d64d61 --- /dev/null +++ b/sources/libs/udfore/ast/type/expr.h @@ -0,0 +1,51 @@ +#pragma once + +#define FOREACH_UD_EXPR_AST(EACTION) \ + EACTION(EXPR_NONE) \ + EACTION(EXPR_NEG) \ + EACTION(EXPR_RETURN) \ + EACTION(EXPR_VAL) \ + EACTION(EXPR_IF) \ + EACTION(EXPR_ELSE) \ + EACTION(EXPR_CONSTANT) \ + EACTION(EXPR_DECL_BLOCK) \ + EACTION(EXPR_IDENT) \ + EACTION(EXPR_INC) /* ++ */ \ + EACTION(EXPR_DEC) /* -- */ \ + EACTION(EXPR_ASSIGN) /* = */ \ + EACTION(EXPR_ASSIGN_ADD) /* += */ \ + EACTION(EXPR_ASSIGN_SUB) /* -= */ \ + EACTION(EXPR_ASSIGN_MULT) /* *= */ \ + EACTION(EXPR_ASSIGN_DIV) /* /= */ \ + EACTION(EXPR_ASSIGN_MOD) /* %= */ \ + EACTION(EXPR_ASSIGN_BIT_AND) /* &= */ \ + EACTION(EXPR_ASSIGN_BIT_OR) /* |= */ \ + EACTION(EXPR_ASSIGN_BIT_XOR) /* ^= */ \ + EACTION(EXPR_ASSIGN_LSHIFT) /* <<= */ \ + EACTION(EXPR_ASSIGN_RSHIFT) /* >>= */ \ + EACTION(EXPR_ADD) /* + */ \ + EACTION(EXPR_SUB) /* - */ \ + EACTION(EXPR_MULT) /* * */ \ + EACTION(EXPR_DIV) /* / */ \ + EACTION(EXPR_MOD) /* mod */ \ + EACTION(EXPR_BIT_NOT) /* ~ */ \ + EACTION(EXPR_BIT_AND) /* & */ \ + EACTION(EXPR_BIT_OR) /* | */ \ + EACTION(EXPR_BIT_XOR) /* ^ */ \ + EACTION(EXPR_LSHIFT) /* << */ \ + EACTION(EXPR_RSHIFT) /* >> */ \ + EACTION(EXPR_NOT) /* ! */ \ + EACTION(EXPR_AND) /* && */ \ + EACTION(EXPR_OR) /* || */ \ + EACTION(EXPR_EQ) /* == */ \ + EACTION(EXPR_NOT_EQ) /* != */ \ + EACTION(EXPR_LT) /* < */ \ + EACTION(EXPR_GT) /* > */ \ + EACTION(EXPR_LT_EQ) /* <= */ \ + EACTION(EXPR_GT_EQ) /* >= */ \ + EACTION(EXPR_INDEX) /* [] */ \ + EACTION(EXPR_DEREF) /* * */ \ + EACTION(EXPR_REF) /* & */ \ + EACTION(EXPR_ACCESS) /* . */ \ + EACTION(EXPR_PTR_ACCESS) /* -> */ \ + EACTION(EXPR_CALL) /* ( */ diff --git a/sources/libs/udfore/ast/type/type.h b/sources/libs/udfore/ast/type/type.h new file mode 100644 index 00000000..931fe1cb --- /dev/null +++ b/sources/libs/udfore/ast/type/type.h @@ -0,0 +1,13 @@ +#pragma once + +#define FOREACH_UD_TYPE_AST(TACTION) \ + TACTION(TYPE_NONE) \ + TACTION(TYPE_IDENT) \ + TACTION(TYPE_FUNC) \ + TACTION(TYPE_ARG_LIST) \ + TACTION(TYPE_INT) \ + TACTION(TYPE_STRING) \ + TACTION(TYPE_FLOAT) \ + TACTION(TYPE_ARRAY) \ + TACTION(TYPE_CONSTANT) \ + TACTION(TYPE_NAMED) diff --git a/sources/libs/udfore/ast/type/val.h b/sources/libs/udfore/ast/type/val.h new file mode 100644 index 00000000..b1fe2e21 --- /dev/null +++ b/sources/libs/udfore/ast/type/val.h @@ -0,0 +1,9 @@ +#pragma once +#define FOREACH_UD_CONST_AST(VACTION) \ + VACTION(CONST_STRING) \ + VACTION(CONST_IDENT) \ + VACTION(CONST_SIGNED) \ + VACTION(CONST_UNSIGNED) \ + VACTION(CONST_FLOAT) \ + VACTION(CONST_BOOL) \ + VACTION(CONST_NULL) diff --git a/sources/libs/udfore/ast/types.c b/sources/libs/udfore/ast/types.c new file mode 100644 index 00000000..c5a21664 --- /dev/null +++ b/sources/libs/udfore/ast/types.c @@ -0,0 +1,11 @@ +#include "types.h" + +#define AST2STR_FUNC(X) \ + [UDAST_##X] = #X, + +const char *udast_type2str_array[] = {FOREACH_UD_AST(AST2STR_FUNC)}; + +Str udast_type_to_str(int type) +{ + return str$(udast_type2str_array[type]); +} diff --git a/sources/libs/udfore/ast/types.h b/sources/libs/udfore/ast/types.h new file mode 100644 index 00000000..73a9c41e --- /dev/null +++ b/sources/libs/udfore/ast/types.h @@ -0,0 +1,24 @@ +#pragma once +#include <brutal-base> + +#include "type/decl.h" +#include "type/expr.h" +#include "type/type.h" +#include "type/val.h" + +#define FOREACH_UD_AST(CALL) \ + FOREACH_UD_EXPR_AST(CALL) \ + FOREACH_UD_DECL_AST(CALL) \ + FOREACH_UD_CONST_AST(CALL) \ + FOREACH_UD_TYPE_AST(CALL) \ + CALL(COUNT) + +#define UDAST_ELEMENT_ENUM_ADD(v) UDAST_##v, + +typedef enum +{ + UDAST_NONE, + FOREACH_UD_AST(UDAST_ELEMENT_ENUM_ADD) +} UDAstTypes; + +Str udast_type_to_str(int type); |