Debugger
This commit is contained in:
@@ -149,9 +149,63 @@ GroundValueType stringToValueType(char* in) {
|
||||
if (strcmp(in, "list") == 0) {
|
||||
return LIST;
|
||||
}
|
||||
if (strcmp(in, "function") == 0) {
|
||||
return FUNCTION;
|
||||
}
|
||||
return CUSTOM;
|
||||
}
|
||||
|
||||
GroundDebugInstruction parseDebugInstruction(char* in) {
|
||||
GroundDebugInstruction gdi;
|
||||
size_t insize = strlen(in);
|
||||
size_t spacepos = -1;
|
||||
|
||||
for (size_t i = 0; i < insize; i++) {
|
||||
if (in[i] == ' ') {
|
||||
spacepos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spacepos == -1) {
|
||||
spacepos = insize;
|
||||
}
|
||||
|
||||
char* instruction = malloc(spacepos + 1);
|
||||
if (!instruction) {
|
||||
gdi.type = UNKNOWN;
|
||||
gdi.arg = NULL;
|
||||
return gdi;
|
||||
}
|
||||
strncpy(instruction, in, spacepos);
|
||||
instruction[spacepos] = '\0';
|
||||
|
||||
if (strcmp(instruction, "dump") == 0) {
|
||||
gdi.type = DUMP;
|
||||
} else if (strcmp(instruction, "inspect") == 0) {
|
||||
gdi.type = INSPECT;
|
||||
} else if (strcmp(instruction, "eval") == 0) {
|
||||
gdi.type = EVAL;
|
||||
} else if (strcmp(instruction, "continue") == 0) {
|
||||
gdi.type = CONTINUE;
|
||||
} else if (strcmp(instruction, "exit") == 0) {
|
||||
gdi.type = EXIT;
|
||||
} else if (strcmp(instruction, "help") == 0) {
|
||||
gdi.type = HELP;
|
||||
} else {
|
||||
gdi.type = UNKNOWN;
|
||||
}
|
||||
|
||||
size_t arglen = insize - spacepos;
|
||||
gdi.arg = malloc(arglen + 1);
|
||||
if (gdi.arg) {
|
||||
strcpy(gdi.arg, in + spacepos + 1);
|
||||
}
|
||||
|
||||
free(instruction);
|
||||
return gdi;
|
||||
}
|
||||
|
||||
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
||||
GroundLabel* labels = NULL;
|
||||
GroundVariable* variables = NULL;
|
||||
@@ -223,6 +277,92 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (in->instructions[i].type == PAUSE) {
|
||||
printf("Paused execution\n");
|
||||
printf("Previous instruction: ");
|
||||
if (i > 0) {
|
||||
printGroundInstruction(&in->instructions[i - 1]);
|
||||
}
|
||||
while (true) {
|
||||
printf("\nprompt> ");
|
||||
char buffer[256];
|
||||
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
|
||||
buffer[strcspn(buffer, "\n")] = '\0';
|
||||
} else {
|
||||
runtimeError(FIXME, "Failed to read input from console with fgets", NULL, -1);
|
||||
}
|
||||
GroundDebugInstruction gdi = parseDebugInstruction(buffer);
|
||||
|
||||
bool shouldBreak = false;
|
||||
switch (gdi.type) {
|
||||
case CONTINUE: {
|
||||
shouldBreak = true;
|
||||
break;
|
||||
}
|
||||
case EXIT: {
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case DUMP: {
|
||||
if (scope.variables == NULL) {
|
||||
printf("Can't access variables");
|
||||
break;
|
||||
}
|
||||
if (*scope.variables == NULL) {
|
||||
printf("Can't access variables");
|
||||
break;
|
||||
}
|
||||
GroundVariable* entry;
|
||||
GroundVariable* tmp;
|
||||
GroundVariable* head = *scope.variables;
|
||||
HASH_ITER(hh, head, entry, tmp) {
|
||||
if (entry != NULL) {
|
||||
printf("%s: ", entry->id);
|
||||
printGroundValue(&entry->value);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INSPECT: {
|
||||
printf("%s: ", gdi.arg);
|
||||
GroundVariable* var = findVariable(*scope.variables, gdi.arg);
|
||||
if (var == NULL) {
|
||||
printf("(nothing)");
|
||||
} else {
|
||||
printGroundValue(&var->value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVAL: {
|
||||
GroundProgram program = parseFile(gdi.arg);
|
||||
interpretGroundProgram(&program, &scope);
|
||||
freeGroundProgram(&program);
|
||||
break;
|
||||
}
|
||||
case HELP: {
|
||||
printf("Ground Debugger Help\n");
|
||||
printf("Didn't mean to end up here? Type \"continue\" to escape this prompt.\n");
|
||||
printf("Commands:\n");
|
||||
printf(" continue: Continue execution of the program\n");
|
||||
printf(" exit: Stop execution early\n");
|
||||
printf(" dump: Shows all variables and their contents\n");
|
||||
printf(" inspect (variable): Shows the contents of a variable\n");
|
||||
printf(" eval (code): Runs Ground code in the current scope\n");
|
||||
printf(" help: Shows this help message");
|
||||
}
|
||||
case UNKNOWN: {
|
||||
printf("Unknown instruction (type \"help\" for help)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shouldBreak) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int ci = currentInstruction;
|
||||
GroundValue gv = interpretGroundInstruction(in->instructions[i], &scope);
|
||||
if (gv.type != NONE) {
|
||||
|
||||
Reference in New Issue
Block a user