• R/O
  • SSH
  • HTTPS

yash: 提交


Commit MetaInfo

修訂4191 (tree)
時間2022-08-14 23:53:38
作者magicant

Log Message

arith: Split calculation functions

Change Summary

差異

--- yash/branches/arith-error/arith.c (revision 4190)
+++ yash/branches/arith-error/arith.c (revision 4191)
@@ -99,8 +99,14 @@
9999 evalinfo_T *info, atokentype_T ttype,
100100 value_T *lhs, value_T *rhs, value_T *result)
101101 __attribute__((nonnull));
102-static long do_long_calculation1(atokentype_T ttype, long v1, long v2);
103-static long do_long_calculation2(atokentype_T ttype, long v1, long v2);
102+static bool do_long_calculation1(
103+ atokentype_T ttype, long v1, long v2, long *result)
104+ __attribute__((nonnull,warn_unused_result));
105+static bool do_long_calculation2(
106+ atokentype_T ttype, long v1, long v2, long *result)
107+ __attribute__((nonnull,warn_unused_result));
108+static long do_long_comparison(atokentype_T ttype, long v1, long v2)
109+ __attribute__((const,warn_unused_result));
104110 static double do_double_calculation(atokentype_T ttype, double v1, double v2);
105111 static long do_double_comparison(atokentype_T ttype, double v1, double v2);
106112 static void parse_conditional(evalinfo_T *info, value_T *result)
@@ -333,8 +339,12 @@
333339 return false;
334340 switch (result->type) {
335341 case VT_LONG:
336- result->v_long = do_long_calculation1(
337- ttype, lhs->v_long, rhs->v_long);
342+ if (!do_long_calculation1(ttype, lhs->v_long, rhs->v_long,
343+ &result->v_long)) {
344+ info->error = true;
345+ result->type = VT_INVALID;
346+ return false;
347+ }
338348 break;
339349 case VT_DOUBLE:
340350 result->v_double = do_double_calculation(
@@ -354,11 +364,17 @@
354364 coerce_integer(info, lhs);
355365 coerce_integer(info, rhs);
356366 if (lhs->type == VT_LONG && rhs->type == VT_LONG) {
357- result->type = VT_LONG;
358- result->v_long =
359- do_long_calculation2(ttype, lhs->v_long, rhs->v_long);
367+ if (do_long_calculation2(
368+ ttype, lhs->v_long, rhs->v_long, &result->v_long)) {
369+ result->type = VT_LONG;
370+ } else {
371+ info->error = true;
372+ result->type = VT_INVALID;
373+ return false;
374+ }
360375 } else {
361376 result->type = VT_INVALID;
377+ return false;
362378 }
363379 break;
364380 case TT_EQUAL:
@@ -370,35 +386,62 @@
370386 return true;
371387 }
372388
373-/* Does unary or binary long calculation according to the specified operator
374- * token. Division by zero is not allowed. */
375-long do_long_calculation1(atokentype_T ttype, long v1, long v2)
389+/* Applies binary operator `ttype' to the given operands `v1' and `v2'.
390+ * If successful, assigns the result to `*result' and returns true.
391+ * Otherwise, prints an error message and returns false. */
392+bool do_long_calculation1(atokentype_T ttype, long v1, long v2, long *result)
376393 {
377394 switch (ttype) {
378395 case TT_PLUS: case TT_PLUSEQUAL:
379- return v1 + v2;
396+ *result = v1 + v2;
397+ return true;
380398 case TT_MINUS: case TT_MINUSEQUAL:
381- return v1 - v2;
399+ *result = v1 - v2;
400+ return true;
382401 case TT_ASTER: case TT_ASTEREQUAL:
383- return v1 * v2;
402+ *result = v1 * v2;
403+ return true;
384404 case TT_SLASH: case TT_SLASHEQUAL:
385- return v1 / v2;
405+ *result = v1 / v2;
406+ return true;
386407 case TT_PERCENT: case TT_PERCENTEQUAL:
387- return v1 % v2;
408+ *result = v1 % v2;
409+ return true;
388410 default:
389411 assert(false);
390412 }
391413 }
392414
393-/* Does unary or binary long calculation according to the specified operator
394- * token. */
395-long do_long_calculation2(atokentype_T ttype, long v1, long v2)
415+/* Applies binary operator `ttype' to the given operands `v1' and `v2'.
416+ * If successful, assigns the result to `*result' and returns true.
417+ * Otherwise, prints an error message and returns false. */
418+bool do_long_calculation2(atokentype_T ttype, long v1, long v2, long *result)
396419 {
397420 switch (ttype) {
398421 case TT_LESSLESS: case TT_LESSLESSEQUAL:
399- return v1 << v2;
422+ *result = v1 << v2;
423+ return true;
400424 case TT_GREATERGREATER: case TT_GREATERGREATEREQUAL:
401- return v1 >> v2;
425+ *result = v1 >> v2;
426+ return true;
427+ case TT_AMP: case TT_AMPEQUAL:
428+ *result = v1 & v2;
429+ return true;
430+ case TT_HAT: case TT_HATEQUAL:
431+ *result = v1 ^ v2;
432+ return true;
433+ case TT_PIPE: case TT_PIPEEQUAL:
434+ *result = v1 | v2;
435+ return true;
436+ default:
437+ assert(false);
438+ }
439+}
440+
441+/* Applies binary operator `ttype' to the given operands `v1' and `v2'. */
442+long do_long_comparison(atokentype_T ttype, long v1, long v2)
443+{
444+ switch (ttype) {
402445 case TT_LESS:
403446 return v1 < v2;
404447 case TT_LESSEQUAL:
@@ -411,12 +454,6 @@
411454 return v1 == v2;
412455 case TT_EXCLEQUAL:
413456 return v1 != v2;
414- case TT_AMP: case TT_AMPEQUAL:
415- return v1 & v2;
416- case TT_HAT: case TT_HATEQUAL:
417- return v1 ^ v2;
418- case TT_PIPE: case TT_PIPEEQUAL:
419- return v1 | v2;
420457 default:
421458 assert(false);
422459 }
@@ -660,7 +697,7 @@
660697 parse_relational(info, &rhs);
661698 switch (coerce_type(info, result, &rhs)) {
662699 case VT_LONG:
663- result->v_long = do_long_calculation2(ttype,
700+ result->v_long = do_long_comparison(ttype,
664701 result->v_long, rhs.v_long);
665702 break;
666703 case VT_DOUBLE:
@@ -702,7 +739,7 @@
702739 parse_shift(info, &rhs);
703740 switch (coerce_type(info, result, &rhs)) {
704741 case VT_LONG:
705- result->v_long = do_long_calculation2(ttype,
742+ result->v_long = do_long_comparison(ttype,
706743 result->v_long, rhs.v_long);
707744 break;
708745 case VT_DOUBLE:
Show on old repository browser