#include "interpreter.h" #include "parser.h" #include "types.h" #include "include/uthash.h" #include 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); } } }