Start working on debugger

This commit is contained in:
2026-07-28 18:01:06 +10:00
parent 5dcbac3166
commit 7020ac3744
3 changed files with 158 additions and 2 deletions

View File

@@ -129,7 +129,8 @@ endif
cli_sources = files(
'src/cli/main.c'
'src/cli/main.c',
'src/cli/debugger.c'
)
incdir = include_directories('include')

140
src/cli/debugger.c Normal file
View File

@@ -0,0 +1,140 @@
#include "../../include/ground.h"
#include "../linenoise/linenoise.h"
#include <stdio.h>
#include <string.h>
typedef struct DebugCommand {
char* command;
struct {
char* at[32];
GroundSize count;
} args;
} DebugCommand;
static inline DebugCommand parseCommand(char* input) {
DebugCommand debugCommand;
// split by spaces
const char* delim = " ";
debugCommand.command = strtok(input, delim);
for (GroundSize i = 0; i < 32; i++) {
char* buf = strtok(NULL, delim);
if (buf == NULL) {
debugCommand.args.count = i;
break;
}
debugCommand.args.at[i] = buf;
}
return debugCommand;
}
typedef struct Debugger {
GroundSize currentInst;
} Debugger;
enum DebuggerStatus {
DBG_DONE, DBG_CONTINUE, DBG_WAIT, DBG_STEP
};
static inline enum DebuggerStatus runCommand(char* input, GroundBytecode* bytecode, Debugger* debugger) {
DebugCommand cmd = parseCommand(input);
if (strcmp(cmd.command, "help") == 0) {
printf(
"Commands: \n" \
" help - Show this help message\n" \
" continue - Run the program until next breakpoint, error, or otherwise termination\n" \
" step - Run one instruction\n" \
" break [idx] - Sets a breakpoint on the specified index\n" \
" exit - Stop debugging and exit\n\n" \
" dump - Dump current state of VM\n" \
" view [slot] - Prints the variable in the current slot\n" \
" set [slot] [value] - Sets the current slot to the specified value\n" \
" copy [slot] [slot] - Copies a value from the second slot to the first\n" \
);
return DBG_CONTINUE;
}
if (strcmp(cmd.command, "continue") == 0) {
return DBG_CONTINUE;
}
if (strcmp(cmd.command, "step") == 0) {
return DBG_STEP;
}
if (strcmp(cmd.command, "break") == 0) {
return DBG_WAIT;
}
if (strcmp(cmd.command, "exit") == 0) {
return DBG_DONE;
}
if (strcmp(cmd.command, "dump") == 0) {
printf("%s", Ground.Stringify.Bytecode(bytecode));
return DBG_WAIT;
}
if (strcmp(cmd.command, "view") == 0) {
return DBG_WAIT;
}
if (strcmp(cmd.command, "set") == 0) {
return DBG_WAIT;
}
if (strcmp(cmd.command, "copy") == 0) {
return DBG_WAIT;
}
fprintf(stderr, "Unknown command %s\n", cmd.command);
return DBG_WAIT;
}
static inline void runInstruction(GroundBytecodeProgram* program, GroundBytecodeHeap* heap) {
GroundSize i = 0;
while (i < program->len) {
struct GroundExecutionResult status = Ground.Bytecode.Instruction.execute(&program->at[i], heap);
if (Ground.Flags.error) {
fprintf(stderr, "Errors while debugging: \n");
Ground.Log.printErrors();
}
switch (status.type) {
case _GER_CONTINUE: i++; break;
case _GER_RETURN: return;
case _GER_JUMP: i = status.as.line; break;
case _GER_END: exit(status.as.end);
}
}
}
void runDebugger(GroundBytecode* bytecode) {
printf("Ground Debugger\n");
printf("Type 'help' for a list of commands\n");
printf("Type 'start' to begin debugging\n");
printf("Type 'exit' to exit\n");
Debugger debugger;
for (;;) {
char* input = linenoise("> ");
if (input == NULL) {
continue;
}
switch (runCommand(input, bytecode, &debugger)) {
case DBG_DONE: {
return;
}
case DBG_CONTINUE: {
break;
}
case DBG_WAIT: {
break;
}
case DBG_STEP: {
break;
}
}
free(input);
}
}

View File

@@ -1,6 +1,8 @@
#include "../../include/ground.h"
#include <stdio.h>
void runDebugger(GroundBytecode* bytecode);
enum ArgsAction {
ARGS_HELP, ARGS_EXECUTE, ARGS_DEBUG, ARGS_ASSEMBLE, ARGS_DISASSEMBLE
};
@@ -73,7 +75,20 @@ int main(int argc, char** argv) {
break;
}
case ARGS_DEBUG: {
fprintf(stderr, "Not yet implemented");
if (args.inputFile == NULL) {
fprintf(stderr, "Please specify a bytecode file\n");
return 1;
}
GroundBytecode bc = Ground.Bytecode.load(args.inputFile);
if (Ground.Flags.error) {
fprintf(stderr, "Failed to load bytecode, printing errors...\n");
Ground.Log.printErrors();
return 1;
}
runDebugger(&bc);
break;
}
case ARGS_ASSEMBLE: {