Implement and/or, introducing jumps and labels
authorDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 1 Oct 2019 06:27:35 +0000 (02:27 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 1 Oct 2019 06:27:35 +0000 (02:27 -0400)
c_generation.py
templates/program2.c

index a1e4e59..821048f 100644 (file)
@@ -22,6 +22,9 @@ def generate_integer_argument(argument):
     assert isinstance(argument, int)
     return '(int32_t){}'.format(argument)
 
     assert isinstance(argument, int)
     return '(int32_t){}'.format(argument)
 
+def generate_label_argument(argument):
+    return 'LABEL_{}'.format(argument)
+
 def generate_null_argument(argument):
     assert argument is None
     return 'NULL'
 def generate_null_argument(argument):
     assert argument is None
     return 'NULL'
@@ -55,6 +58,8 @@ def generate_argument(instruction):
             'gt': generate_null_argument_from(2),
             'gte': generate_null_argument_from(2),
             'idiv': 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,
             'lt': generate_null_argument_from(2),
             'lte': generate_null_argument_from(2),
             'mod': generate_null_argument_from(2),
             'lt': generate_null_argument_from(2),
             'lte': generate_null_argument_from(2),
             'mod': generate_null_argument_from(2),
index ffd014c..180a4c7 100644 (file)
@@ -174,6 +174,20 @@ void end(struct Thread* thread, Argument argument) {
   {% include "arithmetic_instruction.c" %}
 {% endwith %}
 
   {% include "arithmetic_instruction.c" %}
 {% endwith %}
 
+void jump(Thread* thread, Argument argument) {
+  thread->program_counter = argument.label - 1; // We will increment before running
+}
+
+void jump_if_false(Thread* thread, Argument argument) {
+  assert(!Stack_isEmpty(&(thread->stack)));
+  Object result = Stack_pop(&(thread->stack));
+  assert(result.type == BOOLEAN);
+
+  if(!(result.value.boolean)) {
+    jump(thread, argument);
+  }
+}
+
 {% with name='lt', operation='<' %}
   {% include "comparison_instruction.c" %}
 {% endwith %}
 {% with name='lt', operation='<' %}
   {% include "comparison_instruction.c" %}
 {% endwith %}
@@ -194,7 +208,7 @@ void end(struct Thread* thread, Argument argument) {
   {% include "comparison_instruction.c" %}
 {% endwith %}
 
   {% include "comparison_instruction.c" %}
 {% endwith %}
 
-void neg(struct Thread* thread, Argument argument) {
+void neg(Thread* thread, Argument argument) {
   assert(!Stack_isEmpty(&(thread->stack)));
   Object result = Stack_pop(&(thread->stack));
   assert(result.type == INTEGER);
   assert(!Stack_isEmpty(&(thread->stack)));
   Object result = Stack_pop(&(thread->stack));
   assert(result.type == INTEGER);
@@ -286,7 +300,7 @@ const Instruction program[] = {
 
 int main() {
   Thread thread;
 
 int main() {
   Thread thread;
-  Thread_initialize(&thread, 0);
+  Thread_initialize(&thread, LABEL___main__);
 
   for(; program[thread.program_counter].instruction != end; thread.program_counter++) {
     program[thread.program_counter].instruction(
 
   for(; program[thread.program_counter].instruction != end; thread.program_counter++) {
     program[thread.program_counter].instruction(