aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/code_generator
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/code_generator')
-rw-r--r--src/compiler/code_generator/code_generator.c213
-rw-r--r--src/compiler/code_generator/code_generator.h19
2 files changed, 115 insertions, 117 deletions
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 <utils/memory/memory.h>
#include <utils/types.h>
+#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 <compiler/parser/parser.h>
+#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);