comparison lwlib/lw_expr.c @ 249:1f1a28b797e1

Add trap for divide by zero in expression library Added a trap for division by zero in the expression library and adjusted lwasm to use it and report division by zero errors instead of crashing with a cryptic "arithmetic exception" or even more mysterious "floating point exception".
author William Astle <lost@l-w.ca>
date Fri, 25 Jan 2013 21:48:01 -0700
parents 348e2816ce32
children 644f8abf87dc
comparison
equal deleted inserted replaced
248:891bab942b5a 249:1f1a28b797e1
35 static lw_expr_fn3_t *parse_term = NULL; 35 static lw_expr_fn3_t *parse_term = NULL;
36 36
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
41 static void (*divzero)(void *priv) = NULL;
42
43 void lw_expr_setdivzero(void (*fn)(void *priv))
44 {
45 divzero = fn;
46 }
47
48 static void lw_expr_divzero(void *priv)
49 {
50 if (divzero)
51 (*divzero)(priv);
52 else
53 fprintf(stderr, "Divide by zero in lw_expr!\n");
54 }
40 55
41 int lw_expr_istype(lw_expr_t e, int t) 56 int lw_expr_istype(lw_expr_t e, int t)
42 { 57 {
43 /* NULL expression is never of any type */ 58 /* NULL expression is never of any type */
44 if (!e) 59 if (!e)
717 for (o = E -> operands -> next; o; o = o -> next) 732 for (o = E -> operands -> next; o; o = o -> next)
718 tr *= o -> p -> value; 733 tr *= o -> p -> value;
719 break; 734 break;
720 735
721 case lw_expr_oper_divide: 736 case lw_expr_oper_divide:
737 if (E -> operands -> next -> p -> value == 0)
738 {
739 tr = 0;
740 lw_expr_divzero(priv);
741 break;
742 }
722 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; 743 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value;
723 break; 744 break;
724 745
725 case lw_expr_oper_mod: 746 case lw_expr_oper_mod:
726 tr = E -> operands -> p -> value % E -> operands -> next -> p -> value; 747 tr = E -> operands -> p -> value % E -> operands -> next -> p -> value;
727 break; 748 break;
728 749
729 case lw_expr_oper_intdiv: 750 case lw_expr_oper_intdiv:
751 if (E -> operands -> next -> p -> value == 0)
752 {
753 tr = 0;
754 lw_expr_divzero(priv);
755 break;
756 }
730 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; 757 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value;
731 break; 758 break;
732 759
733 case lw_expr_oper_bwand: 760 case lw_expr_oper_bwand:
734 tr = E -> operands -> p -> value & E -> operands -> next -> p -> value; 761 tr = E -> operands -> p -> value & E -> operands -> next -> p -> value;