diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-09-22 19:34:43 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-09-22 19:34:43 +0330 |
commit | f79290084948f3cf140395c270c07cf29ca58e8d (patch) | |
tree | d716526678782153f3617bbf78984b4c4ebed380 /src/compiler/tree_parser | |
parent | d2ab53c625d386a4fbc6a9d5a5eb29faab1b3f0c (diff) |
Better errors
Added variables
Diffstat (limited to 'src/compiler/tree_parser')
-rw-r--r-- | src/compiler/tree_parser/tree_parser.c | 695 | ||||
-rw-r--r-- | src/compiler/tree_parser/tree_parser.h | 113 |
2 files changed, 808 insertions, 0 deletions
diff --git a/src/compiler/tree_parser/tree_parser.c b/src/compiler/tree_parser/tree_parser.c new file mode 100644 index 0000000..cb1ef4c --- /dev/null +++ b/src/compiler/tree_parser/tree_parser.c @@ -0,0 +1,695 @@ +#include "tree_parser.h" + +#include <compiler/error_helper/error_helper.h> +#include <compiler/lexer/lexer.h> +#include <compiler/parser/parser.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utils/memory/memory.h> + +#include "utils/types.h" + +const char *TREE_TOKEN_STRINGS[] = { + "TREE_TOKEN_NONE", + "TREE_TOKEN_GLOBAL_SCOPE", + "TREE_TOKEN_LOCAL_SCOPE", + "TREE_TOKEN_FUNCTION_CALL", + "TREE_TOKEN_DEFINE_VARIABLE", + "TREE_TOKEN_DEFINE_CONSTANT", + "TREE_TOKEN_IDENTIFIER", + "TREE_TOKEN_VALUE_STRING", + "TREE_TOKEN_STRUCT", + "TREE_TOKEN_FUNCTION", +}; + +void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) { + if (parsedTree == NULL) { + for (int i = 0; i < indent; ++i) printf(" "); + printf("null\n"); + } + printf("{token=%s", TREE_TOKEN_STRINGS[parsedTree->token]); + switch (parsedTree->token) { + case TREE_TOKEN_NONE: + goto RETURN_SUCCESS; + case TREE_TOKEN_GLOBAL_SCOPE: + case TREE_TOKEN_LOCAL_SCOPE: + case TREE_TOKEN_FUNCTION_CALL: + 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: + } + fprintf(stderr, "bad parsed tree token %d at %s:%d", parsedTree->token, + __FILE_NAME__, __LINE__); + exit(1); +RETURN_SUCCESS: + printf("}\n"); +}; + +void printParsedTreeNode(const ParsedTree *parsedTree) { + _printParsedTreeNode(parsedTree, 0); +} + +void deleteParsedTree(ParsedTree *parsedTree) { + if (parsedTree == NULL) { + return; + } + switch (parsedTree->token) { + case TREE_TOKEN_NONE: + goto RETURN_SUCCESS; + case TREE_TOKEN_GLOBAL_SCOPE: + case TREE_TOKEN_LOCAL_SCOPE: { + TreeScopeMetadata *metadata = parsedTree->metadata; + for (size_t i = 0; i < metadata->lines_size; ++i) { + deleteParsedTree(metadata->lines[i]); + } + free(metadata->lines); + free(metadata->variables); + free(metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_FUNCTION_CALL: { + TreeFunctionCallMetadata *metadata = parsedTree->metadata; + for (size_t i = 0; i < metadata->values_size; ++i) { + deleteParsedTree(metadata->values[i]); + } + free(metadata->values); + free(metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_DEFINE_VARIABLE: + case TREE_TOKEN_DEFINE_CONSTANT: { + TreeDefineVariableMetadata *metadata = parsedTree->metadata; + deleteParsedTree(metadata->value); + free(metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_IDENTIFIER: { + TreeIdentifierMetadata *metadata = parsedTree->metadata; + free(metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_VALUE_STRING: { + TreeStringValueMetadata *metadata = parsedTree->metadata; + free(metadata->str); + free(metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_STRUCT: { + TreeStructMetadata *metadata = parsedTree->metadata; + free(metadata); + goto RETURN_SUCCESS; + } + case TREE_TOKEN_FUNCTION: { + TreeFunctionMetadata *metadata = parsedTree->metadata; + TreeScopeMetadata *scope = metadata->scope; + if (scope != NULL) { + for (size_t i = 0; i < scope->lines_size; ++i) { + deleteParsedTree(scope->lines[i]); + } + free(scope->lines); + free(scope->variables); + } + for (size_t i = 0; i < metadata->params_size; ++i) { + deleteParsedTree(metadata->params[i]->value); + free(metadata->params[i]); + } + free(metadata->params); + free(metadata); + goto RETURN_SUCCESS; + } + } + fprintf(stderr, "bad parsed tree token %d at %s:%d", parsedTree->token, + __FILE_NAME__, __LINE__); + exit(1); +RETURN_SUCCESS: + free(parsedTree); +} + +ParsedTree *treeParser(SourceCode code) { + ParsedNode *parsedNode = parser(code); + if (parsedNode == NULL) { + return NULL; + } + ParsedTree *tree= _treeParser(parsedNode, code); + deleteParsedNode(parsedNode); + return tree; +} + +ParsedTree *_treeParser(const ParsedNode *node, SourceCode code) { + if (node->token == PARSED_TOKEN_ROOT) { + return treeParseRoot(node, code); + } else { + return NULL; + } +} + +ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + switch (node->token) { + case PARSED_TOKEN_ROOT: + case PARSED_TOKEN_NONE: + fprintf(stderr, "parsed token not allowed %s", + PARSED_TOKEN_STRINGS[node->token]); + return NULL; + case PARSED_TOKEN_EOL: + return treeParseNode((ParserEOLMetadata *)node->metadata, code, scopes, + scopes_size); + case PARSED_TOKEN_IDENTIFIER: + return treeParseIdentifier(node, code, scopes, scopes_size); + case PARSED_TOKEN_FUNCTION_CALL: + return treeParseFunctionCall(node, code, scopes, scopes_size); + case PARSED_TOKEN_COMMA: + return treeParseNode((ParserCommaMetadata *)node->metadata, code, scopes, + scopes_size); + case PARSED_TOKEN_PARENTHESIS: + return treeParseNode((ParserParenthesisMetadata *)node->metadata, code, + scopes, scopes_size); + case PARSED_TOKEN_CODE_BODY: + return treeParseLocalScope(node, code, scopes, scopes_size); + case PARSED_TOKEN_VALUE_STRING: + return treeParseValueString(node, code); + case PARSED_TOKEN_DEFINE_VARIABLE: + return treeParseVariableDefinition(node, code, scopes, scopes_size, + TREE_TOKEN_DEFINE_VARIABLE); + case PARSED_TOKEN_DEFINE_CONSTANT: + return treeParseVariableDefinition(node, code, scopes, scopes_size, + TREE_TOKEN_DEFINE_CONSTANT); + case PARSED_TOKEN_STRUCT: + return treeParseStruct(node, code, scopes, scopes_size); + case PARSED_TOKEN_FUNCTION: + return treeParseFunction(node, code, scopes, scopes_size); + case PARSED_TOKEN_FUNCTION_PARAMS: + } + fprintf(stderr, "bad parsed token %d at %s:%d", node->token, __FILE_NAME__, + __LINE__); + return NULL; +} + +ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + switch (node->token) { + case PARSED_TOKEN_ROOT: + case PARSED_TOKEN_NONE: + case PARSED_TOKEN_EOL: + case PARSED_TOKEN_COMMA: + case PARSED_TOKEN_DEFINE_VARIABLE: + case PARSED_TOKEN_DEFINE_CONSTANT: + case PARSED_TOKEN_CODE_BODY: + printError("Parsed token %s is not an expression", code, node->strBegin, + node->strEnd, PARSED_TOKEN_STRINGS[node->token]); + return NULL; + case PARSED_TOKEN_PARENTHESIS: + case PARSED_TOKEN_FUNCTION_CALL: + case PARSED_TOKEN_VALUE_STRING: + case PARSED_TOKEN_IDENTIFIER: + case PARSED_TOKEN_STRUCT: + case PARSED_TOKEN_FUNCTION: + return treeParseNode(node, code, scopes, scopes_size); + case PARSED_TOKEN_FUNCTION_PARAMS: + } + fprintf(stderr, "bad parsed token %d", node->token); + return NULL; +} + +ParsedTree *treeParseRoot(const ParsedNode *node, SourceCode code) { + return treeParseLocalScope(node, code, NULL, 0); +} + +ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + const ParserScopeMetadata *node_metadata = node->metadata; + ParsedNode **const operands = node_metadata->operands; + const size_t operands_size = node_metadata->operands_size; + + ParsedTree *tree = a404m_malloc(sizeof(*tree)); + tree->token = TREE_TOKEN_LOCAL_SCOPE; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + + 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_size = 0; + + size_t metadata_lines_size = 0; + metadata->lines = a404m_malloc(metadata_lines_size * sizeof(ParsedTree *)); + 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]; + } + + newScopes[newScopes_size - 1] = metadata; + + for (size_t i = 0; i < operands_size; ++i) { + const ParsedNode *operand = operands[i]; + ParsedTree *const parsedTree = + treeParseNode(operand, code, newScopes, newScopes_size); + if (parsedTree == NULL) { + goto RETURN_ERROR; + } + switch (parsedTree->token) { + 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; + } + /* 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; + continue; + } + 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); + + return tree; + +RETURN_ERROR: + free(tree); + free(metadata); + return NULL; +} + +TreeDefineVariableMetadata *treeParseDefineVariable( + ParsedTree *tree, const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], size_t scopes_size) { + TreeDefineVariableMetadata *define = a404m_malloc(sizeof(*define)); + define->tree = tree; + + ParserVariableDefineMetadata *metadata = node->metadata; + + if (metadata->value == NULL) { + define->value = NULL; + } else if ((define->value = treeParseExpr(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; + } else { + printError("Names should be an identifier", code, metadata->name->strBegin, + metadata->name->strEnd); + goto RETURN_ERROR; + } + + if (metadata->type == NULL) { + define->type = getTreeExpressionType(define->value); + } else if (metadata->type->token == PARSED_TOKEN_IDENTIFIER) { + const TreeDefineVariableMetadata *variable = + getVariable(metadata->type->strBegin, 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); + goto RETURN_ERROR; + } + + if (define->type == NULL) { + printError("Can't specify type", code, node->strBegin, node->strEnd); + goto RETURN_ERROR; + } + + return define; + +RETURN_ERROR: + free(define); + return NULL; +} + +TreeDefineVariableMetadata *getVariable(const char *strBegin, + const char *strEnd, SourceCode code, + const 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]; + 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; + if (size == variable_str_size && + strncmp(str, variable->nameBegin, size) == 0) { + return variable; + } + } + } + + printError("Identifier is not defined", code, strBegin, strEnd); + return NULL; +} + +ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + TreeDefineVariableMetadata *variable = + getVariable(node->strBegin, node->strEnd, code, scopes, scopes_size); + if (variable != NULL) { + ParsedTree *tree = a404m_malloc(sizeof(*tree)); + tree->token = TREE_TOKEN_IDENTIFIER; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + TreeIdentifierMetadata *metadata = tree->metadata = + a404m_malloc(sizeof(TreeIdentifierMetadata)); + metadata->variable = variable; + return tree; + } + return NULL; +} + +ParsedTree *treeParseFunctionCall(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + ParserFunctionCallMetadata *node_metadata = node->metadata; + + ParsedTree *tree = a404m_malloc(sizeof(*tree)); + tree->token = TREE_TOKEN_FUNCTION_CALL; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + + TreeFunctionCallMetadata *metadata = tree->metadata = + a404m_malloc(sizeof(*metadata)); + + size_t metadata_values_size = 0; + metadata->values = a404m_malloc(metadata_values_size * sizeof(ParsedTree *)); + metadata->values_size = 0; + + TreeDefineVariableMetadata *variable = + getVariable(node_metadata->functionNameBegin, + node_metadata->functionNameEnd, code, scopes, scopes_size); + + if (variable == NULL) { + goto RETURN_ERROR; + } + metadata->function = variable; + + for (size_t i = 0; i < node_metadata->scope->operands_size; ++i) { + ParsedNode *const operand = node_metadata->scope->operands[i]; + ParsedTree *const operandTree = + treeParseNode(operand, code, scopes, scopes_size); + if (operandTree == NULL) { + goto RETURN_ERROR; + } + // TODO: check types + if (metadata->values_size == metadata_values_size) { + metadata_values_size += metadata_values_size / 2 + 1; + metadata->values = + a404m_malloc(metadata_values_size * sizeof(ParsedTree *)); + } + metadata->values[metadata->values_size] = operandTree; + metadata->values_size += 1; + } + + metadata->values = a404m_realloc( + metadata->values, metadata->values_size * sizeof(ParsedTree *)); + return tree; + +RETURN_ERROR: + free(metadata); + free(tree); + return NULL; +} + +ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode code) { + ParsedTree *const tree = a404m_malloc(sizeof(*tree)); + tree->token = TREE_TOKEN_VALUE_STRING; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + if ((tree->metadata = nodeToString(node, code)) == NULL) { + free(tree); + return NULL; + } + return tree; +} + +ParsedTree *treeParseVariableDefinition(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size, TreeToken token) { + ParsedTree *const tree = a404m_malloc(sizeof(*tree)); + tree->token = token; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + if ((tree->metadata = treeParseDefineVariable(tree, node, code, scopes, + scopes_size)) == NULL) { + free(tree); + return NULL; + } + return tree; +} + +ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + const ParserStructMetadata *node_metadata = node->metadata; + + ParsedTree *const tree = a404m_malloc(sizeof(*tree)); + tree->token = TREE_TOKEN_STRUCT; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + TreeStructMetadata *const metadata = tree->metadata = + a404m_malloc(sizeof(*metadata)); + + if (node_metadata->body != NULL) { + const ParserScopeMetadata *node_body = node_metadata->body->metadata; + for (size_t i = 0; i < node_body->operands_size; ++i) { + // TODO: implement + printError("Not implemented", code, node->strBegin, node->strEnd); + + free(metadata); + free(tree); + return NULL; + } + } + + return tree; +} + +ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size) { + const ParserFunctionMetadata *node_metadata = node->metadata; + + ParsedTree *const tree = a404m_malloc(sizeof(*tree)); + tree->token = TREE_TOKEN_FUNCTION; + tree->strBegin = node->strBegin; + tree->strEnd = node->strEnd; + + TreeFunctionMetadata *const metadata = tree->metadata = + a404m_malloc(sizeof(*metadata)); + + 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; + + size_t metadata_params_size = 0; + metadata->params = + a404m_malloc(metadata_params_size * sizeof(TreeDefineVariableMetadata *)); + metadata->params_size = 0; + + for (size_t i = 0; i < params->operands_size; ++i) { + const ParsedNode *operand = params->operands[i]; + TreeDefineVariableMetadata *define = + treeParseDefineVariable(tree, operand, code, scopes, scopes_size); + if (define == NULL) { + goto RETURN_ERROR; + } + if (metadata->params_size == metadata_params_size) { + metadata_params_size += metadata_params_size / 2 + 1; + metadata->params = a404m_realloc( + metadata->params, + metadata_params_size * sizeof(TreeDefineVariableMetadata *)); + } + metadata->params[metadata->params_size] = define; + metadata->params_size += 1; + } + metadata->params = + a404m_realloc(metadata->params, metadata->params_size * + sizeof(TreeDefineVariableMetadata *)); + + if (node_metadata->body != NULL) { + printError("Not implemented", code, node->strBegin, node->strEnd); + + free(metadata); + free(tree); + return NULL; + } else { + metadata->scope = NULL; + } + + return tree; +RETURN_ERROR: + + free(metadata); + free(tree); + return NULL; +} + +TypeId getTreeExpressionType(ParsedTree *tree) { + switch (tree->token) { + case TREE_TOKEN_FUNCTION_CALL: + return ((TreeFunctionMetadata *)((TreeFunctionCallMetadata *) + tree->metadata) + ->function->type->metadata) + ->returnType; + case TREE_TOKEN_DEFINE_VARIABLE: + case TREE_TOKEN_DEFINE_CONSTANT: + return ((TreeDefineVariableMetadata *)tree->metadata)->type; + case TREE_TOKEN_IDENTIFIER: + return getType(((TreeIdentifierMetadata *)tree->metadata)->variable); + case TREE_TOKEN_VALUE_STRING: + case TREE_TOKEN_STRUCT: + case TREE_TOKEN_GLOBAL_SCOPE: + case TREE_TOKEN_LOCAL_SCOPE: + case TREE_TOKEN_FUNCTION: // TODO: find a better way for function + return tree; + case TREE_TOKEN_NONE: + } + fprintf(stderr, "bad parsed tree token %d at %d:%s", tree->token, __LINE__, + __FILE_NAME__); + exit(1); +} + +TypeId getType(const TreeDefineVariableMetadata *define) { + if (define->value == NULL || !isType(define->value)) { + return define->type; + } else { + return define->tree; + } +} + +bool isType(ParsedTree *const tree) { + switch (tree->token) { + case TREE_TOKEN_FUNCTION_CALL: + case TREE_TOKEN_DEFINE_VARIABLE: + case TREE_TOKEN_DEFINE_CONSTANT: + case TREE_TOKEN_IDENTIFIER: + case TREE_TOKEN_VALUE_STRING: + case TREE_TOKEN_GLOBAL_SCOPE: + case TREE_TOKEN_LOCAL_SCOPE: + return false; + case TREE_TOKEN_STRUCT: + case TREE_TOKEN_FUNCTION: // TODO: find a better way for function + return true; + case TREE_TOKEN_NONE: + } + 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; + + char *str = a404m_malloc((strEnd - strBegin + 1) * sizeof(char)); + size_t inserted = 0; + + for (char const *iter = strBegin; iter < strEnd; ++iter) { + char c = *iter; + if (c == '\\') { + if (++iter < strEnd) { + switch (*iter) { + case '\'': + c = '\''; + break; + case '\"': + c = '\"'; + break; + case '\\': + c = '\\'; + break; + case 'a': + c = '\a'; + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + /*case 'u':*/ // TODO: do it + /* c = '';*/ + /* break;*/ + default: + printError("Bad escape code '\\%s'", code, tree->strBegin, + tree->strEnd, *iter); + goto RETURN_ERROR; + } + } else { + printError("Expected character after '\\'", code, tree->strBegin, + tree->strEnd); + goto RETURN_ERROR; + } + } + str[inserted] = c; + ++inserted; + } + + str[inserted] = '\0'; + SizedString *const string = a404m_malloc(sizeof(SizedString)); + string->str = a404m_realloc(str, (inserted + 1) * sizeof(char)); + string->size = inserted; + return string; +RETURN_ERROR: + free(str); + return NULL; +} diff --git a/src/compiler/tree_parser/tree_parser.h b/src/compiler/tree_parser/tree_parser.h new file mode 100644 index 0000000..0ee783f --- /dev/null +++ b/src/compiler/tree_parser/tree_parser.h @@ -0,0 +1,113 @@ +#pragma once + +#include <compiler/parser/parser.h> + +#include "utils/types.h" + +typedef enum TreeToken { + TREE_TOKEN_NONE = 0, + TREE_TOKEN_GLOBAL_SCOPE, + TREE_TOKEN_LOCAL_SCOPE, + TREE_TOKEN_FUNCTION_CALL, + TREE_TOKEN_DEFINE_VARIABLE, + TREE_TOKEN_DEFINE_CONSTANT, + TREE_TOKEN_IDENTIFIER, + TREE_TOKEN_VALUE_STRING, + TREE_TOKEN_STRUCT, + TREE_TOKEN_FUNCTION, +} TreeToken; + +extern const char *TREE_TOKEN_STRINGS[]; + +typedef struct ParsedTree { + char const *strBegin; + char const *strEnd; + TreeToken token; + void *metadata; +} ParsedTree; + +typedef struct TreeStructMetadata { +} TreeStructMetadata; + +typedef ParsedTree *TypeId; + +typedef struct TreeDefineVariableMetadata { + char const *nameBegin; + char const *nameEnd; + TypeId type; + ParsedTree *value; + ParsedTree *tree; +} TreeDefineVariableMetadata; + +typedef struct TreeFunctionCallMetadata { + TreeDefineVariableMetadata *function; + ParsedTree **values; + size_t values_size; +} TreeFunctionCallMetadata; + +typedef struct TreeScopeMetadata { + ParsedTree **lines; + size_t lines_size; + TreeDefineVariableMetadata **variables; + size_t variables_size; +} TreeScopeMetadata; + +typedef struct TreeIdentifierMetadata { + TreeDefineVariableMetadata *variable; +} TreeIdentifierMetadata; + +typedef struct TreeFunctionMetadata { + TreeDefineVariableMetadata **params; + size_t params_size; + TreeScopeMetadata *scope; + TypeId returnType; +} TreeFunctionMetadata; + +typedef SizedString TreeStringValueMetadata; + +extern void _printParsedTreeNode(const ParsedTree *parsedTree,int indent); +extern void printParsedTreeNode(const ParsedTree *parsedTree); + +extern void deleteParsedTree(ParsedTree *parsedTree); + +extern ParsedTree *treeParser(SourceCode code); +extern ParsedTree *_treeParser(const ParsedNode *node, SourceCode code); + +extern ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size); + +extern ParsedTree *treeParseRoot(const ParsedNode *root, SourceCode code); +extern ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size); + +extern TreeDefineVariableMetadata *treeParseDefineVariable( + ParsedTree *tree, const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], size_t scopes_size); +extern TreeDefineVariableMetadata *getVariable( + const char *strBegin, const char *strEnd, SourceCode code, + const TreeScopeMetadata *scopes[], size_t scopes_size); +extern ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size); +extern ParsedTree *treeParseFunctionCall(const ParsedNode *node, + SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size); +extern ParsedTree *treeParseValueString(const ParsedNode *node, + SourceCode code); +extern ParsedTree *treeParseVariableDefinition( + const ParsedNode *node, SourceCode code, const TreeScopeMetadata *scopes[], + size_t scopes_size, TreeToken token); +extern ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size); +extern ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, + const TreeScopeMetadata *scopes[], + size_t scopes_size); + +extern TypeId getTreeExpressionType(ParsedTree *const tree); +extern TypeId getType(const TreeDefineVariableMetadata *define); +extern bool isType(ParsedTree *const tree); +extern SizedString *nodeToString(ParsedNode const *tree, SourceCode code); |