This commit is contained in:
2025-12-08 11:08:08 +11:00
parent 6e733910ec
commit bd1a47d118
7 changed files with 165 additions and 3 deletions

View File

@@ -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) {