From c24be69b26aedc427c7831f150e86ca00182d8e0 Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Sun, 3 Jan 2021 14:45:44 -0500 Subject: [PATCH] Make the . operator into an instruction --- c_generation.py | 1 + crossplatform_ir_generation.py | 3 ++ desugaring.py | 2 +- templates/program2.c | 55 +++++++++++++--------------------- 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/c_generation.py b/c_generation.py index 0e66abb..7fc4165 100644 --- a/c_generation.py +++ b/c_generation.py @@ -57,6 +57,7 @@ def generate_argument(instruction): 'drop': generate_null_argument, 'end': generate_null_argument, 'eq': generate_null_argument_from(2), + 'field': generate_null_argument_from(2), 'get': generate_null_argument_from(2), 'gt': generate_null_argument_from(2), 'gte': generate_null_argument_from(2), diff --git a/crossplatform_ir_generation.py b/crossplatform_ir_generation.py index f9c7fa9..c67a5f4 100644 --- a/crossplatform_ir_generation.py +++ b/crossplatform_ir_generation.py @@ -60,6 +60,9 @@ def generate_instruction_name_from_builtin(builtin): # String operations '__concat__': 'concat', + + # Structure operations + '__field__': 'field', }[builtin] except KeyError: diff --git a/desugaring.py b/desugaring.py index b04cf1a..f3c7728 100644 --- a/desugaring.py +++ b/desugaring.py @@ -168,7 +168,7 @@ def desugar_infix_expression(expression): if expression.operator == '.': return DesugaredFunctionCallExpression( metadata=expression.metadata, - function=DesugaredSymbolExpression( + function=DesugaredBuiltinExpression( metadata=expression.metadata, symbol='__field__', ), diff --git a/templates/program2.c b/templates/program2.c index d22d595..01203fd 100644 --- a/templates/program2.c +++ b/templates/program2.c @@ -21,7 +21,6 @@ enum Type { enum Builtin; typedef enum Builtin Builtin; enum Builtin { - __FIELD__, NIL, POW, PRINT @@ -126,28 +125,6 @@ union Argument { char* symbol; }; -void callBuiltinField(Thread* thread, size_t argumentCount) { - assert(argumentCount == 2); - - assert(!Stack_isEmpty(&(thread->stack))); - Object key = Stack_pop(&(thread->stack)); - assert(key.type == SYMBOL); - - assert(!Stack_isEmpty(&(thread->stack))); - Object structure = Stack_pop(&(thread->stack)); - assert(structure.type == STRUCTURE); - - while(structure.value.structure != NULL) { - if(strcmp(structure.value.structure->key, key.value.string) == 0) { - Stack_push(&(thread->stack), structure.value.structure->value); - return; - } - structure.value.structure = structure.value.structure->next; - } - - assert(false); // Symbol wasn't found in structure -} - void callBuiltinPow(Thread* thread, size_t argumentCount) { assert(argumentCount == 2); assert(!Stack_isEmpty(&(thread->stack))); @@ -209,10 +186,6 @@ void callBuiltinPrint(Thread* thread, size_t argumentCount) { void callBuiltin(Thread* thread, Builtin b, size_t argumentCount) { switch(b) { - case __FIELD__: - callBuiltinField(thread, argumentCount); - break; - case POW: callBuiltinPow(thread, argumentCount); break; @@ -307,6 +280,26 @@ void inst_end(Thread* thread, Argument argument) { {% include "comparison_instruction.c" %} {% endwith %} +void inst_field(Thread* thread, Argument argument) { + assert(!Stack_isEmpty(&(thread->stack))); + Object key = Stack_pop(&(thread->stack)); + assert(key.type == SYMBOL); + + assert(!Stack_isEmpty(&(thread->stack))); + Object structure = Stack_pop(&(thread->stack)); + assert(structure.type == STRUCTURE); + + while(structure.value.structure != NULL) { + if(strcmp(structure.value.structure->key, key.value.string) == 0) { + Stack_push(&(thread->stack), structure.value.structure->value); + return; + } + structure.value.structure = structure.value.structure->next; + } + + assert(false); // Symbol wasn't found in structure +} + void inst_get(Thread* thread, Argument argument) { assert(!Stack_isEmpty(&(thread->stack))); Object indexObject = Stack_pop(&(thread->stack)); @@ -425,13 +418,7 @@ void inst_pop(Thread* thread, Argument argument) { void inst_push(Thread* thread, Argument argument) { char* argumentString = argument.string; - if(strcmp(argumentString, "__field__") == 0) { - // TODO Make this an instruction - Object result; - result.type = BUILTIN; - result.value.builtin = __FIELD__; - Stack_push(&(thread->stack), result); - } else if(strcmp(argumentString, "false") == 0) { + if(strcmp(argumentString, "false") == 0) { Stack_push(&(thread->stack), (Object){ BOOLEAN, false }); } else if(strcmp(argumentString, "pow") == 0) { Object result; -- 2.20.1