Add variables and add
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "include/uthash.h"
|
#include "include/uthash.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int currentInstruction = 0;
|
int currentInstruction = 0;
|
||||||
|
|
||||||
@@ -21,6 +22,14 @@ void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where
|
|||||||
printf("TooManyArgs");
|
printf("TooManyArgs");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case UNKNOWN_LABEL: {
|
||||||
|
printf("UnknownLabel");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UNKNOWN_VARIABLE: {
|
||||||
|
printf("UnknownVariable");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
case FIXME: {
|
case FIXME: {
|
||||||
printf("FIXME (please report issue to https://chsp.au/ground/cground)");
|
printf("FIXME (please report issue to https://chsp.au/ground/cground)");
|
||||||
@@ -98,6 +107,18 @@ void interpretGroundProgram(GroundProgram* in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) {
|
void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) {
|
||||||
|
// Insert variables prefixed with $
|
||||||
|
for (int i = 0; i < in->args.length; i++) {
|
||||||
|
if (in->args.args[i].type == VALREF) {
|
||||||
|
GroundVariable* variable = findVariable(*scope->variables, in->args.args[0].value.refName);
|
||||||
|
if (variable) {
|
||||||
|
in->args.args[i].value.value = variable->value;
|
||||||
|
in->args.args[i].type = VALUE;
|
||||||
|
} else {
|
||||||
|
runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (in->type) {
|
switch (in->type) {
|
||||||
// We can safely ignore any CREATELABEL instructions, these have been preprocessed
|
// We can safely ignore any CREATELABEL instructions, these have been preprocessed
|
||||||
case CREATELABEL: {
|
case CREATELABEL: {
|
||||||
@@ -156,7 +177,7 @@ void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) {
|
|||||||
}
|
}
|
||||||
case PRINT: {
|
case PRINT: {
|
||||||
if (in->args.length < 1) {
|
if (in->args.length < 1) {
|
||||||
runtimeError(TOO_FEW_ARGS, NULL, 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++) {
|
||||||
printGroundArg(&in->args.args[i]);
|
printGroundArg(&in->args.args[i]);
|
||||||
@@ -166,7 +187,7 @@ void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) {
|
|||||||
}
|
}
|
||||||
case PRINTLN: {
|
case PRINTLN: {
|
||||||
if (in->args.length < 1) {
|
if (in->args.length < 1) {
|
||||||
runtimeError(TOO_FEW_ARGS, NULL, 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++) {
|
||||||
printGroundArg(&in->args.args[i]);
|
printGroundArg(&in->args.args[i]);
|
||||||
@@ -175,6 +196,85 @@ void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SET: {
|
||||||
|
if (in->args.length < 2) {
|
||||||
|
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.length > 2) {
|
||||||
|
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.args[0].type != DIRREF) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.args[1].type != VALUE) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", in, currentInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
addVariable(scope->variables, in->args.args[0].value.refName, in->args.args[1].value.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ADD: {
|
||||||
|
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 == STRING) {
|
||||||
|
if (right->type != STRING) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a String for arg 2", in, currentInstruction);
|
||||||
|
}
|
||||||
|
char* newString = malloc(sizeof(char));
|
||||||
|
strcpy(newString, left->data.stringVal);
|
||||||
|
strcat(newString, right->data.stringVal);
|
||||||
|
|
||||||
|
addVariable(scope->variables, in->args.args[2].value.refName, createStringGroundValue(newString));
|
||||||
|
}
|
||||||
|
else 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 (left->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, Double, or String for arg 1", in, currentInstruction);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
runtimeError(FIXME, "Currently unimplemented instruction", in, currentInstruction);
|
runtimeError(FIXME, "Currently unimplemented instruction", in, currentInstruction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "include/uthash.h"
|
#include "include/uthash.h"
|
||||||
|
|
||||||
typedef enum GroundRuntimeError {
|
typedef enum GroundRuntimeError {
|
||||||
ARG_TYPE_MISMATCH, TOO_FEW_ARGS, TOO_MANY_ARGS, UNKNOWN_LABEL, FIXME
|
ARG_TYPE_MISMATCH, TOO_FEW_ARGS, TOO_MANY_ARGS, UNKNOWN_LABEL, UNKNOWN_VARIABLE, FIXME
|
||||||
} GroundRuntimeError;
|
} GroundRuntimeError;
|
||||||
|
|
||||||
typedef struct GroundLabel {
|
typedef struct GroundLabel {
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
@myLabel
|
# Check setting variables
|
||||||
println "dingus"
|
set &myVar "dingus"
|
||||||
jump %myLabel
|
println $myVar
|
||||||
|
|
||||||
|
# Check string concat
|
||||||
|
add "dingle" "fart" &myOtherVar
|
||||||
|
println $myOtherVar
|
||||||
|
|
||||||
|
# Check double math
|
||||||
|
add 3.14 2.7 &myThirdVar
|
||||||
|
println $myThirdVar
|
||||||
|
|
||||||
|
# Check int math
|
||||||
|
add 464398727 374298 &yetAnotherVar
|
||||||
|
println $yetAnotherVar
|
||||||
|
|
||||||
|
# Check mixed math
|
||||||
|
add 432 4732.12 &finalVar
|
||||||
|
println $finalVar
|
||||||
|
|||||||
Reference in New Issue
Block a user