comparison debug.c @ 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
comparison
equal deleted inserted replaced
2362:b6c5a0fa3dfc 2363:b865f33fd47e
170 ret.type = DBG_VAL_U32; 170 ret.type = DBG_VAL_U32;
171 ret.v.u32 = i; 171 ret.v.u32 = i;
172 return ret; 172 return ret;
173 } 173 }
174 174
175 static debug_val debug_float(float f)
176 {
177 return (debug_val) {
178 .type = DBG_VAL_F32,
179 .v = {
180 .f32 = f
181 }
182 };
183 }
184
175 static const char *token_type_names[] = { 185 static const char *token_type_names[] = {
176 "TOKEN_NONE", 186 "TOKEN_NONE",
177 "TOKEN_NUM", 187 "TOKEN_INT",
188 "TOKEN_DECIMAL",
178 "TOKEN_NAME", 189 "TOKEN_NAME",
179 "TOKEN_OPER", 190 "TOKEN_OPER",
180 "TOKEN_SIZE", 191 "TOKEN_SIZE",
181 "TOKEN_LBRACKET", 192 "TOKEN_LBRACKET",
182 "TOKEN_RBRACKET", 193 "TOKEN_RBRACKET",
196 }; 207 };
197 *end = start; 208 *end = start;
198 } 209 }
199 if (*start == '$' || (*start == '0' && start[1] == 'x')) { 210 if (*start == '$' || (*start == '0' && start[1] == 'x')) {
200 return (token) { 211 return (token) {
201 .type = TOKEN_NUM, 212 .type = TOKEN_INT,
202 .v = { 213 .v = {
203 .num = strtol(start + (*start == '$' ? 1 : 2), end, 16) 214 .num = strtol(start + (*start == '$' ? 1 : 2), end, 16)
204 } 215 }
205 }; 216 };
206 } 217 }
207 if (isdigit(*start)) { 218 if (isdigit(*start)) {
208 return (token) { 219 uint32_t ipart = strtol(start, end, 10);
209 .type = TOKEN_NUM, 220 if (**end == '.') {
210 .v = { 221 start = *end + 1;
211 .num = strtol(start, end, 10) 222 uint32_t fpart = strtol(start, end, 10);
212 } 223 float fval;
213 }; 224 if (fpart) {
225 float divisor = powf(10.0f, *end - start);
226 fval = ipart + fpart / divisor;
227 } else {
228 fval = ipart;
229 }
230 return (token) {
231 .type = TOKEN_DECIMAL,
232 .v = {
233 .f = fval
234 }
235 };
236 } else {
237 return (token) {
238 .type = TOKEN_INT,
239 .v = {
240 .num = ipart
241 }
242 };
243 }
214 } 244 }
215 switch (*start) 245 switch (*start)
216 { 246 {
217 case '+': 247 case '+':
218 case '-': 248 case '-':
434 free_expr(ret); 464 free_expr(ret);
435 return NULL; 465 return NULL;
436 } 466 }
437 return ret; 467 return ret;
438 } 468 }
439 if (first.type != TOKEN_NUM && first.type != TOKEN_NAME) { 469 if (first.type != TOKEN_INT && first.type != TOKEN_DECIMAL && first.type != TOKEN_NAME) {
440 fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]); 470 fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]);
441 return NULL; 471 return NULL;
442 } 472 }
443 token second = parse_token(after_first, end); 473 token second = parse_token(after_first, end);
444 if (second.type != TOKEN_SIZE) { 474 if (second.type != TOKEN_SIZE) {
593 free_expr(ret); 623 free_expr(ret);
594 return NULL; 624 return NULL;
595 } 625 }
596 return maybe_muldiv(ret, *end, end); 626 return maybe_muldiv(ret, *end, end);
597 } 627 }
598 if (first.type != TOKEN_NUM && first.type != TOKEN_NAME) { 628 if (first.type != TOKEN_INT && first.type != TOKEN_DECIMAL && first.type != TOKEN_NAME) {
599 fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]); 629 fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]);
600 return NULL; 630 return NULL;
601 } 631 }
602 char *after_second; 632 char *after_second;
603 token second = parse_token(after_first, &after_second); 633 token second = parse_token(after_first, &after_second);
722 free_expr(ret); 752 free_expr(ret);
723 return NULL; 753 return NULL;
724 } 754 }
725 return maybe_binary(ret, *end, end); 755 return maybe_binary(ret, *end, end);
726 } 756 }
727 if (first.type != TOKEN_NUM && first.type != TOKEN_NAME) { 757 if (first.type != TOKEN_INT && first.type != TOKEN_DECIMAL && first.type != TOKEN_NAME) {
728 fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]); 758 fprintf(stderr, "Unexpected token %s\n", token_type_names[first.type]);
729 return NULL; 759 return NULL;
730 } 760 }
731 char *after_second; 761 char *after_second;
732 token second = parse_token(after_first, &after_second); 762 token second = parse_token(after_first, &after_second);
811 if (!var) { 841 if (!var) {
812 return 0; 842 return 0;
813 } 843 }
814 *out = var->get(var); 844 *out = var->get(var);
815 return 1; 845 return 1;
846 } else if (e->op.type == TOKEN_INT) {
847 *out = debug_int(e->op.v.num);
848 return 1;
816 } else { 849 } else {
817 *out = debug_int(e->op.v.num); 850 *out = debug_float(e->op.v.f);
818 return 1; 851 return 1;
819 } 852 }
820 case EXPR_UNARY: 853 case EXPR_UNARY:
821 if (!eval_expr(root, e->left, out)) { 854 if (!eval_expr(root, e->left, out)) {
822 return 0; 855 return 0;
1085 return 1; 1118 return 1;
1086 } 1119 }
1087 return 0; 1120 return 0;
1088 } 1121 }
1089 1122
1123 static uint8_t debug_cast_float(debug_val val, float *out)
1124 {
1125 if (val.type == DBG_VAL_U32) {
1126 *out = val.v.u32;
1127 return 1;
1128 }
1129 if (val.type == DBG_VAL_F32) {
1130 *out = val.v.f32;
1131 return 1;
1132 }
1133 return 0;
1134 }
1135
1090 static uint8_t debug_cast_bool(debug_val val) 1136 static uint8_t debug_cast_bool(debug_val val)
1091 { 1137 {
1092 switch(val.type) 1138 switch(val.type)
1093 { 1139 {
1094 case DBG_VAL_U32: return val.v.u32 != 0; 1140 case DBG_VAL_U32: return val.v.u32 != 0;
2085 case 'x': 2131 case 'x':
2086 case 'X': 2132 case 'X':
2087 case 'c': 2133 case 'c':
2088 case 'd': 2134 case 'd':
2089 case 's': 2135 case 's':
2136 case 'f':
2090 break; 2137 break;
2091 default: 2138 default:
2092 fprintf(stderr, "Unsupported format character %c\n", cur[1]); 2139 fprintf(stderr, "Unsupported format character %c\n", cur[1]);
2093 free(fmt); 2140 free(fmt);
2094 return 1; 2141 return 1;
2127 tmp[j] = c; 2174 tmp[j] = c;
2128 } 2175 }
2129 tmp[j] = 0; 2176 tmp[j] = 0;
2130 printf(format_str, tmp); 2177 printf(format_str, tmp);
2131 } 2178 }
2179 } else if (cur[1] == 'f') {
2180 float fval;
2181 if (!debug_cast_float(val, &fval)) {
2182 fprintf(stderr, "Format char '%c' only accepts floats\n", cur[1]);
2183 free(fmt);
2184 return 1;
2185 }
2186 printf(format_str, fval);
2132 } else { 2187 } else {
2133 uint32_t ival; 2188 uint32_t ival;
2134 if (!debug_cast_int(val, &ival)) { 2189 if (!debug_cast_int(val, &ival)) {
2135 fprintf(stderr, "Format char '%c' only accepts integers\n", cur[1]); 2190 fprintf(stderr, "Format char '%c' only accepts integers\n", cur[1]);
2136 free(fmt); 2191 free(fmt);