From f91fc3bac670a8c775c7ea7b8ba8789dba9559ad Mon Sep 17 00:00:00 2001 From: A404M Date: Wed, 23 Apr 2025 15:39:11 +0330 Subject: prepairing more for importing --- src/compiler/ast-tree.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++-- src/compiler/ast-tree.h | 16 +++++- src/compiler/parser.c | 18 ++++++ src/compiler/parser.h | 1 + src/main.c | 61 ++------------------ src/runner/runner.c | 31 ++++++----- src/runner/runner.h | 2 +- 7 files changed, 198 insertions(+), 76 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 #include +#include #include 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); diff --git a/src/main.c b/src/main.c index 04640af..fad415b 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include "compiler/ast-tree.h" #include "runner/runner.h" #include "utils/file.h" #include "utils/log.h" @@ -34,52 +35,16 @@ static void printTime(struct timespec time) { } #endif -static int runWithoutRead(char *code) { +static int run(const char *filePath) { #ifdef PRINT_STATISTICS struct timespec start, end; - struct timespec lexTime; - struct timespec parseTime; struct timespec astTime; struct timespec runTime; struct timespec totalTime = {0}; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); #endif - LexerNodeArray lexed = lexer(code); - if (lexerNodeArrayIsError(lexed)) { - return 1; - } -#ifdef PRINT_STATISTICS - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); - lexTime = diff(end, start); - totalTime = add(totalTime, lexTime); -#endif -#ifdef PRINT_COMPILE_TREE - lexerNodeArrayPrint(lexed); -#endif -#ifdef PRINT_STATISTICS - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); -#endif - - ParserNode *parsedRoot = parser(lexed); - lexerNodeArrayDestroy(lexed); - if (parsedRoot == NULL) { - return 1; - } -#ifdef PRINT_STATISTICS - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); - parseTime = diff(end, start); - totalTime = add(totalTime, parseTime); -#endif -#ifdef PRINT_COMPILE_TREE - parserNodePrint(parsedRoot, 0); -#endif -#ifdef PRINT_STATISTICS - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); -#endif - - AstTreeRoot *astTree = makeAstTree(parsedRoot); - parserNodeDelete(parsedRoot); - if (astTree == NULL) { + AstTreeRoots astTrees = makeAstTree(filePath); + if (astTrees.size == AST_TREE_ROOTS_ERROR.size) { return 1; } #ifdef PRINT_STATISTICS @@ -95,12 +60,12 @@ static int runWithoutRead(char *code) { #endif int ret; - if (runAstTree(astTree)) { + if (runAstTree(astTrees)) { ret = 0; } else { ret = 1; } - astTreeRootDelete(astTree); + astTreeRootsDestroy(astTrees); #ifdef PRINT_STATISTICS clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); runTime = diff(end, start); @@ -108,10 +73,6 @@ static int runWithoutRead(char *code) { #endif #ifdef PRINT_STATISTICS - printf("----\nlexTime: "); - printTime(lexTime); - printf("\nparseTime: "); - printTime(parseTime); printf("\nastTime: "); printTime(astTime); printf("\nrunTime: "); @@ -124,16 +85,6 @@ static int runWithoutRead(char *code) { return ret; } -static int run(const char *filePath) { - char *code = readWholeFile(filePath); - - if (code == NULL) { - return 1; - } - - return runWithoutRead(code); -} - int main(int argc, char *argv[]) { fileInit(); diff --git a/src/runner/runner.c b/src/runner/runner.c index 7d1879d..b96f1a8 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -40,27 +40,30 @@ void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable, variable->value = value; } -bool runAstTree(AstTreeRoot *root) { +bool runAstTree(AstTreeRoots roots) { static const char MAIN_STR[] = "main"; static const size_t MAIN_STR_SIZE = (sizeof(MAIN_STR) / sizeof(*MAIN_STR)) - sizeof(*MAIN_STR); AstTreeVariable *mainVariable = NULL; - for (size_t i = 0; i < root->variables.size; ++i) { - AstTreeVariable *variable = root->variables.data[i]; - size_t name_size = variable->name_end - variable->name_begin; - if (name_size == MAIN_STR_SIZE && - strncmp(variable->name_begin, MAIN_STR, MAIN_STR_SIZE) == 0 && - variable->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { - if (mainVariable != NULL) { - printLog("Too many main variables"); - return false; + for (size_t i = 0; i < roots.size; ++i) { + AstTreeRoot *root = roots.data[i]; + for (size_t i = 0; i < root->variables.size; ++i) { + AstTreeVariable *variable = root->variables.data[i]; + size_t name_size = variable->name_end - variable->name_begin; + if (name_size == MAIN_STR_SIZE && + strncmp(variable->name_begin, MAIN_STR, MAIN_STR_SIZE) == 0 && + variable->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { + if (mainVariable != NULL) { + printLog("Too many main variables"); + return false; + } + mainVariable = variable; + } + if (!variable->isConst) { + runnerVariableSetValueWihtoutConstCheck(variable, variable->initValue); } - mainVariable = variable; - } - if (!variable->isConst) { - runnerVariableSetValueWihtoutConstCheck(variable, variable->initValue); } } diff --git a/src/runner/runner.h b/src/runner/runner.h index eef0d40..12ee241 100644 --- a/src/runner/runner.h +++ b/src/runner/runner.h @@ -7,7 +7,7 @@ void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value); void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable, AstTree *value); -bool runAstTree(AstTreeRoot *root); +bool runAstTree(AstTreeRoots roots); AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments, size_t arguments_size); -- cgit v1.2.3