aboutsummaryrefslogtreecommitdiff
path: root/src/vm/runner/runner.c
blob: 5e6339500d5817058322d432b40ac9195b12c8e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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;
}