#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; }