comparison lwlib/lw_expr.c @ 366:433dbc18fb41

Make byte overflow detection for 8 bit immediate not fail with COM operator This is a horrible hack. Add a quick and dirty context to expression parsing so that it knows whether an 8 bit or 16 bit complement is required. The 8 bit complement will just discard anything above bit 7. When returning an operator back with lwasm_whichop(), the result will still be "COM" which should allow other things to keep working as they already do. This does prevent byte overflows when the complement operator is used, however, and since those were introduced, there were problems building Nitros9 among other things. This fix allows Nitros9 to build again.
author William Astle <lost@l-w.ca>
date Tue, 02 Jun 2015 20:58:14 -0600
parents 12e2453f8417
children 67373a053c49
comparison
equal deleted inserted replaced
365:3f8abaac214c 366:433dbc18fb41
37 /* Q&D to break out of infinite recursion */ 37 /* Q&D to break out of infinite recursion */
38 static int level = 0; 38 static int level = 0;
39 static int bailing = 0; 39 static int bailing = 0;
40 40
41 static void (*divzero)(void *priv) = NULL; 41 static void (*divzero)(void *priv) = NULL;
42
43 static int expr_width = 0;
44
45 void lw_expr_setwidth(int w)
46 {
47 expr_width = w;
48 }
42 49
43 void lw_expr_setdivzero(void (*fn)(void *priv)) 50 void lw_expr_setdivzero(void (*fn)(void *priv))
44 { 51 {
45 divzero = fn; 52 divzero = fn;
46 } 53 }
71 } 78 }
72 79
73 int lw_expr_whichop(lw_expr_t e) 80 int lw_expr_whichop(lw_expr_t e)
74 { 81 {
75 if (e -> type == lw_expr_type_oper) 82 if (e -> type == lw_expr_type_oper)
83 {
84 if (e -> value == lw_expr_oper_com8)
85 return lw_expr_oper_com;
76 return e -> value; 86 return e -> value;
87 }
77 return -1; 88 return -1;
78 } 89 }
79 90
80 int lw_expr_specint(lw_expr_t e) 91 int lw_expr_specint(lw_expr_t e)
81 { 92 {
200 break; 211 break;
201 212
202 case lw_expr_type_oper: 213 case lw_expr_type_oper:
203 t = va_arg(args, int); 214 t = va_arg(args, int);
204 te1 = va_arg(args, lw_expr_t); 215 te1 = va_arg(args, lw_expr_t);
205 if (t != lw_expr_oper_com && t != lw_expr_oper_neg) 216 if (t != lw_expr_oper_com && t != lw_expr_oper_neg && t != lw_expr_oper_com8)
206 te2 = va_arg(args, lw_expr_t); 217 te2 = va_arg(args, lw_expr_t);
207 else 218 else
208 te2 = NULL; 219 te2 = NULL;
209 220
210 r -> type = lw_expr_type_oper; 221 r -> type = lw_expr_type_oper;
318 strcat(buf, "NEG "); 329 strcat(buf, "NEG ");
319 break; 330 break;
320 331
321 case lw_expr_oper_com: 332 case lw_expr_oper_com:
322 strcat(buf, "COM "); 333 strcat(buf, "COM ");
334 break;
335
336 case lw_expr_oper_com8:
337 strcat(buf, "COM8 ");
323 break; 338 break;
324 339
325 default: 340 default:
326 strcat(buf, "OPER "); 341 strcat(buf, "OPER ");
327 break; 342 break;
711 tr = -(E -> operands -> p -> value); 726 tr = -(E -> operands -> p -> value);
712 break; 727 break;
713 728
714 case lw_expr_oper_com: 729 case lw_expr_oper_com:
715 tr = ~(E -> operands -> p -> value); 730 tr = ~(E -> operands -> p -> value);
731 break;
732
733 case lw_expr_oper_com8:
734 tr = ~(E -> operands -> p -> value) & 0xff;
716 break; 735 break;
717 736
718 case lw_expr_oper_plus: 737 case lw_expr_oper_plus:
719 tr = E -> operands -> p -> value; 738 tr = E -> operands -> p -> value;
720 for (o = E -> operands -> next; o; o = o -> next) 739 for (o = E -> operands -> next; o; o = o -> next)
1185 (*p)++; 1204 (*p)++;
1186 term = lw_expr_parse_expr(p, priv, 200); 1205 term = lw_expr_parse_expr(p, priv, 200);
1187 if (!term) 1206 if (!term)
1188 return NULL; 1207 return NULL;
1189 1208
1190 term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term); 1209 if (expr_width == 8)
1210 term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com8, term);
1211 else
1212 term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term);
1191 lw_expr_destroy(term); 1213 lw_expr_destroy(term);
1192 return term2; 1214 return term2;
1193 } 1215 }
1194 1216
1195 // non-operator - pass to caller 1217 // non-operator - pass to caller