diff options
Diffstat (limited to 'src/compiler/ast-tree.c')
-rw-r--r-- | src/compiler/ast-tree.c | 145 |
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; +} |