diff options
Diffstat (limited to 'src/compiler/tree_parser/tree_parser.c')
-rw-r--r-- | src/compiler/tree_parser/tree_parser.c | 211 |
1 files changed, 140 insertions, 71 deletions
diff --git a/src/compiler/tree_parser/tree_parser.c b/src/compiler/tree_parser/tree_parser.c index cb1ef4c..fd1dabb 100644 --- a/src/compiler/tree_parser/tree_parser.c +++ b/src/compiler/tree_parser/tree_parser.c @@ -6,12 +6,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <utils/file.h> #include <utils/memory/memory.h> - -#include "utils/types.h" +#include <utils/types.h> const char *TREE_TOKEN_STRINGS[] = { "TREE_TOKEN_NONE", + "TREE_TOKEN_ROOT", "TREE_TOKEN_GLOBAL_SCOPE", "TREE_TOKEN_LOCAL_SCOPE", "TREE_TOKEN_FUNCTION_CALL", @@ -32,6 +33,7 @@ void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) { switch (parsedTree->token) { case TREE_TOKEN_NONE: goto RETURN_SUCCESS; + case TREE_TOKEN_ROOT: case TREE_TOKEN_GLOBAL_SCOPE: case TREE_TOKEN_LOCAL_SCOPE: case TREE_TOKEN_FUNCTION_CALL: @@ -60,6 +62,7 @@ void deleteParsedTree(ParsedTree *parsedTree) { switch (parsedTree->token) { case TREE_TOKEN_NONE: goto RETURN_SUCCESS; + case TREE_TOKEN_ROOT: case TREE_TOKEN_GLOBAL_SCOPE: case TREE_TOKEN_LOCAL_SCOPE: { TreeScopeMetadata *metadata = parsedTree->metadata; @@ -129,17 +132,41 @@ RETURN_SUCCESS: free(parsedTree); } -ParsedTree *treeParser(SourceCode code) { - ParsedNode *parsedNode = parser(code); +ParsedTree *treeParser(SourceCode *code) { + ParserScopeMetadata *scope = a404m_malloc(sizeof(*scope)); + scope->operands_size = 0; + scope->operands = a404m_malloc(scope->operands_size * sizeof(ParsedNode *)); + ParsedNode *const parsedNode = + newParsedNode(NULL, NULL, PARSED_TOKEN_ROOT, scope, NULL); + + for (size_t i = 0; i < code->size; ++i) { + ParsedNode *const nParsedNode = parser(code, i); + ParserScopeMetadata *const nscope = nParsedNode->metadata; + for (size_t j = 0; j < nscope->operands_size; ++j) { + size_t scopeSize = + a404m_malloc_usable_size(scope->operands) / sizeof(ParsedNode *); + if (scopeSize == scope->operands_size) { + scopeSize += scopeSize / 2 + 1; + scope->operands = + a404m_realloc(scope->operands, scopeSize * sizeof(ParsedNode *)); + } + scope->operands[scope->operands_size] = nscope->operands[j]; + scope->operands_size += 1; + } + free(nscope->operands); + nscope->operands = NULL; + nscope->operands_size = 0; + deleteParsedNode(nParsedNode); + } if (parsedNode == NULL) { return NULL; } - ParsedTree *tree= _treeParser(parsedNode, code); + ParsedTree *tree = _treeParser(parsedNode, code); deleteParsedNode(parsedNode); return tree; } -ParsedTree *_treeParser(const ParsedNode *node, SourceCode code) { +ParsedTree *_treeParser(const ParsedNode *node, SourceCode *code) { if (node->token == PARSED_TOKEN_ROOT) { return treeParseRoot(node, code); } else { @@ -147,9 +174,8 @@ ParsedTree *_treeParser(const ParsedNode *node, SourceCode code) { } } -ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseNode(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { switch (node->token) { case PARSED_TOKEN_ROOT: case PARSED_TOKEN_NONE: @@ -183,6 +209,8 @@ ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, return treeParseStruct(node, code, scopes, scopes_size); case PARSED_TOKEN_FUNCTION: return treeParseFunction(node, code, scopes, scopes_size); + case PARSED_TOKEN_IMPORT: + return treeParseImport(node, code, scopes, scopes_size); case PARSED_TOKEN_FUNCTION_PARAMS: } fprintf(stderr, "bad parsed token %d at %s:%d", node->token, __FILE_NAME__, @@ -190,9 +218,8 @@ ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, return NULL; } -ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { switch (node->token) { case PARSED_TOKEN_ROOT: case PARSED_TOKEN_NONE: @@ -201,6 +228,7 @@ ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, case PARSED_TOKEN_DEFINE_VARIABLE: case PARSED_TOKEN_DEFINE_CONSTANT: case PARSED_TOKEN_CODE_BODY: + case PARSED_TOKEN_IMPORT: printError("Parsed token %s is not an expression", code, node->strBegin, node->strEnd, PARSED_TOKEN_STRINGS[node->token]); return NULL; @@ -217,12 +245,12 @@ ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, return NULL; } -ParsedTree *treeParseRoot(const ParsedNode *node, SourceCode code) { +ParsedTree *treeParseRoot(const ParsedNode *node, SourceCode *code) { return treeParseLocalScope(node, code, NULL, 0); } -ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const ParserScopeMetadata *node_metadata = node->metadata; ParsedNode **const operands = node_metadata->operands; @@ -236,55 +264,41 @@ ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, TreeScopeMetadata *metadata = tree->metadata = a404m_malloc(sizeof(*metadata)); - size_t metadata_variables_size = 0; - metadata->variables = a404m_malloc(metadata_variables_size * - sizeof(TreeDefineVariableMetadata *)); + metadata->variables = a404m_malloc(0); metadata->variables_size = 0; - size_t metadata_lines_size = 0; - metadata->lines = a404m_malloc(metadata_lines_size * sizeof(ParsedTree *)); + metadata->lines = a404m_malloc(0); metadata->lines_size = 0; const size_t newScopes_size = scopes_size + 1; - const TreeScopeMetadata *newScopes[newScopes_size]; - - for (size_t i = 0; i < scopes_size; ++i) { - newScopes[i] = scopes[i]; - } + TreeScopeMetadata *newScopes[newScopes_size]; + memcpy(newScopes, scopes, scopes_size); newScopes[newScopes_size - 1] = metadata; for (size_t i = 0; i < operands_size; ++i) { - const ParsedNode *operand = operands[i]; + const ParsedNode *const operand = operands[i]; ParsedTree *const parsedTree = treeParseNode(operand, code, newScopes, newScopes_size); if (parsedTree == NULL) { goto RETURN_ERROR; } switch (parsedTree->token) { + case TREE_TOKEN_ROOT: + printError("It is not allowed here", code, operand->strBegin, + operand->strEnd); + goto RETURN_ERROR; case TREE_TOKEN_DEFINE_CONSTANT: case TREE_TOKEN_DEFINE_VARIABLE: { TreeDefineVariableMetadata *const variableDefine = parsedTree->metadata; if (variableDefine == NULL) { goto RETURN_ERROR; - } else if (metadata->variables_size == metadata_variables_size) { - metadata_variables_size += metadata_variables_size / 2 + 1; - metadata->variables = a404m_realloc( - metadata->variables, - metadata_variables_size * sizeof(TreeDefineVariableMetadata *)); } - metadata->variables[metadata->variables_size] = variableDefine; - metadata->variables_size += 1; + pushVariableToScope(metadata, variableDefine); } /* fall through */ default: - if (metadata->lines_size == metadata_lines_size) { - metadata_lines_size += metadata_lines_size / 2 + 1; - metadata->lines = a404m_realloc( - metadata->lines, metadata_lines_size * sizeof(ParsedTree *)); - } - metadata->lines[metadata->lines_size] = parsedTree; - metadata->lines_size += 1; + pushLineToScope(metadata, parsedTree); continue; } printError("'%s' Is not allowed here", code, operand->strBegin, @@ -303,9 +317,11 @@ RETURN_ERROR: return NULL; } -TreeDefineVariableMetadata *treeParseDefineVariable( - ParsedTree *tree, const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], size_t scopes_size) { +TreeDefineVariableMetadata *treeParseDefineVariable(ParsedTree *tree, + const ParsedNode *node, + SourceCode *code, + TreeScopeMetadata *scopes[], + size_t scopes_size) { TreeDefineVariableMetadata *define = a404m_malloc(sizeof(*define)); define->tree = tree; @@ -356,14 +372,14 @@ RETURN_ERROR: } TreeDefineVariableMetadata *getVariable(const char *strBegin, - const char *strEnd, SourceCode code, - const TreeScopeMetadata *scopes[], + const char *strEnd, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const size_t size = strEnd - strBegin; const char *str = strBegin; for (size_t i = 0; i < scopes_size; ++i) { - const TreeScopeMetadata *scope = scopes[i]; + TreeScopeMetadata *scope = scopes[i]; for (size_t j = scope->variables_size - 1; j != (typeof(j))-1; --j) { TreeDefineVariableMetadata *variable = scope->variables[j]; const size_t variable_str_size = variable->nameEnd - variable->nameBegin; @@ -378,8 +394,8 @@ TreeDefineVariableMetadata *getVariable(const char *strBegin, return NULL; } -ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { TreeDefineVariableMetadata *variable = getVariable(node->strBegin, node->strEnd, code, scopes, scopes_size); @@ -396,8 +412,8 @@ ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, return NULL; } -ParsedTree *treeParseFunctionCall(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseFunctionCall(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { ParserFunctionCallMetadata *node_metadata = node->metadata; @@ -449,7 +465,7 @@ RETURN_ERROR: return NULL; } -ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode code) { +ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode *code) { ParsedTree *const tree = a404m_malloc(sizeof(*tree)); tree->token = TREE_TOKEN_VALUE_STRING; tree->strBegin = node->strBegin; @@ -461,8 +477,9 @@ ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode code) { return tree; } -ParsedTree *treeParseVariableDefinition(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseVariableDefinition(const ParsedNode *node, + SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size, TreeToken token) { ParsedTree *const tree = a404m_malloc(sizeof(*tree)); tree->token = token; @@ -476,9 +493,8 @@ ParsedTree *treeParseVariableDefinition(const ParsedNode *node, SourceCode code, return tree; } -ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const ParserStructMetadata *node_metadata = node->metadata; ParsedTree *const tree = a404m_malloc(sizeof(*tree)); @@ -503,9 +519,8 @@ ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, return tree; } -ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const ParserFunctionMetadata *node_metadata = node->metadata; ParsedTree *const tree = a404m_malloc(sizeof(*tree)); @@ -528,9 +543,7 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, const ParserScopeMetadata *params = node_metadata->params->metadata; - size_t metadata_params_size = 0; - metadata->params = - a404m_malloc(metadata_params_size * sizeof(TreeDefineVariableMetadata *)); + metadata->params = a404m_malloc(0); metadata->params_size = 0; for (size_t i = 0; i < params->operands_size; ++i) { @@ -540,6 +553,8 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, if (define == NULL) { goto RETURN_ERROR; } + size_t metadata_params_size = a404m_malloc_usable_size(metadata->params) / + sizeof(ParserScopeMetadata *); if (metadata->params_size == metadata_params_size) { metadata_params_size += metadata_params_size / 2 + 1; metadata->params = a404m_realloc( @@ -556,8 +571,7 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, if (node_metadata->body != NULL) { printError("Not implemented", code, node->strBegin, node->strEnd); - free(metadata); - free(tree); + goto RETURN_ERROR; return NULL; } else { metadata->scope = NULL; @@ -571,6 +585,32 @@ RETURN_ERROR: return NULL; } +ParsedTree *treeParseImport(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { + const ParserImportMetadata *node_metadata = node->metadata; + SizedString *path = nodeToString(node_metadata, code); + if (path == NULL) { + return NULL; + } + + Code *fileCode = read_whole_file(path->str); + if (fileCode == NULL) { + goto RETURN_ERROR; + } + pushToSourceCode(code, fileCode); + + ParsedNode *parsedNode = parser(code, code->size - 1); + + if (parsedNode == NULL) { + goto RETURN_ERROR; + } + return _treeParser(parsedNode, code); +RETURN_ERROR: + free(path->str); + free(path); + return NULL; +} + TypeId getTreeExpressionType(ParsedTree *tree) { switch (tree->token) { case TREE_TOKEN_FUNCTION_CALL: @@ -590,6 +630,7 @@ TypeId getTreeExpressionType(ParsedTree *tree) { case TREE_TOKEN_FUNCTION: // TODO: find a better way for function return tree; case TREE_TOKEN_NONE: + case TREE_TOKEN_ROOT: } fprintf(stderr, "bad parsed tree token %d at %d:%s", tree->token, __LINE__, __FILE_NAME__); @@ -613,20 +654,22 @@ bool isType(ParsedTree *const tree) { case TREE_TOKEN_VALUE_STRING: case TREE_TOKEN_GLOBAL_SCOPE: case TREE_TOKEN_LOCAL_SCOPE: + case TREE_TOKEN_ROOT: return false; case TREE_TOKEN_STRUCT: case TREE_TOKEN_FUNCTION: // TODO: find a better way for function return true; case TREE_TOKEN_NONE: + break; } fprintf(stderr, "bad parsed tree token %d at %d:%s", tree->token, __LINE__, __FILE_NAME__); exit(1); } -SizedString *nodeToString(ParsedNode const *tree, SourceCode code) { - const char *strBegin = tree->strBegin + 1; - const char *strEnd = tree->strEnd - 1; +SizedString *nodeToString(ParsedNode const *node, SourceCode *code) { + const char *strBegin = node->strBegin + 1; + const char *strEnd = node->strEnd - 1; char *str = a404m_malloc((strEnd - strBegin + 1) * sizeof(char)); size_t inserted = 0; @@ -670,13 +713,13 @@ SizedString *nodeToString(ParsedNode const *tree, SourceCode code) { /* c = '';*/ /* break;*/ default: - printError("Bad escape code '\\%s'", code, tree->strBegin, - tree->strEnd, *iter); + printError("Bad escape code '\\%s'", code, node->strBegin, + node->strEnd, *iter); goto RETURN_ERROR; } } else { - printError("Expected character after '\\'", code, tree->strBegin, - tree->strEnd); + printError("Expected character after '\\'", code, node->strBegin, + node->strEnd); goto RETURN_ERROR; } } @@ -693,3 +736,29 @@ RETURN_ERROR: free(str); return NULL; } + +void pushVariableToScope(TreeScopeMetadata *scope, + TreeDefineVariableMetadata *variable) { + size_t scope_variables_size = a404m_malloc_usable_size(scope->variables) / + sizeof(TreeDefineVariableMetadata *); + if (scope->variables_size == scope_variables_size) { + scope_variables_size += scope_variables_size / 2 + 1; + scope->variables = a404m_realloc( + scope->variables, + scope_variables_size * sizeof(TreeDefineVariableMetadata *)); + } + scope->variables[scope->variables_size] = variable; + scope->variables_size += 1; +} + +void pushLineToScope(TreeScopeMetadata *scope, ParsedTree *line) { + size_t scope_lines_size = + a404m_malloc_usable_size(scope->lines) / sizeof(ParsedTree *); + if (scope->lines_size == scope_lines_size) { + scope_lines_size += scope_lines_size / 2 + 1; + scope->lines = + a404m_realloc(scope->lines, scope_lines_size * sizeof(ParsedTree *)); + } + scope->lines[scope->lines_size] = line; + scope->lines_size += 1; +} |