Fixed problem with the IN operator
authorceriel <none@none>
Fri, 19 Nov 1993 09:53:47 +0000 (09:53 +0000)
committerceriel <none@none>
Fri, 19 Nov 1993 09:53:47 +0000 (09:53 +0000)
lang/m2/comp/casestat.C
lang/m2/comp/code.c
lang/m2/comp/walk.c
lang/m2/comp/walk.h

index 8cf73a0..5d0cbaa 100644 (file)
@@ -201,7 +201,7 @@ CaseCode(nd, exitlabel, end_reached)
                                rval |= LblWalkNode((label) pnode->nd_LEFT->nd_lab,
                                            pnode->nd_LEFT->nd_RIGHT,
                                            exitlabel, end_reached);
-                               C_bra(sh->sh_break);
+                               c_bra(sh->sh_break);
                        }
                }
                else {
@@ -313,7 +313,7 @@ AddOneCase(sh, lnode, rnode, lbl)
                        C_zgt(cont);
                }
                C_asp(int_size);
-               C_bra(lbl);
+               c_bra(lbl);
                C_df_ilb(cont);
                ce->ce_label = 0;
        }
index c360106..5e6128d 100644 (file)
@@ -164,7 +164,7 @@ CodeExpr(nd, ds, true_label, false_label)
                */
                CodeValue(ds, tp);
                C_zne(true_label);
-               C_bra(false_label);
+               c_bra(false_label);
        }
 }
 
@@ -911,7 +911,7 @@ CodeOper(expr, true_label, false_label)
                }
                if (true_label != NO_LABEL)     {
                        compare(expr->nd_symb, true_label);
-                       C_bra(false_label);
+                       c_bra(false_label);
                        break;
                }
                truthvalue(expr->nd_symb);
@@ -923,30 +923,56 @@ CodeOper(expr, true_label, false_label)
                   INN instruction expects the bit number on top of the
                   stack
                */
-               label l_toolarge = NO_LABEL;
-
-               CodePExpr(rightop);
-               CodePExpr(leftop);
-               C_loc(rightop->nd_type->set_low);
-               C_sbu(word_size);
-               if (needs_rangecheck(ElementType(rightop->nd_type), leftop->nd_type)) {
-                       l_toolarge = ++text_label;
-                       C_dup(word_size);
-                       C_loc(rightop->nd_type->tp_size*8);
-                       C_cmu(word_size);
-                       C_zge(l_toolarge);
+               label l_toolarge = NO_LABEL, l_cont = NO_LABEL;
+               t_type *ltp = leftop->nd_type;
+
+               if (leftop->nd_symb == COERCION) {
+                       /* Could be coercion to word_type. */
+                       ltp = leftop->nd_RIGHT->nd_type;
+               }
+               if (leftop->nd_class == Value) {
+                       if (! in_range(leftop->nd_INT, ElementType(rightop->nd_type))) {
+                               if (true_label != NO_LABEL) {
+                                       c_bra(false_label);
+                               }
+                               else    c_loc(0);
+                               break;
+                       }
+                       CodePExpr(rightop);
+                       C_loc(rightop->nd_type->set_low-leftop->nd_INT);
+               }
+               else {
+                       CodePExpr(rightop);
+                       CodePExpr(leftop);
+                       C_loc(rightop->nd_type->set_low);
+                       C_sbu(word_size);
+                       if (needs_rangecheck(ElementType(rightop->nd_type), ltp)) {
+                               l_toolarge = ++text_label;
+                               C_dup(word_size);
+                               C_loc(rightop->nd_type->tp_size*8);
+                               C_cmu(word_size);
+                               C_zge(l_toolarge);
+                       }
                }
                C_inn(rightop->nd_type->tp_size);
                if (true_label != NO_LABEL) {
                        C_zne(true_label);
-                       C_bra(false_label);
+                       c_bra(false_label);
+               }
+               else {
+                       l_cont =  ++text_label;
+                       c_bra(l_cont);
                }
                if (l_toolarge != NO_LABEL) {
+                       def_ilb(l_toolarge);
                        C_asp(word_size+rightop->nd_type->tp_size);
                        if (true_label != NO_LABEL) {
-                               C_bra(false_label);
+                               c_bra(false_label);
                        }
-                       c_loc(0);
+                       else    c_loc(0);
+               }
+               if (l_cont != NO_LABEL) {
+                       def_ilb(l_cont);
                }
                break;
                }
