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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include "runner.h"
#include <compiler/code_generator/code_generator.h>
#include <stdio.h>
#include <stdlib.h>
#include <utils/memory/memory.h>
#include <utils/types.h>
const BuiltinFunction BUILTIN_FUNCTIONS[] = {
print,
};
const char *BUILTIN_FUNCTION_NAMES[] = {
"print",
};
const size_t BUILTIN_FUNCTIONS_SIZE =
sizeof(BUILTIN_FUNCTIONS) / sizeof(BuiltinFunction);
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;
}
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
for (size_t j = 0;; ++j) {
const char searchChar = search[j];
if (j == string.size) {
if (searchChar == '\0') {
return BUILTIN_FUNCTIONS[i];
} else {
break;
}
} else if (searchChar == '\0') {
break;
} else if (searchChar != string.str[j]) {
break;
}
}
}
return NULL;
}
bool runInstruction(Instruction instruction, void ***restrict stack,
size_t *restrict stack_size,
size_t *restrict stack_inserted) {
switch (instruction.command) {
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;
return true;
}
case COMMAND_CALL_FUNCTION: {
SizedString *functionName = instruction.operand;
BuiltinFunction function = getBuiltinFunction(*functionName);
if (function == NULL) {
fprintf(stderr, "function '%.*s' not found\n", (int)functionName->size,
functionName->str);
return false;
}
function(stack, stack_inserted);
return true;
}
case COMMAND_NONE:
}
fprintf(stderr, "unknown command '%d'\n", instruction.command);
return false;
}
void print(void ***restrict stack, size_t *restrict stack_inserted) {
const SizedString *string = (*stack)[--*stack_inserted];
printf("%.*s", (int)string->size, string->str);
}
|