diff options
Diffstat (limited to 'src/vm/runner/runner.c')
-rw-r--r-- | src/vm/runner/runner.c | 115 |
1 files changed, 101 insertions, 14 deletions
diff --git a/src/vm/runner/runner.c b/src/vm/runner/runner.c index de1a478..4fcea52 100644 --- a/src/vm/runner/runner.c +++ b/src/vm/runner/runner.c @@ -3,6 +3,7 @@ #include <compiler/code_generator/code_generator.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <utils/memory/memory.h> #include <utils/types.h> @@ -15,18 +16,39 @@ const char *BUILTIN_FUNCTION_NAMES[] = { const size_t BUILTIN_FUNCTIONS_SIZE = sizeof(BUILTIN_FUNCTIONS) / sizeof(BuiltinFunction); -bool runner(Instructions instructions) { +bool runner(SourceCode code) { + Instructions instructions = codeGenerator(code); + if (instructions.size != ERROR_SIZE) { + bool ranSuccess = _runner(instructions); + deleteInstructions(instructions); + return ranSuccess; + } + return false; +} + +bool _runner(Instructions instructions) { size_t stack_size = 0; void **stack = a404m_malloc(stack_size * sizeof(void *)); size_t stack_inserted = 0; + size_t variables_size = 0; + RunnerVariable **variables = + a404m_malloc(variables_size * sizeof(RunnerVariable *)); + size_t variables_inserted = 0; + for (size_t i = 0; i < instructions.size; ++i) { if (!runInstruction(instructions.instructions[i], &stack, &stack_size, - &stack_inserted)) { + &stack_inserted, &variables, &variables_size, + &variables_inserted)) { goto RETURN_ERROR; } } + for(size_t i = 0;i < variables_size;++i){ + free(variables[i]); + } + + free(variables); free(stack); return true; @@ -38,7 +60,7 @@ RETURN_ERROR: BuiltinFunction getBuiltinFunction(SizedString string) { for (size_t i = 0; i < BUILTIN_FUNCTIONS_SIZE; ++i) { const char *search = BUILTIN_FUNCTION_NAMES[i]; - // faster than strlen+strncpy + // faster than strlen+strncmp for (size_t j = 0;; ++j) { const char searchChar = search[j]; if (j == string.size) { @@ -59,21 +81,25 @@ BuiltinFunction getBuiltinFunction(SizedString string) { bool runInstruction(Instruction instruction, void ***restrict stack, size_t *restrict stack_size, - size_t *restrict stack_inserted) { + size_t *restrict stack_inserted, + RunnerVariable ***restrict variables, + size_t *restrict variables_size, + size_t *restrict variables_inserted) { switch (instruction.command) { + case COMMAND_PUSH_IDENTIFIER: { + const CommandPushIdentifierOperand *operand = instruction.operand; + pushToStack(getRunnerVariable(operand, variables, variables_inserted)->value, + stack, stack_size, stack_inserted); + return true; + } 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; + CommandPushStringOperand *operand = instruction.operand; + pushToStack(operand, stack, stack_size, stack_inserted); return true; } case COMMAND_CALL_FUNCTION: { SizedString *functionName = instruction.operand; - BuiltinFunction function = getBuiltinFunction(*functionName); + const BuiltinFunction function = getBuiltinFunction(*functionName); if (function == NULL) { fprintf(stderr, "function '%.*s' not found\n", (int)functionName->size, functionName->str); @@ -82,13 +108,74 @@ bool runInstruction(Instruction instruction, void ***restrict stack, function(stack, stack_inserted); return true; } + case COMMAND_POP_IDENTIFIER: { + const CommandPopIdentifierOperand *operand = instruction.operand; + setRunnerVariable(popFromStack(stack, stack_inserted), operand, variables, + variables_size, variables_inserted); + return true; + } case COMMAND_NONE: } - fprintf(stderr, "unknown command '%d'\n", instruction.command); + fprintf(stderr, "bad command '%d'\n", instruction.command); return false; } +RunnerVariable *getRunnerVariable(const SizedString *varName, + RunnerVariable ***restrict variables, + size_t *restrict variables_inserted) { + for (size_t i = *variables_inserted - 1; i != (typeof(i))-1; ++i) { + RunnerVariable *variable = (*variables)[i]; + if (variable->name->size == varName->size && + strncmp(varName->str, variable->name->str, varName->size) == 0) { + return variable; + } + } + return NULL; +} + +void setRunnerVariable(void *value, const SizedString *varName, + RunnerVariable ***restrict variables, + size_t *restrict variables_size, + size_t *restrict variables_inserted) { + RunnerVariable *variable = + getRunnerVariable(varName, variables, variables_inserted); + if (variable != NULL) { + variable->value = value; + return; + } + + variable = a404m_malloc(sizeof(*variable)); + variable->name = varName; + variable->value = value; + + if (*variables_inserted == *variables_size) { + *variables_size += *variables_size / 2 + 1; + *variables = + a404m_realloc(*variables, *variables_size * sizeof(RunnerVariable *)); + } + (*variables)[*variables_inserted] = variable; + *variables_inserted += 1; +} + +void *popFromStack(void ***restrict stack, size_t *restrict stack_inserted) { + if (*stack_inserted == 0) { + fprintf(stderr, "stack underflow\n"); + exit(1); + } + return (*stack)[--*stack_inserted]; +} + +void pushToStack(void *value, void ***restrict stack, + size_t *restrict stack_size, size_t *restrict stack_inserted) { + if (*stack_inserted == *stack_size) { + *stack_size += *stack_size / 2 + 1; + *stack = a404m_realloc(*stack, *stack_size * sizeof(void *)); + } + (*stack)[*stack_inserted] = value; + ++*stack_inserted; +} + void print(void ***restrict stack, size_t *restrict stack_inserted) { - const SizedString *string = (*stack)[--*stack_inserted]; + const SizedString *string = popFromStack(stack, stack_inserted); printf("%.*s", (int)string->size, string->str); } |