Implement variable length arguments, but really only for print
[fur] / templates / program2.c
index ffd014c..89d80de 100644 (file)
@@ -108,26 +108,36 @@ void call(struct Thread* thread, Argument argument) {
           break;
         case PRINT:
           {
-            // TODO Handle multiple arguments
-            assert(!Stack_isEmpty(&(thread->stack)));
-            Object arg = Stack_pop(&(thread->stack));
+            assert(argumentCount > 0);
+
+            Object arguments[argumentCount];
+            size_t count;
+
+            for(count = 0; count < argumentCount; count++) {
+              assert(!Stack_isEmpty(&(thread->stack)));
+              arguments[argumentCount - count - 1] = Stack_pop(&(thread->stack));
+            }
 
-            switch(arg.type) {
-              case BOOLEAN:
-                if(arg.value.boolean) printf("true");
-                else printf("false");
-                break;
+            for(count = 0; count < argumentCount; count ++) {
+              Object arg = arguments[count];
 
-              case INTEGER:
-                printf("%i", arg.value.integer);
-                break;
+              switch(arg.type) {
+                case BOOLEAN:
+                  if(arg.value.boolean) printf("true");
+                  else printf("false");
+                  break;
 
-              case STRING:
-                printf("%s", arg.value.string);
-                break;
+                case INTEGER:
+                  printf("%i", arg.value.integer);
+                  break;
 
-              default:
-                assert(0);
+                case STRING:
+                  printf("%s", arg.value.string);
+                  break;
+
+                default:
+                  assert(0);
+              }
             }
 
             Stack_push(&(thread->stack), BUILTIN_NIL);
@@ -174,6 +184,20 @@ void end(struct Thread* thread, Argument argument) {
   {% 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 %}
@@ -194,7 +218,7 @@ void end(struct Thread* thread, Argument argument) {
   {% 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);
@@ -286,7 +310,7 @@ const Instruction program[] = {
 
 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(