@@ -973,7 +999,7 @@ CodeOper(expr, true_label, false_label)
                if (l_end != NO_LABEL) {
                        def_ilb(true_label);
                        c_loc(1);
-                       C_bra(l_end);
+                       c_bra(l_end);
                        def_ilb(false_label);
                        c_loc(0);
                        def_ilb(l_end);
@@ -1107,7 +1133,7 @@ CodeEl(nd, tp, null_set)
                if (eltype->tp_fund == T_SUBRANGE) {
                        C_loc(eltype->sub_ub);
                }
-               else    C_loc((arith) (eltype->enm_ncst - 1));
+               else    C_loc(eltype->enm_ncst - 1);
                Operands(nd);
                CAL("LtoUset", 5 * (int) word_size);
                /* library routine to fill set */
@@ -1201,6 +1227,12 @@ DoHIGH(df)
 }
 
 #ifdef SQUEEZE
+c_bra(l)
+       label l;
+{
+       C_bra((label) l);
+}
+
 c_loc(n)
 {
        C_loc((arith) n);
index cdf468d..4b2d1d3 100644 (file)
@@ -384,7 +384,7 @@ WalkProcedure(procedure)
 #else
        cd_init = ++text_label;
        cd_body = ++text_label;
-       C_bra(cd_init);
+       c_bra(cd_init);
        def_ilb(cd_body);
 #endif
 
@@ -399,7 +399,7 @@ WalkProcedure(procedure)
                        C_asp(-func_res_size);
                }
 #ifndef USE_INSERT
-               C_bra(RETURN_LABEL);
+               c_bra(RETURN_LABEL);
 #endif
        }
 
@@ -458,7 +458,7 @@ WalkProcedure(procedure)
 #ifdef USE_INSERT
        C_endpart(partno);
 #else
-       C_bra(cd_body);
+       c_bra(cd_body);
 #endif
        DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
        def_ilb(RETURN_LABEL);  /* label at end */
@@ -660,7 +660,7 @@ WalkStat(nd, exit_label, end_reached)
                        if (right->nd_RIGHT) {  /* ELSE part */
                                label l2 = ++text_label;
 
-                               C_bra(l2);
+                               c_bra(l2);
                                end_reached = end_r | LblWalkNode(l1, right->nd_RIGHT, exit_label, end_reached);
                                l1 = l2;
                        }
@@ -678,7 +678,7 @@ WalkStat(nd, exit_label, end_reached)
                                exit = ++text_label,
                                dummy = ++text_label;
 
-                       C_bra(dummy);
+                       c_bra(dummy);
                        end_reached |= LblWalkNode(loop, right, exit_label, end_reached);
                        def_ilb(dummy);
                        ExpectBool(&(nd->nd_LEFT), loop, exit);
@@ -702,7 +702,7 @@ WalkStat(nd, exit_label, end_reached)
                                end_reached &= REACH_FLAG;
                        }
                        else    end_reached = 0;
-                       C_bra(loop);
+                       c_bra(loop);
                        def_ilb(exit);
                        break;
                }
@@ -794,7 +794,7 @@ WalkStat(nd, exit_label, end_reached)
                                end_reached |= WalkNode(right->nd_RIGHT, exit_label, end_reached);
                                loopid->nd_def->df_flags &= ~D_FORLOOP;
                        }
-                       C_bra(l1);
+                       c_bra(l1);
                        def_ilb(l2);
                        FreeInt(tmp);
                }
@@ -842,7 +842,7 @@ WalkStat(nd, exit_label, end_reached)
                assert(exit_label != 0);
 
                if (end_reached & REACH_FLAG) end_reached = EXIT_FLAG;
-               C_bra(exit_label);
+               c_bra(exit_label);
                break;
 
        case RETURN:
@@ -862,7 +862,7 @@ WalkStat(nd, exit_label, end_reached)
                        }
                        else    CodePExpr(right);
                }
-               C_bra(RETURN_LABEL);
+               c_bra(RETURN_LABEL);
                break;
 
        default:
index 0aa7e75..80f978e 100644 (file)
@@ -25,4 +25,5 @@ extern label  data_label;
 #define c_loc(x)       C_loc((arith) (x))
 #define c_lae_dlb(x)   C_lae_dlb(x,(arith) 0)
 #define CAL(nm, sz)    (C_cal(nm), C_asp((arith)(sz)))
+#define c_bra(x)       C_bra((label) (x))
 #endif