return '(size_t){}'.format(argument)
def generate_string_argument(argument):
- return argument
+ return argument[0] + ''.join('\\"' if ch == '"' else ch for ch in argument[1:-1]) + argument[-1]
def generate_symbol_argument(argument):
assert argument.startswith('sym(') and argument.endswith(')')
'add': generate_null_argument_from(2),
'call': generate_size_t_argument,
'close': generate_label_argument,
+ 'concat': generate_integer_argument,
'drop': generate_null_argument,
'end': generate_null_argument,
'eq': generate_null_argument_from(2),
+ 'get': generate_null_argument_from(2),
'gt': generate_null_argument_from(2),
'gte': generate_null_argument_from(2),
'idiv': generate_null_argument_from(2),
'jump': generate_label_argument,
'jump_if_false': generate_label_argument,
+ 'list': generate_integer_argument,
'lt': generate_null_argument_from(2),
'lte': generate_null_argument_from(2),
'mod': generate_null_argument_from(2),
'push': generate_symbol_argument,
'push_integer': generate_integer_argument,
'push_string': generate_string_argument,
+ 'push_symbol': generate_symbol_argument,
'return': generate_null_argument,
+ 'structure': generate_integer_argument,
'sub': generate_null_argument_from(2),
}[instruction.instruction](instruction.argument)
BUILTIN,
CLOSURE,
INTEGER,
- STRING
+ LIST,
+ STRING,
+ SYMBOL
};
enum Builtin;
size_t entry;
};
+struct List;
+typedef struct List List;
+
union Value;
typedef union Value Value;
union Value {
Builtin builtin;
- Closure closure;
bool boolean;
- char* string;
+ Closure closure;
int32_t integer;
+ List* list;
+ char* string;
+ char* symbol;
};
struct Object {
Value value;
};
+struct List {
+ Object head;
+ List* tail;
+};
+
#define BUILTIN_NIL (Object) { BUILTIN, (Value)(Builtin)NIL }
void Object_deinitialize(Object* self) {
void* pointer;
char* string;
int32_t integer;
+ char* symbol;
};
void callBuiltinPow(Thread* thread, size_t argumentCount) {
}
}
+void inst_concat(Thread* thread, Argument argument) {
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object left = Stack_pop(&(thread->stack));
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object right = Stack_pop(&(thread->stack));
+
+ assert(left.type == STRING);
+ assert(right.type == STRING);
+
+ char* resultString = malloc(strlen(left.value.string) + strlen(right.value.string) + 1);
+ resultString[0] = '\0';
+
+ strcat(resultString, left.value.string);
+ strcat(resultString, right.value.string);
+
+ Object resultObject = (Object) {
+ STRING,
+ (Value)resultString
+ };
+
+ Stack_push(&(thread->stack), resultObject);
+}
+
{% with name='add', operation='+' %}
{% include "arithmetic_instruction.c" %}
{% endwith %}
{% include "comparison_instruction.c" %}
{% endwith %}
+void inst_get(Thread* thread, Argument argument) {
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object listObject = Stack_pop(&(thread->stack));
+ assert(listObject.type == LIST);
+ List* list = listObject.value.list;
+
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object indexObject = Stack_pop(&(thread->stack));
+ assert(indexObject.type == INTEGER);
+ int32_t index = indexObject.value.integer;
+
+ while(index > 0) {
+ assert(list != NULL);
+ list = list->tail;
+ index--;
+ }
+
+ assert(list != NULL);
+ Stack_push(&(thread->stack), list->head);
+}
+
{% with name='gt', operation='>' %}
{% include "comparison_instruction.c" %}
{% endwith %}
}
}
+void inst_list(Thread* thread, Argument argument) {
+ Object result;
+ result.type = LIST;
+ result.value.list = NULL;
+
+ while(argument.integer > 0) {
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object item = Stack_pop(&(thread->stack));
+
+ List* node = malloc(sizeof(List));
+ node->head = item;
+ node->tail = result.value.list;
+
+ result.value.list = node;
+ }
+
+ Stack_push(&(thread->stack), result);
+}
+
{% with name='lt', operation='<' %}
{% include "comparison_instruction.c" %}
{% endwith %}
Stack_push(&(thread->stack), result);
}
+void inst_push_symbol(Thread* thread, Argument argument) {
+ // TODO Store symbols in a symbol table so they can be looked up by reference
+ // without string comparison
+ Object result;
+ result.type = SYMBOL;
+ result.value.symbol = argument.symbol;
+}
+
{% with name='sub', operation='-' %}
{% include "arithmetic_instruction.c" %}
{% endwith %}
free(returnFrame);
}
+void inst_structure(Thread* thread, Argument argument) {
+ assert(false);
+}
+
struct Instruction;
typedef const struct Instruction Instruction;
struct Instruction {