Add input instruction
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user