changeset 2190:59e0dcc01b2c

Add 'if' and 'while' debugger commands
author Michael Pavone <pavone@retrodev.com>
date Sat, 20 Aug 2022 12:08:01 -0700
parents 6b33ce6bc740
children d87a76afbd8a
files debug.c
diffstat 1 files changed, 55 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/debug.c	Sat Aug 20 11:41:41 2022 -0700
+++ b/debug.c	Sat Aug 20 12:08:01 2022 -0700
@@ -1475,6 +1475,37 @@
 	return 1;
 }
 
+static uint8_t execute_block(debug_root *root, command_block * block)
+{
+	uint8_t debugging = 1;
+	for (int i = 0; i < block->num_commands; i++)
+	{
+		debugging = run_command(root, block->commands + i) && debugging;
+	}
+	return debugging;
+}
+
+static uint8_t cmd_if(debug_root *root, parsed_command *cmd)
+{
+	return execute_block(root, cmd->args[0].value ? &cmd->block : &cmd->else_block);
+}
+
+static uint8_t cmd_while(debug_root *root, parsed_command *cmd)
+{
+	if (!cmd->args[0].value) {
+		return execute_block(root, &cmd->else_block);
+	}
+	int debugging = 1;
+	do {
+		debugging = execute_block(root, &cmd->block) && debugging;
+		if (!eval_expr(root, cmd->args[0].parsed, &cmd->args[0].value)) {
+			fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw);
+			return 1;
+		}
+	} while (cmd->args[0].value);
+	return debugging;
+}
+
 const char *expr_type_names[] = {
 	"EXPR_NONE",
 	"EXPR_SCALAR",
@@ -2031,6 +2062,30 @@
 		.min_args = 1,
 		.max_args = 2,
 		.skip_eval = 1
+	},
+	{
+		.names = (const char *[]){
+			"if", NULL
+		},
+		.usage = "if CONDITION",
+		.desc = "If the condition is true, the following block is executed. Otherwise the else block is executed if present",
+		.impl = cmd_if,
+		.min_args = 1,
+		.max_args = 1,
+		.has_block = 1,
+		.accepts_else = 1
+	},
+	{
+		.names = (const char *[]){
+			"while", NULL
+		},
+		.usage = "while CONDITION",
+		.desc = "The following block is executed repeatedly until the condition is false. If the condition is false at the start, the else block is executed if present",
+		.impl = cmd_while,
+		.min_args = 1,
+		.max_args = 1,
+		.has_block = 1,
+		.accepts_else = 1
 	}
 };
 #define NUM_COMMON (sizeof(common_commands)/sizeof(*common_commands))