From addd54dc31603dc204773d3108dba4e000cd7657 Mon Sep 17 00:00:00 2001 From: A404M Date: Tue, 8 Oct 2024 04:16:27 +0330 Subject: added fasm support added compiler options tried to compile to fasm first --- src/compiler/fasm_generator/fasm_generator.c | 208 +++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 src/compiler/fasm_generator/fasm_generator.c (limited to 'src/compiler/fasm_generator/fasm_generator.c') 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 +#include +#include + +#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; +} -- cgit v1.2.3