Make the . operator into an instruction
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 3 Jan 2021 19:45:44 +0000 (14:45 -0500)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 3 Jan 2021 19:45:44 +0000 (14:45 -0500)
c_generation.py
crossplatform_ir_generation.py
desugaring.py
templates/program2.c

index 0e66abb..7fc4165 100644 (file)
@@ -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),
index f9c7fa9..c67a5f4 100644 (file)
@@ -60,6 +60,9 @@ def generate_instruction_name_from_builtin(builtin):
 
             # String operations
             '__concat__': 'concat',
+
+            # Structure operations
+            '__field__': 'field',
         }[builtin]
 
     except KeyError:
index b04cf1a..f3c7728 100644 (file)
@@ -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__',
             ),
index d22d595..01203fd 100644 (file)
@@ -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;