Add input instruction

This commit is contained in:
2025-11-24 11:37:16 +11:00
parent 51e9df75c3
commit fa44e3ee60

View File

@@ -192,8 +192,8 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction);
} }
for (int i = 0; i < in->args.length; i++) { for (int i = 0; i < in->args.length; i++) {
if (i != 0) printf(" ");
printGroundArg(&in->args.args[i]); printGroundArg(&in->args.args[i]);
printf(" ");
} }
break; break;
} }
@@ -202,12 +202,28 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction);
} }
for (int i = 0; i < in->args.length; i++) { for (int i = 0; i < in->args.length; i++) {
if (i != 0) printf(" ");
printGroundArg(&in->args.args[i]); printGroundArg(&in->args.args[i]);
printf(" ");
} }
printf("\n"); printf("\n");
break; break;
} }
case INPUT: {
if (in->args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", in, currentInstruction);
}
char buffer[256];
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
buffer[strcspn(buffer, "\n")] = '\0';
addVariable(scope->variables, in->args.args[0].value.refName, createStringGroundValue(buffer));
} else {
runtimeError(FIXME, "Failed to read input from console with fgets", in, currentInstruction);
}
break;
}
case SET: { case SET: {
if (in->args.length < 2) { if (in->args.length < 2) {
@@ -287,6 +303,156 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
} }
break; break;
} }
case SUBTRACT: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction);
}
GroundValue* left = &in->args.args[0].value.value;
GroundValue* right = &in->args.args[1].value.value;
if (left->type == INT || left->type == DOUBLE) {
if (right->type != INT && right->type != DOUBLE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int or Double for arg 2", in, currentInstruction);
}
if (left->type == DOUBLE || right->type == DOUBLE) {
double result = 0;
if (left->type == INT) {
result -= left->data.intVal;
} else if (left->type == DOUBLE) {
result -= left->data.doubleVal;
}
if (right->type == INT) {
result += right->data.intVal;
} else if (right->type == DOUBLE) {
result += right->data.doubleVal;
}
addVariable(scope->variables, in->args.args[2].value.refName, createDoubleGroundValue(result));
} else {
int64_t result = left->data.intVal - right->data.intVal;
addVariable(scope->variables, in->args.args[2].value.refName, createIntGroundValue(result));
}
} else {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int or Double for arg 1", in, currentInstruction);
}
break;
}
case MULTIPLY: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction);
}
GroundValue* left = &in->args.args[0].value.value;
GroundValue* right = &in->args.args[1].value.value;
if (left->type == INT || left->type == DOUBLE) {
if (right->type != INT && right->type != DOUBLE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int or Double for arg 2", in, currentInstruction);
}
if (left->type == DOUBLE || right->type == DOUBLE) {
double result = 0;
if (left->type == INT) {
result *= left->data.intVal;
} else if (left->type == DOUBLE) {
result += left->data.doubleVal;
}
if (right->type == INT) {
result *= right->data.intVal;
} else if (right->type == DOUBLE) {
result += right->data.doubleVal;
}
addVariable(scope->variables, in->args.args[2].value.refName, createDoubleGroundValue(result));
} else {
int64_t result = left->data.intVal * right->data.intVal;
addVariable(scope->variables, in->args.args[2].value.refName, createIntGroundValue(result));
}
} else {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int or Double for arg 1", in, currentInstruction);
}
break;
}
case DIVIDE: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction);
}
GroundValue* left = &in->args.args[0].value.value;
GroundValue* right = &in->args.args[1].value.value;
if (left->type == INT || left->type == DOUBLE) {
if (right->type != INT && right->type != DOUBLE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int or Double for arg 2", in, currentInstruction);
}
if (left->type == DOUBLE || right->type == DOUBLE) {
double result = 0;
if (left->type == INT) {
result /= left->data.intVal;
} else if (left->type == DOUBLE) {
result /= left->data.doubleVal;
}
if (right->type == INT) {
result /= right->data.intVal;
} else if (right->type == DOUBLE) {
result /= right->data.doubleVal;
}
addVariable(scope->variables, in->args.args[2].value.refName, createDoubleGroundValue(result));
} else {
int64_t result = left->data.intVal / right->data.intVal;
addVariable(scope->variables, in->args.args[2].value.refName, createIntGroundValue(result));
}
} else {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int or Double for arg 1", in, currentInstruction);
}
break;
}
case EQUAL: { case EQUAL: {
if (in->args.length < 3) { if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);