aboutsummaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2024-10-08 04:16:27 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2024-10-08 04:17:08 +0330
commitaddd54dc31603dc204773d3108dba4e000cd7657 (patch)
tree621620c4ca5634680d7655e3474cf0b0bcec8e01 /src/compiler
parentbf84010e01bb11874689ce53ea4df853b2e41c2b (diff)
added fasm support
added compiler options tried to compile to fasm first
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/code_generator/code_generator.c19
-rw-r--r--src/compiler/code_generator/code_generator.h1
-rw-r--r--src/compiler/fasm_generator/fasm_generator.c208
-rw-r--r--src/compiler/fasm_generator/fasm_generator.h31
-rw-r--r--src/compiler/lexer/lexer.h1
-rw-r--r--src/compiler/parser/parser.c87
-rw-r--r--src/compiler/parser/parser.h1
-rw-r--r--src/compiler/tree_parser/tree_parser.c262
-rw-r--r--src/compiler/tree_parser/tree_parser.h2
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,