diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-10-08 04:16:27 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-10-08 04:17:08 +0330 |
commit | addd54dc31603dc204773d3108dba4e000cd7657 (patch) | |
tree | 621620c4ca5634680d7655e3474cf0b0bcec8e01 /src/compiler/fasm_generator | |
parent | bf84010e01bb11874689ce53ea4df853b2e41c2b (diff) |
added fasm support
added compiler options
tried to compile to fasm first
Diffstat (limited to 'src/compiler/fasm_generator')
-rw-r--r-- | src/compiler/fasm_generator/fasm_generator.c | 208 | ||||
-rw-r--r-- | src/compiler/fasm_generator/fasm_generator.h | 31 |
2 files changed, 239 insertions, 0 deletions
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); |