changeset 2364:c822bb628fc3

Add support for function call expressions in debug parser
author Michael Pavone <pavone@retrodev.com>
date Wed, 08 Nov 2023 00:09:33 -0800
parents b865f33fd47e
children 8c060849a503
files debug.c debug.h
diffstat 2 files changed, 131 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/debug.c	Tue Nov 07 22:19:21 2023 -0800
+++ b/debug.c	Wed Nov 08 00:09:33 2023 -0800
@@ -187,6 +187,8 @@
 	"TOKEN_INT",
 	"TOKEN_DECIMAL",
 	"TOKEN_NAME",
+	"TOKEN_ARRAY",
+	"TOKEN_FUNCALL",
 	"TOKEN_OPER",
 	"TOKEN_SIZE",
 	"TOKEN_LBRACKET",
@@ -310,6 +312,10 @@
 		{
 		case '[':
 			type = TOKEN_ARRAY;
+			done = 1;
+			break;
+		case '(':
+			type = TOKEN_FUNCALL;
 		case '+':
 		case '-':
 		case '*':
@@ -324,7 +330,6 @@
 		case '<':
 		case '.':
 		case ']':
-		case '(':
 		case ')':
 			done = 1;
 			break;
@@ -346,16 +351,30 @@
 	};
 }
 
+static void free_expr(expr *e);
+static void free_expr_int(expr *e)
+{
+	free_expr(e->left);
+	if (e->type == EXPR_FUNCALL) {
+		for (uint32_t i = 0; i < e->op.v.num; i++)
+		{
+			free_expr_int(e->right + i);
+		}
+		free(e->right);
+	} else {
+		free_expr(e->right);
+	}
+	if (e->op.type == TOKEN_NAME) {
+		free(e->op.v.str);
+	}
+}
+
 static void free_expr(expr *e)
 {
 	if (!e) {
 		return;
 	}
-	free_expr(e->left);
-	free_expr(e->right);
-	if (e->op.type == TOKEN_NAME) {
-		free(e->op.v.str);
-	}
+	free_expr_int(e);
 	free(e);
 }
 
@@ -466,6 +485,39 @@
 		}
 		return ret;
 	}
+	if (first.type == TOKEN_FUNCALL) {
+		expr *ret = calloc(1, sizeof(expr));
+		ret->left = calloc(1, sizeof(expr));
+		ret->left->type = EXPR_SCALAR;
+		ret->left->op = first;
+		ret->left->op.type = TOKEN_NAME;
+		uint32_t storage = 0;
+		ret->op.v.num = 0;
+		token next = parse_token(after_first, end);
+		while (next.type != TOKEN_RPAREN && next.type != TOKEN_NONE)
+		{
+			expr *e = parse_expression(after_first, end);
+			if (!e) {
+				fprintf(stderr, "Expression expected after '('\n");
+				free_expr(ret);
+				return NULL;
+			}
+			if (storage == ret->op.v.num) {
+				storage = storage ? storage * 2 : 1;
+				ret->right = realloc(ret->right, storage * sizeof(expr));
+			}
+			ret->right[ret->op.v.num++] = *e;
+			free(e);
+			after_first = *end;
+			next = parse_token(after_first, end);
+		}
+		if (next.type != TOKEN_RPAREN) {
+			fprintf(stderr, "Missing ')' after '('\n");
+			free_expr(ret);
+			return NULL;
+		}
+		return ret;
+	}
 	if (first.type != TOKEN_INT && first.type != TOKEN_DECIMAL && first.type != TOKEN_NAME) {
 		fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]);
 		return NULL;
@@ -625,6 +677,39 @@
 		}
 		return maybe_muldiv(ret, *end, end);
 	}
+	if (first.type == TOKEN_FUNCALL) {
+		expr *ret = calloc(1, sizeof(expr));
+		ret->left = calloc(1, sizeof(expr));
+		ret->left->type = EXPR_SCALAR;
+		ret->left->op = first;
+		ret->left->op.type = TOKEN_NAME;
+		uint32_t storage = 0;
+		ret->op.v.num = 0;
+		token next = parse_token(after_first, end);
+		while (next.type != TOKEN_RPAREN && next.type != TOKEN_NONE)
+		{
+			expr *e = parse_expression(after_first, end);
+			if (!e) {
+				fprintf(stderr, "Expression expected after '('\n");
+				free_expr(ret);
+				return NULL;
+			}
+			if (storage == ret->op.v.num) {
+				storage = storage ? storage * 2 : 1;
+				ret->right = realloc(ret->right, storage * sizeof(expr));
+			}
+			ret->right[ret->op.v.num++] = *e;
+			free(e);
+			after_first = *end;
+			next = parse_token(after_first, end);
+		}
+		if (next.type != TOKEN_RPAREN) {
+			fprintf(stderr, "Missing ')' after '('\n");
+			free_expr(ret);
+			return NULL;
+		}
+		return maybe_muldiv(ret, *end, end);
+	}
 	if (first.type != TOKEN_INT && first.type != TOKEN_DECIMAL && first.type != TOKEN_NAME) {
 		fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]);
 		return NULL;
@@ -754,6 +839,43 @@
 		}
 		return maybe_binary(ret, *end, end);
 	}
+	if (first.type == TOKEN_FUNCALL) {
+		expr *ret = calloc(1, sizeof(expr));
+		ret->type = EXPR_FUNCALL;
+		ret->left = calloc(1, sizeof(expr));
+		ret->left->type = EXPR_SCALAR;
+		ret->left->op = first;
+		ret->left->op.type = TOKEN_NAME;
+		uint32_t storage = 0;
+		ret->op.v.num = 0;
+		//consume LPAREN
+		parse_token(after_first, end);
+		after_first = *end;
+		token next = parse_token(after_first, end);
+		while (next.type != TOKEN_RPAREN && next.type != TOKEN_NONE)
+		{
+			expr *e = parse_expression(after_first, end);
+			if (!e) {
+				fprintf(stderr, "Expression expected after '('\n");
+				free_expr(ret);
+				return NULL;
+			}
+			if (storage == ret->op.v.num) {
+				storage = storage ? storage * 2 : 1;
+				ret->right = realloc(ret->right, storage * sizeof(expr));
+			}
+			ret->right[ret->op.v.num++] = *e;
+			free(e);
+			after_first = *end;
+			next = parse_token(after_first, end);
+		}
+		if (next.type != TOKEN_RPAREN) {
+			fprintf(stderr, "Missing ')' after '('\n");
+			free_expr(ret);
+			return NULL;
+		}
+		return maybe_binary(ret, *end, end);
+	}
 	if (first.type != TOKEN_INT && first.type != TOKEN_DECIMAL && first.type != TOKEN_NAME) {
 		fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]);
 		return NULL;
--- a/debug.h	Tue Nov 07 22:19:21 2023 -0800
+++ b/debug.h	Wed Nov 08 00:09:33 2023 -0800
@@ -17,6 +17,7 @@
 	TOKEN_DECIMAL,
 	TOKEN_NAME,
 	TOKEN_ARRAY,
+	TOKEN_FUNCALL,
 	TOKEN_OPER,
 	TOKEN_SIZE,
 	TOKEN_LBRACKET,
@@ -42,7 +43,8 @@
 	EXPR_BINARY,
 	EXPR_SIZE,
 	EXPR_MEM,
-	EXPR_NAMESPACE
+	EXPR_NAMESPACE,
+	EXPR_FUNCALL
 } expr_type;
 
 typedef struct expr expr;