Mercurial > repos > blastem
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); |