diff options
Diffstat (limited to 'src/vm/runner/runner.c')
-rw-r--r-- | src/vm/runner/runner.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/vm/runner/runner.c b/src/vm/runner/runner.c new file mode 100644 index 0000000..5e63395 --- /dev/null +++ b/src/vm/runner/runner.c @@ -0,0 +1,50 @@ +#include "runner.h" + +#include <stdio.h> +#include <stdlib.h> +#include <utils/memory/memory.h> +#include <utils/types.h> + +bool runner(Instructions instructions) { + size_t stack_size = 0; + void **stack = a404m_malloc(stack_size * sizeof(void *)); + size_t stack_inserted = 0; + for (size_t i = 0; i < instructions.size; ++i) { + if (!runInstruction(instructions.instructions[i], &stack, &stack_size, + &stack_inserted)) { + goto RETURN_ERROR; + } + } + + free(stack); + return true; + +RETURN_ERROR: + free(stack); + return false; +} + +bool runInstruction(Instruction instruction, void ***restrict stack, + size_t *restrict stack_size, + size_t *restrict stack_inserted) { + switch (instruction.command) { + case COMMAND_PRINT: { + const SizedString *string = (*stack)[*stack_inserted - 1]; + --*stack_inserted; + printf("%.*s", (int)string->size, string->str); + } break; + case COMMAND_PUSH_STRING: { + SizedString *string = instruction.operand; + if (*stack_inserted == *stack_size) { + *stack_size += *stack_size / 2 + 1; + *stack = a404m_realloc(*stack, *stack_size * sizeof(void *)); + } + (*stack)[*stack_inserted] = string; + ++*stack_inserted; + } break; + default: + fprintf(stderr, "unknown command '%d'\n", instruction.command); + return false; + } + return true; +} |