Start work on interpreter
This commit is contained in:
97
src/interpreter.c
Normal file
97
src/interpreter.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "interpreter.h"
|
||||
#include "parser.h"
|
||||
#include "types.h"
|
||||
#include "include/uthash.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int currentInstruction = 0;
|
||||
|
||||
void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) {
|
||||
printf("Ground runtime error:\n ErrorType: ");
|
||||
switch (error) {
|
||||
case ARG_TYPE_MISMATCH: {
|
||||
printf("ArgTypeMismatch");
|
||||
break;
|
||||
}
|
||||
case TOO_FEW_ARGS: {
|
||||
printf("TooFewArgs");
|
||||
break;
|
||||
}
|
||||
case TOO_MANY_ARGS: {
|
||||
printf("TooManyArgs");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case FIXME: {
|
||||
printf("FIXME (please report issue to https://chsp.au/ground/cground)");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if (what != NULL) {
|
||||
printf(" ErrorContext: %s\n", what);
|
||||
}
|
||||
if (where != NULL) {
|
||||
printf(" ErrorInstruction: ");
|
||||
printGroundInstruction(where);
|
||||
printf("\n");
|
||||
}
|
||||
if (whereLine > -1) {
|
||||
printf(" ErrorLine: %d\n", whereLine + 1);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void interpretGroundProgram(GroundProgram* in) {
|
||||
// Preprocess all labels
|
||||
for (int i = 0; i < in->size; i++) {
|
||||
if (in->instructions[i].type == CREATELABEL) {
|
||||
// labelHashmap.addLabel()
|
||||
}
|
||||
}
|
||||
while (currentInstruction < in->size) {
|
||||
interpretGroundInstruction(&in->instructions[currentInstruction]);
|
||||
currentInstruction++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void interpretGroundInstruction(GroundInstruction* in) {
|
||||
switch (in->type) {
|
||||
// We can safely ignore any CREATELABEL instructions, these have been preprocessed
|
||||
case CREATELABEL: {
|
||||
break;
|
||||
}
|
||||
case PRINT: {
|
||||
if (in->args.length < 1) {
|
||||
runtimeError(TOO_FEW_ARGS, NULL, in, currentInstruction);
|
||||
}
|
||||
for (int i = 0; i < in->args.length; i++) {
|
||||
printGroundArg(&in->args.args[i]);
|
||||
printf(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PRINTLN: {
|
||||
if (in->args.length < 1) {
|
||||
runtimeError(TOO_FEW_ARGS, NULL, in, currentInstruction);
|
||||
}
|
||||
for (int i = 0; i < in->args.length; i++) {
|
||||
printGroundArg(&in->args.args[i]);
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
case END: {
|
||||
if (in->args.length < 1) {
|
||||
exit(0);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
runtimeError(FIXME, "Currently unimplemented instruction", in, currentInstruction);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user