aboutsummaryrefslogtreecommitdiff
path: root/src/vm/runner/runner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/runner/runner.c')
-rw-r--r--src/vm/runner/runner.c115
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);
}