Implemented integer comparison
authorDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 1 Oct 2019 06:09:09 +0000 (02:09 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 1 Oct 2019 06:09:09 +0000 (02:09 -0400)
c_generation.py
crossplatform_ir_generation.py
templates/arithmetic_instruction.c
templates/comparison_instruction.c [new file with mode: 0644]
templates/program2.c

index fba8f50..a1e4e59 100644 (file)
@@ -26,6 +26,13 @@ def generate_null_argument(argument):
     assert argument is None
     return 'NULL'
 
+def generate_null_argument_from(argument_count):
+    def generator(argument):
+        assert isinstance(argument, int)
+        assert argument == argument_count
+        return 'NULL'
+    return generator
+
 def generate_size_t_argument(argument):
     assert isinstance(argument, int)
     return '(size_t){}'.format(argument)
@@ -40,19 +47,25 @@ def generate_symbol_argument(argument):
 def generate_argument(instruction):
     try:
         return {
-            'add': generate_size_t_argument,
+            'add': generate_null_argument_from(2),
+            'call': generate_size_t_argument,
             'drop': generate_null_argument,
             'end': generate_null_argument,
-            'call': generate_size_t_argument,
-            'idiv': generate_size_t_argument,
-            'mod': generate_size_t_argument,
-            'mul': generate_size_t_argument,
-            'neg': generate_size_t_argument,
+            'eq': generate_null_argument_from(2),
+            'gt': generate_null_argument_from(2),
+            'gte': generate_null_argument_from(2),
+            'idiv': generate_null_argument_from(2),
+            'lt': generate_null_argument_from(2),
+            'lte': generate_null_argument_from(2),
+            'mod': generate_null_argument_from(2),
+            'mul': generate_null_argument_from(2),
+            'neg': generate_null_argument_from(1),
+            'neq': generate_null_argument_from(2),
             'pop': generate_symbol_argument,
             'push': generate_symbol_argument,
             'push_integer': generate_integer_argument,
             'push_string': generate_string_argument,
-            'sub': generate_size_t_argument,
+            'sub': generate_null_argument_from(2),
         }[instruction.instruction](instruction.argument)
 
     except KeyError:
index c452126..49e7408 100644 (file)
@@ -45,6 +45,13 @@ def generate_instruction_name_from_builtin(builtin):
             '__multiply__': 'mul',
             '__negate__': 'neg',
             '__subtract__': 'sub',
+
+            '__eq__': 'eq',
+            '__neq__': 'neq',
+            '__lt__': 'lt',
+            '__lte__': 'lte',
+            '__gt__': 'gt',
+            '__gte__': 'gte',
         }[builtin]
 
     except KeyError:
index a78a579..5b68efd 100644 (file)
@@ -1,12 +1,12 @@
 void {{ name }}(struct Thread* thread, const union Argument argument) {
-  // We're going to reuse result as both the addend and the sum
+  // We're going to reuse result as both the first input and the result
   assert(!Stack_isEmpty(&(thread->stack)));
   Object result = Stack_pop(&(thread->stack));
   assert(result.type == INTEGER);
 
   assert(!Stack_isEmpty(&(thread->stack)));
   Object other = Stack_pop(&(thread->stack));
-  assert(result.type == INTEGER);
+  assert(other.type == INTEGER);
 
   result.value.integer = other.value.integer {{ operation }} result.value.integer;
 
diff --git a/templates/comparison_instruction.c b/templates/comparison_instruction.c
new file mode 100644 (file)
index 0000000..dabd905
--- /dev/null
@@ -0,0 +1,15 @@
+void {{ name }}(struct Thread* thread, const union Argument argument) {
+  // We're going to reuse result as both the first input and the result
+  assert(!Stack_isEmpty(&(thread->stack)));
+  Object result = Stack_pop(&(thread->stack));
+  assert(result.type == INTEGER);
+
+  assert(!Stack_isEmpty(&(thread->stack)));
+  Object other = Stack_pop(&(thread->stack));
+  assert(other.type == INTEGER);
+
+  result.type = BOOLEAN;
+  result.value.boolean = other.value.integer {{ operation }} result.value.integer;
+
+  Stack_push(&(thread->stack), result);
+}
index 1610a54..ffd014c 100644 (file)
@@ -117,6 +117,7 @@ void call(struct Thread* thread, Argument argument) {
                 if(arg.value.boolean) printf("true");
                 else printf("false");
                 break;
+
               case INTEGER:
                 printf("%i", arg.value.integer);
                 break;
@@ -157,10 +158,30 @@ void drop(struct Thread* thread, Argument argument) {
 void end(struct Thread* thread, Argument argument) {
 }
 
+{% with name='eq', operation='==' %}
+  {% include "comparison_instruction.c" %}
+{% endwith %}
+
+{% with name='gt', operation='>' %}
+  {% include "comparison_instruction.c" %}
+{% endwith %}
+
+{% with name='gte', operation='>=' %}
+  {% include "comparison_instruction.c" %}
+{% endwith %}
+
 {% with name='idiv', operation='/' %}
   {% include "arithmetic_instruction.c" %}
 {% endwith %}
 
+{% with name='lt', operation='<' %}
+  {% include "comparison_instruction.c" %}
+{% endwith %}
+
+{% with name='lte', operation='<=' %}
+  {% include "comparison_instruction.c" %}
+{% endwith %}
+
 {% with name='mod', operation='%' %}
   {% include "arithmetic_instruction.c" %}
 {% endwith %}
@@ -169,6 +190,10 @@ void end(struct Thread* thread, Argument argument) {
   {% include "arithmetic_instruction.c" %}
 {% endwith %}
 
+{% with name='neq', operation='!=' %}
+  {% include "comparison_instruction.c" %}
+{% endwith %}
+
 void neg(struct Thread* thread, Argument argument) {
   assert(!Stack_isEmpty(&(thread->stack)));
   Object result = Stack_pop(&(thread->stack));