Bug fixes
This commit is contained in:
@@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
int currentInstruction = 0;
|
int currentInstruction = 0;
|
||||||
|
|
||||||
GroundLabel* labels = NULL;
|
|
||||||
|
|
||||||
void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) {
|
void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) {
|
||||||
printf("Ground runtime error:\n ErrorType: ");
|
printf("Ground runtime error:\n ErrorType: ");
|
||||||
switch (error) {
|
switch (error) {
|
||||||
@@ -61,29 +59,45 @@ void deleteLabel(GroundLabel** head, GroundLabel *item) {
|
|||||||
free(item);
|
free(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_all(GroundLabel **head) {
|
void addVariable(GroundVariable **head, const char *id, GroundValue data) {
|
||||||
GroundLabel *current, *tmp;
|
GroundVariable* item = malloc(sizeof(GroundVariable));
|
||||||
HASH_ITER(hh, *head, current, tmp) {
|
snprintf(item->id, MAX_ID_LEN, "%s", id);
|
||||||
HASH_DEL(*head, current);
|
item->value = data;
|
||||||
free(current);
|
HASH_ADD_STR(*head, id, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroundVariable* findVariable(GroundVariable* head, const char *id) {
|
||||||
|
GroundVariable *item;
|
||||||
|
HASH_FIND_STR(head, id, item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteVariable(GroundVariable** head, GroundVariable *item) {
|
||||||
|
HASH_DEL(*head, item);
|
||||||
|
free(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpretGroundProgram(GroundProgram* in) {
|
void interpretGroundProgram(GroundProgram* in) {
|
||||||
|
GroundLabel* labels = NULL;
|
||||||
|
GroundVariable* variables = NULL;
|
||||||
|
|
||||||
|
GroundScope scope;
|
||||||
|
scope.labels = &labels;
|
||||||
|
scope.variables = &variables;
|
||||||
// Preprocess all labels
|
// Preprocess all labels
|
||||||
for (int i = 0; i < in->size; i++) {
|
for (int i = 0; i < in->size; i++) {
|
||||||
if (in->instructions[i].type == CREATELABEL) {
|
if (in->instructions[i].type == CREATELABEL) {
|
||||||
addLabel(&labels, in->instructions[i].args.args[0].value.refName, i);
|
addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (currentInstruction < in->size) {
|
while (currentInstruction < in->size) {
|
||||||
interpretGroundInstruction(&in->instructions[currentInstruction]);
|
interpretGroundInstruction(&in->instructions[currentInstruction], &scope);
|
||||||
currentInstruction++;
|
currentInstruction++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpretGroundInstruction(GroundInstruction* in) {
|
void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) {
|
||||||
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: {
|
||||||
@@ -96,21 +110,22 @@ void interpretGroundInstruction(GroundInstruction* in) {
|
|||||||
if (in->args.length > 2) {
|
if (in->args.length > 2) {
|
||||||
runtimeError(TOO_MANY_ARGS, "Expecting 2 arguments", in, currentInstruction);
|
runtimeError(TOO_MANY_ARGS, "Expecting 2 arguments", in, currentInstruction);
|
||||||
}
|
}
|
||||||
if (in->args.args[0].type != VALUE && in->args.args[0].value.value.type != BOOL) {
|
if (in->args.args[0].type != VALUE || in->args.args[0].value.value.type != BOOL) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a bool for arg 0", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a bool for arg 0", in, currentInstruction);
|
||||||
}
|
}
|
||||||
if (in->args.args[0].type != LINEREF) {
|
if (in->args.args[1].type != LINEREF) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 1", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 1", in, currentInstruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in->args.args[0].value.value.data.boolVal) {
|
if (in->args.args[0].value.value.data.boolVal) {
|
||||||
GroundLabel* label = findLabel(labels, in->args.args[1].value.refName);
|
GroundLabel* label = findLabel(*scope->labels, in->args.args[1].value.refName);
|
||||||
if (label) {
|
if (label) {
|
||||||
currentInstruction = label->lineNum;
|
currentInstruction = label->lineNum;
|
||||||
} else {
|
} else {
|
||||||
runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction);
|
runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case JUMP: {
|
case JUMP: {
|
||||||
if (in->args.length < 1) {
|
if (in->args.length < 1) {
|
||||||
@@ -123,17 +138,19 @@ void interpretGroundInstruction(GroundInstruction* in) {
|
|||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 1", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 1", in, currentInstruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
GroundLabel* label = findLabel(labels, in->args.args[0].value.refName);
|
GroundLabel* label = findLabel(*scope->labels, in->args.args[0].value.refName);
|
||||||
if (label) {
|
if (label) {
|
||||||
currentInstruction = label->lineNum;
|
currentInstruction = label->lineNum;
|
||||||
} else {
|
} else {
|
||||||
runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction);
|
runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case END: {
|
case END: {
|
||||||
if (in->args.length < 1) {
|
if (in->args.length < 1 || in->args.args[0].type != VALUE || in->args.args[0].value.value.type != INT) {
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
|
exit(in->args.args[0].value.value.data.intVal);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,17 @@ typedef struct GroundLabel {
|
|||||||
UT_hash_handle hh;
|
UT_hash_handle hh;
|
||||||
} GroundLabel;
|
} GroundLabel;
|
||||||
|
|
||||||
|
typedef struct GroundVariable {
|
||||||
|
char id[MAX_ID_LEN];
|
||||||
|
GroundValue value;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
} GroundVariable;
|
||||||
|
|
||||||
|
typedef struct GroundScope {
|
||||||
|
GroundLabel** labels;
|
||||||
|
GroundVariable** variables;
|
||||||
|
} GroundScope;
|
||||||
|
|
||||||
void interpretGroundProgram(GroundProgram* in);
|
void interpretGroundProgram(GroundProgram* in);
|
||||||
void interpretGroundInstruction(GroundInstruction* in);
|
void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,5 +45,6 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
char* file = getFileContents(argv[1]);
|
char* file = getFileContents(argv[1]);
|
||||||
GroundProgram program = parseFile(file);
|
GroundProgram program = parseFile(file);
|
||||||
|
free(file);
|
||||||
interpretGroundProgram(&program);
|
interpretGroundProgram(&program);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user