diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/code_generator/code_generator.c | 19 | ||||
-rw-r--r-- | src/compiler/code_generator/code_generator.h | 1 | ||||
-rw-r--r-- | src/compiler/fasm_generator/fasm_generator.c | 208 | ||||
-rw-r--r-- | src/compiler/fasm_generator/fasm_generator.h | 31 | ||||
-rw-r--r-- | src/compiler/lexer/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser/parser.c | 87 | ||||
-rw-r--r-- | src/compiler/parser/parser.h | 1 | ||||
-rw-r--r-- | src/compiler/tree_parser/tree_parser.c | 262 | ||||
-rw-r--r-- | src/compiler/tree_parser/tree_parser.h | 2 |
9 files changed, 505 insertions, 107 deletions
diff --git a/src/compiler/code_generator/code_generator.c b/src/compiler/code_generator/code_generator.c index 75b89c6..bf77419 100644 --- a/src/compiler/code_generator/code_generator.c +++ b/src/compiler/code_generator/code_generator.c @@ -76,6 +76,24 @@ Instructions codeGenerator(SourceCode *code) { return error; } +Instructions codeGeneratorWithPrint(SourceCode *code) { + ParsedTree *root = treeParserWithPrint(code); + if (root != NULL) { + printf("----tree parsed:\n"); + printParsedTreeNode(root); + Instructions instructions = _codeGenerator(root, code); + + deleteParsedTree(root); + return instructions; + } + fprintf(stderr, "error in tree parser\n"); + const Instructions error = { + .instructions = NULL, + .size = ERROR_SIZE, + }; + return error; +} + Instructions _codeGenerator(ParsedTree *root, SourceCode *code) { const TreeScopeMetadata *metadata = root->metadata; @@ -112,6 +130,7 @@ RETURN_ERROR: bool nodeToInstruction(ParsedTree *tree, Instruction **instructions, size_t *instructions_size, size_t *instructions_inserted, SourceCode *code) { + /*printf("Parsing token = %s\n", TREE_TOKEN_STRINGS[tree->token]);*/ switch (tree->token) { case TREE_TOKEN_FUNCTION_CALL: { const TreeFunctionCallMetadata *tree_metadata = tree->metadata; diff --git a/src/compiler/code_generator/code_generator.h b/src/compiler/code_generator/code_generator.h index 0ae3219..902d76b 100644 --- a/src/compiler/code_generator/code_generator.h +++ b/src/compiler/code_generator/code_generator.h @@ -37,6 +37,7 @@ extern void deleteInstruction(Instruction instruction); extern void deleteInstructions(Instructions instructions); extern Instructions codeGenerator(SourceCode *code); +extern Instructions codeGeneratorWithPrint(SourceCode *code); extern Instructions _codeGenerator(ParsedTree *root, SourceCode *code); extern bool nodeToInstruction(ParsedTree *tree, Instruction **instructions, diff --git a/src/compiler/fasm_generator/fasm_generator.c b/src/compiler/fasm_generator/fasm_generator.c new file mode 100644 index 0000000..b83f3d2 --- /dev/null +++ b/src/compiler/fasm_generator/fasm_generator.c @@ -0,0 +1,208 @@ +#include "fasm_generator.h" + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include "compiler/tree_parser/tree_parser.h" +#include "utils/memory/memory.h" + +FasmLines generateFasm(SourceCode *code) { + ParsedTree *root = treeParser(code); + if (root != NULL) { + FasmLines lines = _generateFasm(root, code); + + deleteParsedTree(root); + return lines; + } + const FasmLines error = { + .lines = NULL, + /*.size = ERROR_SIZE,*/ + }; + return error; +} + +FasmLines generateFasmWithPrint(SourceCode *code) { + ParsedTree *root = treeParser(code); + if (root != NULL) { + printf("----tree parsed:\n"); + printParsedTreeNode(root); + FasmLines lines = _generateFasm(root, code); + + deleteParsedTree(root); + return lines; + } + fprintf(stderr, "error in tree parser\n"); + const FasmLines error = { + .lines = NULL, + /*.size = ERROR_SIZE,*/ + }; + return error; +} + +FasmLines _generateFasm(const ParsedTree *root, SourceCode *code) { + const TreeScopeMetadata *metadata = root->metadata; + + FasmVariables thisVariables = { + .variables = a404m_malloc(metadata->variables_size * + sizeof(*thisVariables.variables)), + .size = metadata->variables_size, + }; + + size_t size = 0; + + for (size_t i = 0; i < metadata->variables_size; ++i) { + const TreeDefineVariableMetadata *variable = metadata->variables[i]; + FasmVariable keyValue = { + .variable = variable, + .value = size, + }; + thisVariables.variables[i] = keyValue; + size += 8; + } + + const size_t variables_size = 1; + FasmVariables *variables[1] = { + &thisVariables, + }; + + FasmLines lines = { + .lines = a404m_malloc(0), + /*.size = 0,*/ + }; + + for (size_t i = 0; i < metadata->lines_size; ++i) { + const ParsedTree *node = metadata->lines[i]; + if (!nodeToFasmLine(node, &lines, variables, variables_size, code)) { + goto RETURN_ERROR; + } + } + + return lines; + +RETURN_ERROR: + free(lines.lines); + + const FasmLines error = { + .lines = NULL, + /*.size = ERROR_SIZE,*/ + }; + return error; +} + +bool nodeToFasmLine(const ParsedTree *node, FasmLines *lines, + FasmVariables *variables[], size_t variables_size, + SourceCode *code) { + switch (node->token) { + case TREE_TOKEN_NONE: + case TREE_TOKEN_ROOT: + printError("Is not allowed in compiler line %s:%d", code, node->strBegin, + node->strBegin, __FILE_NAME__, __LINE__); + exit(1); + case TREE_TOKEN_GLOBAL_SCOPE: + case TREE_TOKEN_LOCAL_SCOPE: { + const TreeScopeMetadata *metadata = node->metadata; + + FasmVariables thisVariables = { + .variables = a404m_malloc(metadata->variables_size * + sizeof(*thisVariables.variables)), + .size = metadata->variables_size, + }; + + size_t size = 0; + + for (size_t i = 0; i < metadata->variables_size; ++i) { + const TreeDefineVariableMetadata *variable = metadata->variables[i]; + FasmVariable keyValue = { + .variable = variable, + .value = size, + .isGlobal = node->token == TREE_TOKEN_GLOBAL_SCOPE, + }; + thisVariables.variables[i] = keyValue; + size += getSizeOfVariable(variable); + } + + size_t newVariables_size = variables_size + 1; + FasmVariables *newVariables[newVariables_size]; + + for (size_t i = 0; i < variables_size; ++i) { + newVariables[i] = variables[i]; + } + newVariables[variables_size] = &thisVariables; + + for (size_t i = 0; i < metadata->lines_size; ++i) { + if (!nodeToFasmLine(metadata->lines[i], lines, newVariables, + newVariables_size, code)) { + return false; + } + } + return true; + } + case TREE_TOKEN_FUNCTION_CALL: { + const TreeFunctionCallMetadata *metadata = node->metadata; + return true; + } + case TREE_TOKEN_FUNCTION: { + const TreeFunctionMetadata *metadata = node->metadata; + return true; + } + case TREE_TOKEN_IDENTIFIER: { + const TreeIdentifierMetadata *metadata = node->metadata; + + const FasmVariable fasmVariable = getVariableFasmKeyValue( + metadata->variable, variables, variables_size); + if (fasmVariable.variable == NULL) { + return false; + } + + FasmLine line = { + /*.label = NULL,*/ + // TODO: do it + }; + + pushFasmLine(lines, line); + + return true; + } + case TREE_TOKEN_DEFINE_VARIABLE: + case TREE_TOKEN_DEFINE_CONSTANT: + case TREE_TOKEN_VALUE_STRING: + case TREE_TOKEN_STRUCT: + } + fprintf(stderr, "Bad parsed token '%d' %s:%d", node->token, __FILE_NAME__, + __LINE__); + exit(1); +} + +void pushFasmLine(FasmLines *lines, FasmLine line) { + const size_t size = + a404m_malloc_usable_size(lines->lines) / sizeof(*lines->lines); + /*if (size == lines->size) { + lines->lines = + a404m_realloc(lines->lines, (size * 2 + 1) * sizeof(*lines->lines)); + } + lines->lines[lines->size] = line; + lines->size += 1;*/ +} + +size_t getSizeOfVariable(const TreeDefineVariableMetadata *variable) { + return 8; // TODO: do it; +} + +FasmVariable getVariableFasmKeyValue(const TreeDefineVariableMetadata *variable, + FasmVariables *variables[], + size_t variables_size) { + for (size_t i = 0; i < variables_size; ++i) { + for (size_t j = 0; j < variables[i]->size; ++j) { + if (variables[i]->variables[j].variable == variable) { + return variables[i]->variables[j]; + } + } + } + const FasmVariable error = { + .variable = NULL, + .value = 0, + .isGlobal = false, + }; + return error; +} diff --git a/src/compiler/fasm_generator/fasm_generator.h b/src/compiler/fasm_generator/fasm_generator.h new file mode 100644 index 0000000..c6925ad --- /dev/null +++ b/src/compiler/fasm_generator/fasm_generator.h @@ -0,0 +1,31 @@ +#pragma once + +#include <compiler/tree_parser/tree_parser.h> +#include <fasm/lexer/lexer.h> +#include <stdint.h> + +typedef struct FasmVariable { + TreeDefineVariableMetadata const *variable; + uint64_t value; + bool isGlobal; +} FasmVariable; + +typedef struct FasmVariables { + FasmVariable *variables; + size_t size; +} FasmVariables; + +extern FasmLines generateFasm(SourceCode *code); +extern FasmLines generateFasmWithPrint(SourceCode *code); +extern FasmLines _generateFasm(const ParsedTree *root, SourceCode *code); + +extern bool nodeToFasmLine(const ParsedTree *node, FasmLines *lines, + FasmVariables *variables[], size_t variables_size, + SourceCode *code); + +extern void pushFasmLine(FasmLines *lines, FasmLine line); + +extern size_t getSizeOfVariable(const TreeDefineVariableMetadata *variable); +extern FasmVariable getVariableFasmKeyValue( + const TreeDefineVariableMetadata *variable, FasmVariables *variables[], + size_t variables_size); diff --git a/src/compiler/lexer/lexer.h b/src/compiler/lexer/lexer.h index 66db1cf..30a5d0f 100644 --- a/src/compiler/lexer/lexer.h +++ b/src/compiler/lexer/lexer.h @@ -1,7 +1,6 @@ #pragma once #include <compiler/error_helper/error_helper.h> -#include <stddef.h> #include <utils/memory/memory.h> #include <utils/types.h> diff --git a/src/compiler/parser/parser.c b/src/compiler/parser/parser.c index ee9e69b..b60dd60 100644 --- a/src/compiler/parser/parser.c +++ b/src/compiler/parser/parser.c @@ -287,6 +287,20 @@ ParsedNode *parser(SourceCode *code, size_t sourceIndex) { return root; } +ParsedNode *parserWithPrint(SourceCode *code, size_t sourceIndex) { + Nodes nodes = lexer(code, sourceIndex); + if (nodes.size == ERROR_SIZE) { + fprintf(stderr, "Error in lexer"); + return NULL; + } + printf("----lexed '%s'\n", code->codes[sourceIndex]->filePath); + printNodes(nodes); + ParsedNode *root = _parser(nodes, code); + + deleteNodes(nodes); + return root; +} + ParsedNode *_parser(Nodes lexedNodes, SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); root->token = PARSED_TOKEN_ROOT; @@ -303,6 +317,12 @@ ParsedNode *_parser(Nodes lexedNodes, SourceCode *code) { ParserScopeMetadata *parserScope( Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, bool (*isAllowed)(ParsedToken token, bool isLast), SourceCode *code) { + if (nodesBegin == nodesEnd) { + ParserScopeMetadata *metadata = a404m_malloc(sizeof(*metadata)); + metadata->operands = a404m_malloc(0); + metadata->operands_size = 0; + return metadata; + } ParsedNode **nodes = a404m_malloc(0); size_t nodes_inserted = 0; @@ -314,7 +334,7 @@ ParserScopeMetadata *parserScope( for (size_t order_tokens_index = 0; order_tokens_index < order->size; ++order_tokens_index) { if (node->token == order->tokens[order_tokens_index]) { - ParsedNode *parsedNode = + ParsedNode *const parsedNode = parseNode(nodesBegin, nodesEnd, node, parent, code); if (parsedNode == NULL) { goto RETURN_ERROR; @@ -344,26 +364,25 @@ ParserScopeMetadata *parserScope( size_t nodes_size = nodes_inserted; nodes_inserted = 0; - ParsedNode *last = NULL; - - for (size_t i = nodes_size - 1; i != (typeof(i))-1; ++i) { - ParsedNode *currentNode = nodes[i]; - if (currentNode->parent == parent) { - last = currentNode; - break; - } + const Node *lastNode = (nodesEnd - 1); + ParsedNode *last = getUntilCommonFather(lastNode->parsedNode, parent); + if (last == NULL) { + printError("Unexpected token '%s'", code, lastNode->strBegin, + lastNode->strEnd, + PARSED_TOKEN_STRINGS[lastNode->parsedNode->token]); + goto RETURN_ERROR; } for (size_t i = 0; i < nodes_size; ++i) { ParsedNode *currentNode = nodes[i]; if (currentNode->parent == parent) { if (!isAllowed(currentNode->token, currentNode == last)) { - printError("Token '%s' is not allowed here", code, - currentNode->strBegin, currentNode->strEnd, - PARSED_TOKEN_STRINGS[currentNode->token]); + printError( + "Token '%s' is not allowed here at %ld current = %p, last = %p", + code, currentNode->strBegin, currentNode->strEnd, + PARSED_TOKEN_STRINGS[currentNode->token], i, currentNode, last); goto RETURN_ERROR; - } - if (nodes_inserted != i) { + } else if (nodes_inserted != i) { nodes[nodes_inserted] = currentNode; } ++nodes_inserted; @@ -378,6 +397,11 @@ ParserScopeMetadata *parserScope( return metadata; RETURN_ERROR: + for (size_t i = 0; i < nodes_inserted; ++i) { + if (nodes[i]->parent == parent) { + deleteParsedNode(nodes[i]); + } + } free(nodes); return NULL; } @@ -641,8 +665,8 @@ ParsedNode *parseParenthesis(Node *nodesBegin, Node *nodesEnd, Node *closing, root->metadata = metadata; } - closing->parsedNode = opening->parsedNode = root; opening->token = closing->token = TOKEN_PARSED; + closing->parsedNode = opening->parsedNode = root; return root; RETURN_ERROR: @@ -676,8 +700,8 @@ ParsedNode *parseCurly(Node *nodesBegin, Node *closing, ParsedNode *parent, root->strEnd = opening->strEnd; root->parent = parent; root->token = PARSED_TOKEN_CODE_BODY; - closing->parsedNode = opening->parsedNode = root; opening->token = closing->token = TOKEN_PARSED; + closing->parsedNode = opening->parsedNode = root; return root; @@ -775,6 +799,7 @@ ParsedNode *parseVariable(Node *nodesBegin, Node *nodesEnd, Node *node, follow->strEnd); goto RETURN_ERROR; } + type->parent = root; ++follow; while (follow->token == TOKEN_PARSED && getUntilCommonFather(follow->parsedNode, type) != NULL) { @@ -794,8 +819,8 @@ ParsedNode *parseVariable(Node *nodesBegin, Node *nodesEnd, Node *node, else root->token = PARSED_TOKEN_DEFINE_CONSTANT; - follow->parsedNode = root; follow->token = TOKEN_PARSED; + follow->parsedNode = root; ++follow; if (follow == nodesEnd) { --follow; @@ -804,8 +829,8 @@ ParsedNode *parseVariable(Node *nodesBegin, Node *nodesEnd, Node *node, goto RETURN_ERROR; } else if (follow->token == TOKEN_PARSED) { value = getUntilCommonFather(follow->parsedNode, parent); + value->parent = root; } else { - BAD_VALUE: printError("Expected value after assignment but got something else", code, follow->strBegin, follow->strEnd); goto RETURN_ERROR; @@ -817,21 +842,8 @@ ParsedNode *parseVariable(Node *nodesBegin, Node *nodesEnd, Node *node, node->strBegin, node->strEnd); goto RETURN_ERROR; } - if (type != NULL) { - metadata->type = type; - type->parent = root; - } else { - metadata->type = NULL; - } - if (value != NULL) { - metadata->value = value = getUntilCommonFather(value, parent); - if (value == NULL) { - goto BAD_VALUE; - } - value->parent = root; - } else { - metadata->value = NULL; - } + metadata->type = type; + metadata->value = value; root->strBegin = variableName->strBegin; root->strEnd = follow->strEnd; @@ -938,6 +950,7 @@ ParsedNode *parseFunction(Node *nodesBegin, Node *nodesEnd, Node *node, metadata->params = params->parsedNode; metadata->params->parent = root; } + if (type >= nodesEnd || type->token != TOKEN_PARSED || type->parsedNode->token != PARSED_TOKEN_IDENTIFIER) { printError("Function definition needs a type to be identifier (for now)", @@ -957,9 +970,9 @@ ParsedNode *parseFunction(Node *nodesBegin, Node *nodesEnd, Node *node, body->token = TOKEN_PARSED; body->parsedNode = root; metadata->body = NULL; - } else if (type->token == TOKEN_PARSED && - type->parsedNode->token == PARSED_TOKEN_CODE_BODY) { - metadata->body = type->parsedNode; + } else if (body->token == TOKEN_PARSED && + body->parsedNode->token == PARSED_TOKEN_CODE_BODY) { + metadata->body = body->parsedNode; metadata->body->parent = root; } else { goto NEED_BODY; @@ -974,7 +987,7 @@ ParsedNode *parseFunction(Node *nodesBegin, Node *nodesEnd, Node *node, return root; RETURN_ERROR: - + // TODO: doesn't delete all free(metadata); free(root); return NULL; diff --git a/src/compiler/parser/parser.h b/src/compiler/parser/parser.h index 234264b..81a5040 100644 --- a/src/compiler/parser/parser.h +++ b/src/compiler/parser/parser.h @@ -74,6 +74,7 @@ extern ParsedNode *getUntilCommonFather(ParsedNode *parsedNode, extern void deleteParsedNode(ParsedNode *parsedNode); extern ParsedNode *parser(SourceCode *code,size_t sourceIndex); +extern ParsedNode *parserWithPrint(SourceCode *code,size_t sourceIndex); extern ParsedNode *_parser(Nodes lexedNodes, SourceCode *code); extern ParserScopeMetadata *parserScope( diff --git a/src/compiler/tree_parser/tree_parser.c b/src/compiler/tree_parser/tree_parser.c index f657f97..07bad0a 100644 --- a/src/compiler/tree_parser/tree_parser.c +++ b/src/compiler/tree_parser/tree_parser.c @@ -1,15 +1,9 @@ #include "tree_parser.h" -#include <compiler/error_helper/error_helper.h> -#include <compiler/lexer/lexer.h> -#include <compiler/parser/parser.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <utils/file.h> -#include <utils/memory/memory.h> -#include <utils/types.h> const char *TREE_TOKEN_STRINGS[] = { "TREE_TOKEN_NONE", @@ -25,10 +19,27 @@ const char *TREE_TOKEN_STRINGS[] = { "TREE_TOKEN_FUNCTION", }; +static void _printParsedTreeVariable(const TreeDefineVariableMetadata *variable, + int indent) { + if (variable == NULL) { + for (int i = 0; i < indent; ++i) printf(" "); + printf("null\n"); + return; + } + for (int i = 0; i < indent; ++i) printf(" "); + printf("{name='%.*s',type=%p,value=\n", + (int)(variable->nameEnd - variable->nameBegin), variable->nameBegin, + variable->type); + _printParsedTreeNode(variable->value, indent + 1); + for (int i = 0; i < indent; ++i) printf(" "); + printf("}\n"); +} + void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) { + for (int i = 0; i < indent; ++i) printf(" "); if (parsedTree == NULL) { - for (int i = 0; i < indent; ++i) printf(" "); printf("null\n"); + return; } printf("{token=%s", TREE_TOKEN_STRINGS[parsedTree->token]); switch (parsedTree->token) { @@ -36,19 +47,83 @@ void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) { goto RETURN_SUCCESS; case TREE_TOKEN_ROOT: case TREE_TOKEN_GLOBAL_SCOPE: - case TREE_TOKEN_LOCAL_SCOPE: - case TREE_TOKEN_FUNCTION_CALL: + case TREE_TOKEN_LOCAL_SCOPE: { + const TreeScopeMetadata *metadata = parsedTree->metadata; + for (int i = 0; i < indent; ++i) printf(" "); + printf(",lines=\n"); + for (size_t i = 0; i < metadata->lines_size; ++i) { + _printParsedTreeNode(metadata->lines[i], indent + 1); + } + for (int i = 0; i < indent; ++i) printf(" "); + printf(",variables=\n"); + for (size_t i = 0; i < metadata->variables_size; ++i) { + _printParsedTreeVariable(metadata->variables[i], indent + 1); + } + goto RETURN_SUCCESS; + } + case TREE_TOKEN_FUNCTION_CALL: { + const TreeFunctionCallMetadata *metadata = parsedTree->metadata; + printf(",lines=\n"); + for (size_t i = 0; i < metadata->values_size; ++i) { + _printParsedTreeNode(metadata->values[i], indent + 1); + } + goto RETURN_SUCCESS; + } case TREE_TOKEN_DEFINE_VARIABLE: - case TREE_TOKEN_IDENTIFIER: - case TREE_TOKEN_VALUE_STRING: - case TREE_TOKEN_STRUCT: - case TREE_TOKEN_DEFINE_CONSTANT: - case TREE_TOKEN_FUNCTION: + case TREE_TOKEN_DEFINE_CONSTANT: { + const TreeDefineVariableMetadata *metadata = parsedTree->metadata; + printf(",define=\n"); + _printParsedTreeVariable(metadata, indent + 1); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_IDENTIFIER: { + const TreeIdentifierMetadata *metadata = parsedTree->metadata; + printf(",variable=\n"); + _printParsedTreeVariable(metadata->variable, indent + 1); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_VALUE_STRING: { + const TreeStringValueMetadata *metadata = parsedTree->metadata; + printf(",str='%.*s'\n", (int)metadata->size, metadata->str); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_STRUCT: { + const TreeStructMetadata *metadata = parsedTree->metadata; + printf(",metadata=%p\n", metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_FUNCTION: { + const TreeFunctionMetadata *metadata = parsedTree->metadata; + const TreeScopeMetadata *scope = metadata->scope; + printf(",scope=\n"); + if (scope != NULL) { + for (int i = 0; i < indent; ++i) printf(" "); + printf(",lines=\n"); + for (size_t i = 0; i < scope->lines_size; ++i) { + _printParsedTreeNode(scope->lines[i], indent + 1); + } + for (int i = 0; i < indent; ++i) printf(" "); + printf(",variables=\n"); + for (size_t i = 0; i < scope->variables_size; ++i) { + _printParsedTreeVariable(scope->variables[i], indent + 1); + } + } else { + for (int i = 0; i < indent; ++i) printf(" "); + printf("null\n"); + } + for (int i = 0; i < indent; ++i) printf(" "); + printf(",params=\n"); + for (size_t i = 0; i < metadata->params_size; ++i) { + _printParsedTreeVariable(metadata->params[i], indent + 1); + } + goto RETURN_SUCCESS; + } } fprintf(stderr, "bad parsed tree token %d at %s:%d", parsedTree->token, __FILE_NAME__, __LINE__); exit(1); RETURN_SUCCESS: + for (int i = 0; i < indent; ++i) printf(" "); printf("}\n"); }; @@ -143,6 +218,9 @@ ParsedTree *treeParser(SourceCode *code) { for (size_t i = 0; i < code->size; ++i) { ParsedNode *const nParsedNode = parser(code, i); + if (nParsedNode == NULL) { + goto RETURN_ERROR; + } ParserScopeMetadata *const nscope = nParsedNode->metadata; for (size_t j = 0; j < nscope->operands_size; ++j) { size_t scopeSize = @@ -160,12 +238,52 @@ ParsedTree *treeParser(SourceCode *code) { nscope->operands_size = 0; deleteParsedNode(nParsedNode); } - if (parsedNode == NULL) { - return NULL; + ParsedTree *tree = _treeParser(parsedNode, code); + deleteParsedNode(parsedNode); + return tree; +RETURN_ERROR: + deleteParsedNode(parsedNode); + return NULL; +} + +ParsedTree *treeParserWithPrint(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 = parserWithPrint(code, i); + if (nParsedNode == NULL) { + fprintf(stderr, "Error in parser"); + goto RETURN_ERROR; + } + printf("----parsed '%s'\n", code->codes[i]->filePath); + printParsedNode(parsedNode); + 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); } ParsedTree *tree = _treeParser(parsedNode, code); deleteParsedNode(parsedNode); return tree; +RETURN_ERROR: + deleteParsedNode(parsedNode); + return NULL; } ParsedTree *_treeParser(const ParsedNode *node, SourceCode *code) { @@ -275,7 +393,7 @@ ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code, const size_t newScopes_size = scopes_size + 1; TreeScopeMetadata *newScopes[newScopes_size]; - memcpy(newScopes, scopes, scopes_size); + memcpy(newScopes, scopes, scopes_size * sizeof(TreeScopeMetadata *)); newScopes[newScopes_size - 1] = metadata; for (size_t i = 0; i < operands_size; ++i) { @@ -285,31 +403,18 @@ ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code, 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; - } - pushVariableToScope(metadata, variableDefine); - } - /* fall through */ - default: - pushLineToScope(metadata, parsedTree); - continue; + if (parsedTree->token != TREE_TOKEN_ROOT) { + pushLineToScope(metadata, parsedTree); + } else { + printError("'%s' Is not allowed here", code, operand->strBegin, + operand->strEnd, PARSED_TOKEN_STRINGS[operand->token]); + goto RETURN_ERROR; } - printError("'%s' Is not allowed here", code, operand->strBegin, - operand->strEnd, PARSED_TOKEN_STRINGS[operand->token]); - goto RETURN_ERROR; } - metadata->variables = - a404m_realloc(metadata->variables, metadata->variables_size); + metadata->variables = a404m_realloc( + metadata->variables, + metadata->variables_size * sizeof(TreeDefineVariableMetadata *)); return tree; @@ -327,37 +432,37 @@ TreeDefineVariableMetadata *treeParseDefineVariable(ParsedTree *tree, TreeDefineVariableMetadata *define = a404m_malloc(sizeof(*define)); define->tree = tree; - ParserVariableDefineMetadata *metadata = node->metadata; + const ParserVariableDefineMetadata *node_metadata = node->metadata; - if (metadata->value == NULL) { + if (node_metadata->value == NULL) { define->value = NULL; - } else if ((define->value = treeParseExpr(metadata->value, code, scopes, + } else if ((define->value = treeParseExpr(node_metadata->value, code, scopes, scopes_size)) == NULL) { goto RETURN_ERROR; } - if (metadata->name->token == PARSED_TOKEN_IDENTIFIER) { - define->nameBegin = metadata->name->strBegin; - define->nameEnd = metadata->name->strEnd; + if (node_metadata->name->token == PARSED_TOKEN_IDENTIFIER) { + define->nameBegin = node_metadata->name->strBegin; + define->nameEnd = node_metadata->name->strEnd; } else { - printError("Names should be an identifier", code, metadata->name->strBegin, - metadata->name->strEnd); + printError("Names should be an identifier", code, + node_metadata->name->strBegin, node_metadata->name->strEnd); goto RETURN_ERROR; } - if (metadata->type == NULL) { + if (node_metadata->type == NULL) { define->type = getTreeExpressionType(define->value); - } else if (metadata->type->token == PARSED_TOKEN_IDENTIFIER) { + } else if (node_metadata->type->token == PARSED_TOKEN_IDENTIFIER) { const TreeDefineVariableMetadata *variable = - getVariable(metadata->type->strBegin, metadata->type->strEnd, code, - scopes, scopes_size); + getVariable(node_metadata->type->strBegin, node_metadata->type->strEnd, + code, scopes, scopes_size); if (variable == NULL) { goto RETURN_ERROR; } define->type = getType(variable); } else { printError("Types should be an identifier (for now)", code, - metadata->type->strBegin, metadata->type->strEnd); + node_metadata->type->strBegin, node_metadata->type->strEnd); goto RETURN_ERROR; } @@ -366,6 +471,8 @@ TreeDefineVariableMetadata *treeParseDefineVariable(ParsedTree *tree, goto RETURN_ERROR; } + pushVariableToScope(scopes[scopes_size - 1], define); + return define; RETURN_ERROR: @@ -536,14 +643,8 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, ParsedTree *parsedTree = treeParseNode(node_metadata->type, code, scopes, scopes_size); - if (parsedTree == NULL) { - goto RETURN_ERROR; - } - metadata->returnType = getTreeExpressionType(parsedTree); - // TODO: this is not right - deleteParsedTree(parsedTree); - - const ParserScopeMetadata *params = node_metadata->params->metadata; + const size_t newScopes_size = scopes_size + 1; + TreeScopeMetadata *newScopes[newScopes_size]; metadata->params = a404m_malloc(0); metadata->params_size = 0; @@ -555,10 +656,30 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, metadata->scope->lines = a404m_malloc(0); metadata->scope->lines_size = 0; + memcpy(newScopes, scopes, scopes_size * sizeof(TreeScopeMetadata *)); + newScopes[newScopes_size - 1] = metadata->scope; + + if (parsedTree == NULL) { + goto RETURN_ERROR; + } + metadata->returnType = getTreeExpressionType(parsedTree); + // TODO: this is not right + deleteParsedTree(parsedTree); + + const ParserScopeMetadata *params = node_metadata->params->metadata; + for (size_t i = 0; i < params->operands_size; ++i) { const ParsedNode *operand = params->operands[i]; + if (operand->token == PARSED_TOKEN_COMMA) { + operand = (ParserCommaMetadata *)operand->metadata; + } + if (operand->token != PARSED_TOKEN_DEFINE_VARIABLE) { + printError( + "Only variable definition is allowed in function parameter list", + code, operand->strBegin, operand->strEnd); + } TreeDefineVariableMetadata *define = - treeParseDefineVariable(tree, operand, code, scopes, scopes_size); + treeParseDefineVariable(tree, operand, code, newScopes, newScopes_size); if (define == NULL) { goto RETURN_ERROR; } @@ -578,10 +699,15 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, sizeof(TreeDefineVariableMetadata *)); if (node_metadata->body != NULL) { - printError("Not implemented", code, node->strBegin, node->strEnd); - - goto RETURN_ERROR; - return NULL; + const ParserScopeMetadata *body = node_metadata->body->metadata; + for (size_t i = 0; i < body->operands_size; ++i) { + ParsedTree *parsedTree = + treeParseNode(body->operands[i], code, newScopes, newScopes_size); + if (parsedTree == NULL) { + goto RETURN_ERROR; + } + pushLineToScope(metadata->scope, parsedTree); + } } else { free(metadata->scope->lines); metadata->scope->lines_size = 0; @@ -589,7 +715,7 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, return tree; RETURN_ERROR: - + // TODO: doesn't delete all of them free(metadata); free(tree); return NULL; @@ -598,12 +724,12 @@ RETURN_ERROR: ParsedTree *treeParseImport(const ParsedNode *node, SourceCode *code, TreeScopeMetadata *[], size_t) { const ParserImportMetadata *node_metadata = node->metadata; - SizedString *path = nodeToString(node_metadata, code); + SizedString *const path = nodeToString(node_metadata, code); if (path == NULL) { return NULL; } - Code *fileCode = read_whole_file(path->str); + Code *const fileCode = read_whole_file(path->str); if (fileCode == NULL) { goto RETURN_ERROR; } diff --git a/src/compiler/tree_parser/tree_parser.h b/src/compiler/tree_parser/tree_parser.h index 8a9f7b5..b598348 100644 --- a/src/compiler/tree_parser/tree_parser.h +++ b/src/compiler/tree_parser/tree_parser.h @@ -1,7 +1,6 @@ #pragma once #include <compiler/parser/parser.h> -#include <stdint.h> typedef enum TreeToken { TREE_TOKEN_NONE = 0, @@ -71,6 +70,7 @@ extern void printParsedTreeNode(const ParsedTree *parsedTree); extern void deleteParsedTree(ParsedTree *parsedTree); extern ParsedTree *treeParser(SourceCode *code); +extern ParsedTree *treeParserWithPrint(SourceCode *code); extern ParsedTree *_treeParser(const ParsedNode *node, SourceCode *code); extern ParsedTree *treeParseNode(const ParsedNode *node, SourceCode *code, |