From 5e3bb8aa55a25e2ced307e06f6579c027749ff0e Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Sun, 3 Jan 2021 13:27:10 -0500 Subject: [PATCH] Get all examples compiling, though output is not correct --- c_generation.py | 7 ++- crossplatform_ir_generation.py | 8 +++ templates/frame.c | 17 ++++++ templates/program2.c | 94 ++++++++++++++++++++++++++++++++-- 4 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 templates/frame.c diff --git a/c_generation.py b/c_generation.py index 78a80b1..0e66abb 100644 --- a/c_generation.py +++ b/c_generation.py @@ -41,7 +41,7 @@ def generate_size_t_argument(argument): 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(')') @@ -53,14 +53,17 @@ def generate_argument(instruction): '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), @@ -71,7 +74,9 @@ def generate_argument(instruction): '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) diff --git a/crossplatform_ir_generation.py b/crossplatform_ir_generation.py index 49e7408..f9c7fa9 100644 --- a/crossplatform_ir_generation.py +++ b/crossplatform_ir_generation.py @@ -39,6 +39,10 @@ def generate_symbol_literal(symbol): def generate_instruction_name_from_builtin(builtin): try: return { + # Environment operations + '__get__': 'get', + + # Integer operations '__add__': 'add', '__integer_divide__': 'idiv', '__modular_divide__': 'mod', @@ -46,12 +50,16 @@ def generate_instruction_name_from_builtin(builtin): '__negate__': 'neg', '__subtract__': 'sub', + # Boolean operations '__eq__': 'eq', '__neq__': 'neq', '__lt__': 'lt', '__lte__': 'lte', '__gt__': 'gt', '__gte__': 'gte', + + # String operations + '__concat__': 'concat', }[builtin] except KeyError: diff --git a/templates/frame.c b/templates/frame.c new file mode 100644 index 0000000..3afd157 --- /dev/null +++ b/templates/frame.c @@ -0,0 +1,17 @@ +struct Frame; +typedef struct Frame Frame; +struct Frame { + + Environment* environment; + Frame* returnFrame; + size_t programCounter; +}; + +void Frame_initialize(Frame* self, Environment* environment, Frame* returnFrame, size_t programCounter) { + self->environment = environment; + self->returnFrame = returnFrame; + self->programCounter = programCounter; +} + +void Frame_deinitialize(Frame* self) { +} diff --git a/templates/program2.c b/templates/program2.c index 5ca9f61..f51cdbf 100644 --- a/templates/program2.c +++ b/templates/program2.c @@ -12,7 +12,9 @@ enum Type { BUILTIN, CLOSURE, INTEGER, - STRING + LIST, + STRING, + SYMBOL }; enum Builtin; @@ -37,14 +39,19 @@ struct Closure { 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 { @@ -52,6 +59,11 @@ struct Object { Value value; }; +struct List { + Object head; + List* tail; +}; + #define BUILTIN_NIL (Object) { BUILTIN, (Value)(Builtin)NIL } void Object_deinitialize(Object* self) { @@ -99,6 +111,7 @@ union Argument { void* pointer; char* string; int32_t integer; + char* symbol; }; void callBuiltinPow(Thread* thread, size_t argumentCount) { @@ -206,6 +219,29 @@ void inst_call(Thread* thread, Argument argument) { } } +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 %} @@ -232,6 +268,27 @@ void inst_end(Thread* thread, Argument argument) { {% 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 %} @@ -258,6 +315,25 @@ void inst_jump_if_false(Thread* thread, Argument argument) { } } +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 %} @@ -350,6 +426,14 @@ void inst_push_string(Thread* thread, Argument argument) { 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 %} @@ -369,6 +453,10 @@ void inst_return(Thread* thread, Argument argument) { free(returnFrame); } +void inst_structure(Thread* thread, Argument argument) { + assert(false); +} + struct Instruction; typedef const struct Instruction Instruction; struct Instruction { -- 2.20.1