summaryrefslogtreecommitdiff
path: root/src/compiler/ast-tree.c
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-23 15:39:11 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-23 15:39:11 +0330
commitf91fc3bac670a8c775c7ea7b8ba8789dba9559ad (patch)
treee227022c0c2fa09fc52f47519f3c1815590651b8 /src/compiler/ast-tree.c
parent157475f0bd929a9b42b6cd9a4ca7f4fc4e64bf71 (diff)
prepairing more for importing
Diffstat (limited to 'src/compiler/ast-tree.c')
-rw-r--r--src/compiler/ast-tree.c145
1 files changed, 140 insertions, 5 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 16b2682..c93b477 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -5,8 +5,10 @@
#include "utils/log.h"
#include "utils/memory.h"
#include "utils/string.h"
+#include "utils/type.h"
#include <stddef.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
AstTree AST_TREE_TYPE_TYPE = {
@@ -177,6 +179,12 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
const char *AST_TREE_BUILTIN_TOKEN_STRINGS[] = {
"cast",
"typeOf",
+ "import",
+};
+
+AstTreeRoots AST_TREE_ROOTS_ERROR = {
+ .data = NULL,
+ .size = -1ULL,
};
void astTreePrint(const AstTree *tree, int indent) {
@@ -823,6 +831,13 @@ void astTreeRootDelete(AstTreeRoot *root) {
free(root);
}
+void astTreeRootsDestroy(AstTreeRoots roots) {
+ for (size_t i = 0; i < roots.size; ++i) {
+ astTreeRootDelete(roots.data[i]);
+ }
+ free(roots.data);
+}
+
AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type,
char *str_begin, char *str_end) {
AstTree *result = a404m_malloc(sizeof(*result));
@@ -1243,7 +1258,120 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables,
return result;
}
-AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
+AstTreeRoots makeAstTree(const char *filePath) {
+ size_t parserNodes_capacity = 1;
+ ParserNode **parserNodes =
+ a404m_malloc(parserNodes_capacity * sizeof(*parserNodes));
+ size_t parserNodes_size = 1;
+
+ parserNodes[0] = parserFromPath(filePath);
+
+ size_t roots_size = 0;
+ AstTreeRoots roots = {
+ .data = a404m_malloc(roots_size * sizeof(*roots.data)),
+ .size = 0,
+ };
+
+ for (size_t i = 0; i < parserNodes_size; ++i) {
+ ParserNode *parserNode = parserNodes[i];
+ AstTreeRoot *root = makeAstRoot(parserNode);
+ if (root == NULL) {
+ goto RETURN_ERROR;
+ }
+ for (size_t i = 0; i < root->trees.size; ++i) {
+ AstTree *tree = root->trees.data[i];
+ if (tree->token == AST_TREE_TOKEN_FUNCTION_CALL) {
+ AstTreeFunctionCall *tree_metadata = tree->metadata;
+ AstTree *operand = tree_metadata->function;
+ if (operand->token == AST_TREE_TOKEN_BUILTIN) {
+ AstTreeBuiltin *operand_metadata = operand->metadata;
+ if (operand_metadata->token == AST_TREE_BUILTIN_TOKEN_IMPORT) {
+ if (tree_metadata->parameters_size != 1) {
+ printError(tree->str_begin, tree->str_end,
+ "Too many or too few arguments");
+ goto RETURN_ERROR;
+ }
+ AstTreeSetTypesHelper helper = {
+ .lookingType = NULL,
+ .dependencies.data = NULL,
+ .dependencies.size = 0,
+ .variables = root->variables,
+ };
+ if (!setAllTypes(tree, helper, NULL, NULL)) {
+ goto RETURN_ERROR;
+ }
+ AstTree *parameter = tree_metadata->parameters[0].value;
+ if (!isConstByValue(parameter)) {
+ printError(parameter->str_begin, parameter->str_end,
+ "Is not constant");
+ goto RETURN_ERROR;
+ }
+ parameter = getValue(parameter);
+ if (parameter == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ AstTreeBracket *type_metadata =
+ a404m_malloc(sizeof(*type_metadata));
+ type_metadata->operand = &AST_TREE_U8_TYPE;
+
+ type_metadata->parameters.size = 0;
+ type_metadata->parameters.data =
+ a404m_malloc(0 * sizeof(*type_metadata->parameters.data));
+
+ AstTree *type = newAstTree(AST_TREE_TOKEN_TYPE_ARRAY, type_metadata,
+ &AST_TREE_TYPE_TYPE, NULL, NULL);
+
+ if (!typeIsEqual(type, parameter->type)) {
+ printError(parameter->str_begin, parameter->str_end,
+ "Type mismatch (must be a []u8 aka string)");
+ goto RETURN_ERROR;
+ }
+
+ char *str = u8ArrayToCString(parameter);
+
+ const size_t imported_size =
+ a404m_malloc_usable_size(root->imported) /
+ sizeof(*root->imported);
+ if (imported_size == root->imported_size) {
+ root->imported = a404m_realloc(
+ root->imported, (imported_size + imported_size / 2 + 1) *
+ sizeof(*root->imported));
+ }
+ root->imported[root->imported_size++] = str;
+
+ astTreeDelete(type);
+ }
+ }
+ }
+ }
+
+ if (roots_size == roots.size) {
+ roots_size += roots_size / 2 + 13;
+ roots.data = a404m_realloc(roots.data, roots_size);
+ }
+ roots.data[roots.size++] = root;
+ }
+
+ for (size_t i = 0; i < roots.size; ++i) {
+ AstTreeRoot *root = roots.data[i];
+ if (!setAllTypesRoot(root)) {
+ goto RETURN_ERROR;
+ }
+ }
+
+ for (size_t i = 0; i < parserNodes_size; ++i) {
+ parserNodeDelete(parserNodes[i]);
+ }
+ free(parserNodes);
+
+ return roots;
+
+RETURN_ERROR:
+ return AST_TREE_ROOTS_ERROR;
+}
+
+AstTreeRoot *makeAstRoot(ParserNode *parsedRoot) {
if (parsedRoot->token != PARSER_TOKEN_ROOT) {
return NULL;
}
@@ -1255,6 +1383,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
root->variables.data =
a404m_malloc(nodes->size * sizeof(*root->variables.data));
root->variables.size = 0;
+ root->imported = a404m_malloc(0 * sizeof(*root->imported));
+ root->imported_size = 0;
AstTreeVariables *variables = &root->variables;
static const size_t variables_size = 1;
@@ -1450,10 +1580,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
}
}
- if (!setAllTypesRoot(root)) {
- goto RETURN_ERROR;
- }
-
return root;
RETURN_ERROR:
@@ -4712,3 +4838,12 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper _helper) {
return setAllTypes(infix->right, helper, NULL, NULL);
}
+
+char *u8ArrayToCString(AstTree *tree) {
+ AstTreeObject *object = tree->metadata;
+ char *str = a404m_malloc((object->variables.size + 1) * sizeof(*str));
+ for (size_t i = 0; i < object->variables.size; ++i) {
+ str[i] = *(AstTreeInt *)object->variables.data[i]->value->metadata;
+ }
+ return str;
+}