changeset 2363:b865f33fd47e

Basic float support in debug language
author Michael Pavone <pavone@retrodev.com>
date Tue, 07 Nov 2023 22:19:21 -0800
parents b6c5a0fa3dfc
children c822bb628fc3
files debug.c debug.h
diffstat 2 files changed, 69 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/debug.c	Mon Nov 06 22:41:33 2023 -0800
+++ b/debug.c	Tue Nov 07 22:19:21 2023 -0800
@@ -172,9 +172,20 @@
 	return ret;
 }
 
+static debug_val debug_float(float f)
+{
+	return (debug_val) {
+		.type = DBG_VAL_F32,
+		.v = {
+			.f32 = f
+		}
+	};
+}
+
 static const char *token_type_names[] = {
 	"TOKEN_NONE",
-	"TOKEN_NUM",
+	"TOKEN_INT",
+	"TOKEN_DECIMAL",
 	"TOKEN_NAME",
 	"TOKEN_OPER",
 	"TOKEN_SIZE",
@@ -198,19 +209,38 @@
 	}
 	if (*start == '$' || (*start == '0' && start[1] == 'x')) {
 		return (token) {
-			.type = TOKEN_NUM,
+			.type = TOKEN_INT,
 			.v = {
 				.num = strtol(start + (*start == '$' ? 1 : 2), end, 16)
 			}
 		};
 	}
 	if (isdigit(*start)) {
-		return (token) {
-			.type = TOKEN_NUM,
-			.v = {
-				.num = strtol(start, end, 10)
+		uint32_t ipart = strtol(start, end, 10);
+		if (**end == '.') {
+			start = *end + 1;
+			uint32_t fpart = strtol(start, end, 10);
+			float fval;
+			if (fpart) {
+				float divisor = powf(10.0f, *end - start);
+				fval = ipart + fpart / divisor;
+			} else {
+				fval = ipart;
 			}
-		};
+			return (token) {
+				.type = TOKEN_DECIMAL,
+				.v = {
+					.f = fval
+				}
+			};
+		} else {
+			return (token) {
+				.type = TOKEN_INT,
+				.v = {
+					.num = ipart
+				}
+			};
+		}
 	}
 	switch (*start)
 	{
@@ -436,7 +466,7 @@
 		}
 		return ret;
 	}
-	if (first.type != TOKEN_NUM && first.type != TOKEN_NAME) {
+	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;
 	}
@@ -595,7 +625,7 @@
 		}
 		return maybe_muldiv(ret, *end, end);
 	}
-	if (first.type != TOKEN_NUM && first.type != TOKEN_NAME) {
+	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;
 	}
@@ -724,7 +754,7 @@
 		}
 		return maybe_binary(ret, *end, end);
 	}
-	if (first.type != TOKEN_NUM && first.type != TOKEN_NAME) {
+	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;
 	}
@@ -813,8 +843,11 @@
 			}
 			*out = var->get(var);
 			return 1;
+		} else if (e->op.type == TOKEN_INT) {
+			*out = debug_int(e->op.v.num);
+			return 1;
 		} else {
-			*out = debug_int(e->op.v.num);
+			*out = debug_float(e->op.v.f);
 			return 1;
 		}
 	case EXPR_UNARY:
@@ -1087,6 +1120,19 @@
 	return 0;
 }
 
+static uint8_t debug_cast_float(debug_val val, float *out)
+{
+	if (val.type == DBG_VAL_U32) {
+		*out = val.v.u32;
+		return 1;
+	}
+	if (val.type == DBG_VAL_F32) {
+		*out = val.v.f32;
+		return 1;
+	}
+	return 0;
+}
+
 static uint8_t debug_cast_bool(debug_val val)
 {
 	switch(val.type)
@@ -2087,6 +2133,7 @@
 			case 'c':
 			case 'd':
 			case 's':
+			case 'f':
 				break;
 			default:
 				fprintf(stderr, "Unsupported format character %c\n", cur[1]);
@@ -2129,6 +2176,14 @@
 					tmp[j] = 0;
 					printf(format_str, tmp);
 				}
+			} else if (cur[1] == 'f') {
+				float fval;
+				if (!debug_cast_float(val, &fval)) {
+					fprintf(stderr, "Format char '%c' only accepts floats\n", cur[1]);
+					free(fmt);
+					return 1;
+				}
+				printf(format_str, fval);
 			} else {
 				uint32_t ival;
 				if (!debug_cast_int(val, &ival)) {
--- a/debug.h	Mon Nov 06 22:41:33 2023 -0800
+++ b/debug.h	Tue Nov 07 22:19:21 2023 -0800
@@ -13,7 +13,8 @@
 
 typedef enum {
 	TOKEN_NONE,
-	TOKEN_NUM,
+	TOKEN_INT,
+	TOKEN_DECIMAL,
 	TOKEN_NAME,
 	TOKEN_ARRAY,
 	TOKEN_OPER,
@@ -30,6 +31,7 @@
 		char     *str;
 		char     op[3];
 		uint32_t num;
+		float    f;
 	} v;
 } token;