diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-04-23 15:39:11 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-04-23 15:39:11 +0330 |
commit | f91fc3bac670a8c775c7ea7b8ba8789dba9559ad (patch) | |
tree | e227022c0c2fa09fc52f47519f3c1815590651b8 /src/compiler | |
parent | 157475f0bd929a9b42b6cd9a4ca7f4fc4e64bf71 (diff) |
prepairing more for importing
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/ast-tree.c | 145 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 16 | ||||
-rw-r--r-- | src/compiler/parser.c | 18 | ||||
-rw-r--r-- | src/compiler/parser.h | 1 |
4 files changed, 174 insertions, 6 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; +} diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 0360f7e..300be41 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -128,8 +128,17 @@ typedef struct AstTrees { typedef struct AstTreeRoot { AstTreeVariables variables; AstTrees trees; + char **imported; + size_t imported_size; } AstTreeRoot; +typedef struct AstTreeRoots { + AstTreeRoot **data; + size_t size; +} AstTreeRoots; + +extern AstTreeRoots AST_TREE_ROOTS_ERROR; + typedef struct AstTreeScope { AstTreeVariables variables; AstTree **expressions; @@ -237,6 +246,7 @@ typedef struct AstTreeBracket { typedef enum AstTreeBuiltinToken { AST_TREE_BUILTIN_TOKEN_CAST, AST_TREE_BUILTIN_TOKEN_TYPE_OF, + AST_TREE_BUILTIN_TOKEN_IMPORT, AST_TREE_BUILTIN_TOKEN__SIZE__, } AstTreeBuiltinToken; @@ -256,6 +266,7 @@ void astTreeVariableDelete(AstTreeVariable *variable); void astTreeDelete(AstTree *tree); bool astTreeShouldDelete(AstTree *tree); void astTreeRootDelete(AstTreeRoot *root); +void astTreeRootsDestroy(AstTreeRoots roots); AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type, char *str_begin, char *str_end); @@ -268,7 +279,8 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables, AstTreeVariables newVariables[], size_t variables_size); -AstTreeRoot *makeAstTree(ParserNode *parsedRoot); +AstTreeRoots makeAstTree(const char *filePath); +AstTreeRoot *makeAstRoot(ParserNode *parsedRoot); bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables, AstTreeVariable *variable); @@ -368,3 +380,5 @@ bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesAstVariable(AstTreeVariable *variable, AstTreeSetTypesHelper helper); bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper); + +char *u8ArrayToCString(AstTree *tree); diff --git a/src/compiler/parser.c b/src/compiler/parser.c index f5009e5..f0d3e9b 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -1,6 +1,7 @@ #include "parser.h" #include "compiler/lexer.h" +#include "utils/file.h" #include "utils/log.h" #include "utils/memory.h" #include "utils/string.h" @@ -667,6 +668,23 @@ ParserNode *newParserNode(ParserToken token, char *str_begin, char *str_end, return parserNode; } +ParserNode *parserFromPath(const char *filePath) { + char *code = readWholeFile(filePath); + if (code == NULL) { + return NULL; + } + + LexerNodeArray lexed = lexer(code); + if (lexerNodeArrayIsError(lexed)) { + return NULL; + } + + ParserNode *root = parser(lexed); + lexerNodeArrayDestroy(lexed); + + return root; +} + ParserNode *parser(LexerNodeArray lexed) { ParserNode *root = newParserNode(PARSER_TOKEN_ROOT, NULL, NULL, NULL, NULL); if (parserNodeArray(lexed.data, lexed.data + lexed.size, root)) { diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 326849b..ecc6159 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -175,6 +175,7 @@ typedef struct ParserNodeBracketMetadata { void parserNodePrint(const ParserNode *node, int indent); void parserNodeDelete(ParserNode *node); +ParserNode *parserFromPath(const char *filePath); ParserNode *parser(LexerNodeArray lexed); bool parserNodeArray(LexerNode *begin, LexerNode *end, ParserNode *parent); |