+void callBuiltinPow(Thread* thread, size_t argumentCount) {
+ assert(argumentCount == 2);
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object exponent = Stack_pop(&(thread->stack));
+ assert(exponent.type == INTEGER);
+ assert(exponent.value.integer >= 0);
+
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object base = Stack_pop(&(thread->stack));
+ assert(base.type == INTEGER);
+
+ Object result;
+ result.type = INTEGER;
+ result.value.integer = 1;
+
+ while(exponent.value.integer > 0) {
+ result.value.integer *= base.value.integer;
+ exponent.value.integer--;
+ }
+
+ Stack_push(&(thread->stack), result);
+}
+
+void callBuiltinPrint(Thread* thread, size_t argumentCount) {
+ 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));
+ }
+
+ for(count = 0; count < argumentCount; count ++) {
+ Object arg = arguments[count];
+
+ switch(arg.type) {
+ case BOOLEAN:
+ if(arg.value.boolean) printf("true");
+ else printf("false");
+ break;
+
+ case INTEGER:
+ printf("%i", arg.value.integer);
+ break;
+
+ case STRING:
+ printf("%s", arg.value.string);
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+
+ Stack_push(&(thread->stack), BUILTIN_NIL);
+}
+
+void callBuiltin(Thread* thread, Builtin b, size_t argumentCount) {
+ switch(b) {
+ case POW:
+ callBuiltinPow(thread, argumentCount);
+ break;
+ case PRINT:
+ callBuiltinPrint(thread, argumentCount);
+ break;
+
+ default:
+ assert(false);
+ }
+}
+
+void inst_call(struct Thread* thread, Argument argument) {