summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSupercip971 <supercyp971@gmail.com>2022-05-26 17:15:49 +0000
committerSupercip971 <supercyp971@gmail.com>2022-05-26 17:15:49 +0000
commit4ba593e588f6ba25118e9dc80f47eec7f3db5150 (patch)
tree9b3e242e256ff098d47ff8ff2c62329e50cc9fe5
parent23543b80fea663d929c5a5621466412ad2bf9459 (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.c53
-rw-r--r--sources/libs/udfore/ast/dump.h7
-rw-r--r--sources/libs/udfore/ast/type/decl.h9
-rw-r--r--sources/libs/udfore/ast/type/expr.h51
-rw-r--r--sources/libs/udfore/ast/type/type.h13
-rw-r--r--sources/libs/udfore/ast/type/val.h9
-rw-r--r--sources/libs/udfore/ast/types.c11
-rw-r--r--sources/libs/udfore/ast/types.h24
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);