From f79290084948f3cf140395c270c07cf29ca58e8d Mon Sep 17 00:00:00 2001 From: A404M Date: Sun, 22 Sep 2024 19:34:43 +0330 Subject: Better errors Added variables --- src/compiler/code_generator/code_generator.c | 213 +++++++++++++-------------- src/compiler/code_generator/code_generator.h | 19 ++- 2 files changed, 115 insertions(+), 117 deletions(-) (limited to 'src/compiler/code_generator') diff --git a/src/compiler/code_generator/code_generator.c b/src/compiler/code_generator/code_generator.c index 8560129..2b575d8 100644 --- a/src/compiler/code_generator/code_generator.c +++ b/src/compiler/code_generator/code_generator.c @@ -7,6 +7,8 @@ #include #include +#include "compiler/tree_parser/tree_parser.h" + const char *COMMAND_STRINGS[] = { "COMMAND_NONE", "COMMAND_CALL_FUNCTION", @@ -21,6 +23,8 @@ void printInstruction(Instruction instruction) { return; case COMMAND_CALL_FUNCTION: case COMMAND_PUSH_STRING: + case COMMAND_POP_IDENTIFIER: + case COMMAND_PUSH_IDENTIFIER: SizedString *sizedString = instruction.operand; printf(" '%.*s'\n", (int)sizedString->size, sizedString->str); return; @@ -40,6 +44,8 @@ void deleteInstruction(Instruction instruction) { return; case COMMAND_PUSH_STRING: case COMMAND_CALL_FUNCTION: + case COMMAND_PUSH_IDENTIFIER: + case COMMAND_POP_IDENTIFIER: SizedString *sizedString = instruction.operand; free(sizedString->str); free(sizedString); @@ -55,30 +61,47 @@ void deleteInstructions(Instructions instructions) { free(instructions.instructions); } -Instructions codeGenerator(ParsedNode *root) { - const ScopeMetadata *metadata = root->metadata; +Instructions codeGenerator(SourceCode code) { + ParsedTree *root = treeParser(code); + if (root != NULL) { + Instructions instructions = _codeGenerator(root, code); + + deleteParsedTree(root); + return instructions; + } + const Instructions error = { + .instructions = NULL, + .size = ERROR_SIZE, + }; + return error; +} + +Instructions _codeGenerator(ParsedTree *root, SourceCode code) { + const TreeScopeMetadata *metadata = root->metadata; size_t instructions_size = 10; Instruction *instructions = - a404m_malloc(instructions_size * sizeof(Instruction)); + a404m_malloc(instructions_size * sizeof(*instructions)); size_t instructions_inserted = 0; - for (size_t i = 0; i < metadata->operands_size; ++i) { - ParsedNode *node = metadata->operands[i]; + for (size_t i = 0; i < metadata->lines_size; ++i) { + ParsedTree *node = metadata->lines[i]; if (!nodeToInstruction(node, &instructions, &instructions_size, - &instructions_inserted)) { + &instructions_inserted, code)) { goto RETURN_ERROR; } } Instructions result = { .instructions = a404m_realloc( - instructions, instructions_inserted * sizeof(Instruction)), + instructions, instructions_inserted * sizeof(*instructions)), .size = instructions_inserted, }; return result; RETURN_ERROR: + free(instructions); + const Instructions error = { .instructions = NULL, .size = ERROR_SIZE, @@ -86,65 +109,99 @@ RETURN_ERROR: return error; } -bool nodeToInstruction(ParsedNode *node, Instruction **instructions, - size_t *instructions_size, - size_t *instructions_inserted) { - switch (node->token) { - case PARSED_TOKEN_FUNCTION_CALL: { - FunctionCallMetadata *metadata = node->metadata; - const ScopeMetadata *scope = metadata->scope; - for (size_t i = 0; i < scope->operands_size; ++i) { - if (!nodeToInstruction(scope->operands[i], instructions, - instructions_size, instructions_inserted)) { +bool nodeToInstruction(ParsedTree *tree, Instruction **instructions, + size_t *instructions_size, size_t *instructions_inserted, + SourceCode code) { + switch (tree->token) { + case TREE_TOKEN_FUNCTION_CALL: { + const TreeFunctionCallMetadata *tree_metadata = tree->metadata; + for (size_t i = 0; i < tree_metadata->values_size; ++i) { + if (!nodeToInstruction(tree_metadata->values[i], instructions, + instructions_size, instructions_inserted, + code)) { return false; } } - SizedString *string = a404m_malloc(sizeof(*string)); - string->size = metadata->functionNameEnd - metadata->functionNameBegin; - string->str = a404m_malloc(string->size); - strncpy(string->str, metadata->functionNameBegin, string->size); - if (string == NULL) { - return false; - } + CommandCallFunctionOperand *operand = a404m_malloc(sizeof(*operand)); + operand->size = + tree_metadata->function->nameEnd - tree_metadata->function->nameBegin; + operand->str = a404m_malloc((operand->size + 1) * sizeof(char)); + strncpy(operand->str, tree_metadata->function->nameBegin, operand->size); const Instruction instruction = { .command = COMMAND_CALL_FUNCTION, - .operand = string, + .operand = operand, }; insertInstruction(instruction, instructions, instructions_size, instructions_inserted); return true; } - case PARSED_TOKEN_PARENTHESIS: { - const ScopeMetadata *metadata = node->metadata; - for (size_t i = 0; i < metadata->operands_size; ++i) { - if (!nodeToInstruction(metadata->operands[i], instructions, - instructions_size, instructions_inserted)) { - return false; - } - } + case TREE_TOKEN_IDENTIFIER: { + const TreeIdentifierMetadata *tree_metadata = tree->metadata; + CommandPushIdentifierOperand *operand = a404m_malloc(sizeof(*operand)); + operand->size = + tree_metadata->variable->nameEnd - tree_metadata->variable->nameBegin; + operand->str = a404m_malloc((operand->size + 1) * sizeof(char)); + strncpy(operand->str, tree_metadata->variable->nameBegin, + operand->size * sizeof(char)); + + const Instruction instruction = { + .command = COMMAND_PUSH_IDENTIFIER, + .operand = operand, + }; + insertInstruction(instruction, instructions, instructions_size, + instructions_inserted); return true; } - case PARSED_TOKEN_EOL: - return nodeToInstruction(node->metadata, instructions, instructions_size, - instructions_inserted); - case PARSED_TOKEN_VALUE_STRING: { - SizedString *string = nodeToString(node); - if (string == NULL) { + case TREE_TOKEN_VALUE_STRING: { + const TreeStringValueMetadata *tree_metadata = tree->metadata; + CommandPushStringOperand *operand = a404m_malloc(sizeof(*operand)); + operand->size = tree_metadata->size; + operand->str = a404m_malloc((operand->size + 1) * sizeof(char)); + memcpy(operand->str, tree_metadata->str, + (operand->size + 1) * sizeof(char)); + + const Instruction instruction = { + .command = COMMAND_PUSH_STRING, + .operand = operand, + }; + insertInstruction(instruction, instructions, instructions_size, + instructions_inserted); + return true; + } + case TREE_TOKEN_DEFINE_VARIABLE: { + const TreeDefineVariableMetadata *tree_metadata = tree->metadata; + if (tree_metadata->value == NULL) { + return true; + } else if (!nodeToInstruction(tree_metadata->value, instructions, + instructions_size, instructions_inserted, + code)) { return false; } + CommandPopIdentifierOperand *operand = a404m_malloc(sizeof(*operand)); + + operand->size = tree_metadata->nameEnd - tree_metadata->nameBegin; + operand->str = a404m_malloc((operand->size + 1) * sizeof(char)); + strncpy(operand->str, tree_metadata->nameBegin, operand->size); + const Instruction instruction = { - .command = COMMAND_PUSH_STRING, - .operand = string, + .command = COMMAND_POP_IDENTIFIER, + .operand = operand, }; insertInstruction(instruction, instructions, instructions_size, instructions_inserted); return true; } - case PARSED_TOKEN_NONE: - case PARSED_TOKEN_ROOT: + case TREE_TOKEN_DEFINE_CONSTANT: + return true; + case TREE_TOKEN_GLOBAL_SCOPE: + case TREE_TOKEN_LOCAL_SCOPE: + case TREE_TOKEN_STRUCT: + case TREE_TOKEN_FUNCTION: + case TREE_TOKEN_NONE: } - fprintf(stderr, "unexpected token %s\n", PARSED_TOKEN_STRINGS[node->token]); + printError("Unhandled token %s\n", code, tree->strBegin, tree->strEnd, + TREE_TOKEN_STRINGS[tree->token]); return false; } @@ -160,71 +217,3 @@ void insertInstruction(const Instruction instruction, (*instructions)[*instructions_inserted] = instruction; ++*instructions_inserted; } - -SizedString *nodeToString(ParsedNode const *node) { - const char *strBegin = node->strBegin + 1; - const char *strEnd = node->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: - fprintf(stderr, "bad string, bad '\\'\n"); - goto RETURN_ERROR; - } - } else { - fprintf(stderr, "bad string, bad '\\'\n"); - goto RETURN_ERROR; - } - } - str[inserted] = c; - ++inserted; - } - - str[inserted] = '\0'; - SizedString *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/code_generator/code_generator.h b/src/compiler/code_generator/code_generator.h index da5b686..0f8b69d 100644 --- a/src/compiler/code_generator/code_generator.h +++ b/src/compiler/code_generator/code_generator.h @@ -2,10 +2,15 @@ #include +#include "compiler/tree_parser/tree_parser.h" +#include "utils/types.h" + typedef enum Command { COMMAND_NONE = 0, COMMAND_CALL_FUNCTION, COMMAND_PUSH_STRING, + COMMAND_PUSH_IDENTIFIER, + COMMAND_POP_IDENTIFIER, } Command; extern const char *COMMAND_STRINGS[]; @@ -20,21 +25,25 @@ typedef struct Instructions { size_t size; } Instructions; +typedef SizedString CommandCallFunctionOperand; +typedef SizedString CommandPushStringOperand; +typedef SizedString CommandPushIdentifierOperand; +typedef SizedString CommandPopIdentifierOperand; + extern void printInstruction(Instruction instruction); extern void printInstructions(Instructions instructions); extern void deleteInstruction(Instruction instruction); extern void deleteInstructions(Instructions instructions); -extern Instructions codeGenerator(ParsedNode *root); +extern Instructions codeGenerator(SourceCode code); +extern Instructions _codeGenerator(ParsedTree *root, SourceCode code); -extern bool nodeToInstruction(ParsedNode *node, Instruction **instructions, +extern bool nodeToInstruction(ParsedTree *tree, Instruction **instructions, size_t *instructions_size, - size_t *instructions_inserted); + size_t *instructions_inserted, SourceCode code); extern void insertInstruction(const Instruction instruction, Instruction **restrict instructions, size_t *restrict instructions_size, size_t *restrict instructions_inserted); - -extern SizedString *nodeToString(ParsedNode const *node); -- cgit v1.2.3