Changeset 163

Show
Ignore:
Timestamp:
12/17/07 03:32:00 (10 months ago)
Author:
Don Clugston
Message:

Folding of unary minus -- it gets eliminated in the majority of cases.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/blade/Blade.d

    r162 r163  
    149149            } 
    150150            // TODO: disallow asm if any non-int/not FP types are used. 
    151             continue; // BUG: assume asm can always do scalars 
     151            continue; 
    152152        } 
    153153        if (r>'1') return VecExpressionType.DExpression; // can only do scalars and vectors right now. 
  • trunk/blade/BladeSimplify.d

    r162 r163  
    1414*      be moved to every vector inside A. 
    1515*    - Use associativity of *: A*(B*C[]) == (A*B)*C[] 
    16 *    - Use * distributive law over + and -. (Not strictly correct). 
    1716* (D) Expression standardisation  
    1817*    - Move multiplies to left: Convert A[]*B into B*A[] (assumes * is commutative, 
     
    421420{ 
    422421    char [] expr;       // vector or matrix expression; empty for a pure scalar expression 
    423     char [] multiplier; // scalar multiply of the entire expression 
     422    char [] multiplier; // scalar multiply of the entire expression. or "-" for unary minus 
    424423} 
    425424 
     
    438437            ScalarFold left = doVisit(this_,args[0]); 
    439438            ScalarFold right = doVisit(this_, args[1]); 
    440             char [] s = left.multiplier; 
    441             if (s.length>0 && right.multiplier.length>0) s~= "*"  ~ right.multiplier; 
    442             if (s.length>0) s ~="*"; 
    443439            return ScalarFold("", combineMul(combineMul(left.multiplier, right.multiplier), func ~ "(" ~ left.expr ~ "," ~ right.expr ~ ")")); 
    444440        } else { 
     
    451447            // Fold unary minus into a multiply, if possible. 
    452448            ScalarFold left = doVisit(this_, expr); 
    453             if (left.multiplier!="") return ScalarFold(left.expr, "-" ~ wrapInParens(left.multiplier)); 
    454             else return ScalarFold("-" ~ wrapInParens(left.expr), left.multiplier); 
     449            if (left.multiplier=="-") return ScalarFold(left.expr, ""); 
     450            else if (left.multiplier!="") return ScalarFold(left.expr, "-" ~ wrapInParens(left.multiplier)); 
     451            else return ScalarFold(left.expr, "-"); 
    455452        } else if (op=="+") { // just ignore unary plus 
    456453            return doVisit(this_, expr);         
     
    485482        if (op=="*=") { 
    486483            assert(first.multiplier=="" && second.expr=="", "BLADE ICE"); 
     484            assert(second.multiplier!="-", "BLADE ICE"); // this would be a*=-b, where b is a vector 
    487485            if (second.multiplier.length>1)  return ScalarFold(wrapInParens(first.expr) ~ op ~ " {" ~ wrapInParens(second.multiplier) ~ "} ","");  
    488486            else return ScalarFold(wrapInParens(first.expr) ~ op ~ wrapInParens(second.multiplier),"");  
     
    492490        } 
    493491        if (first.expr=="" && second.expr=="") { // both are 100% scalars -- it remains a scalar. 
     492            // Note: neither can be a unary minus. 
    494493            return ScalarFold("", 
    495494            wrapInParens(combineMul(first.expr, first.multiplier)) ~ op ~ 
    496495            wrapInParens(combineMul(second.expr, second.multiplier))); 
    497496        } 
     497        // BUG: Should also do +=, -=. 
     498        if (op=="-" && second.multiplier=="-") { 
     499            if (first.multiplier=="-") { 
     500                // convert (-a)-(-b) into b-a 
     501                return ScalarFold(wrapInParens(second.expr) ~ "-" ~ 
     502                wrapInParens(first.expr), ""); 
     503            } 
     504            // convert a-(-b) into a+b 
     505            return ScalarFold(wrapInParens(combineMulWithCompound(first.expr, first.multiplier)) ~ "+" ~ 
     506            wrapInParens(second.expr), ""); 
     507        } 
     508        if (op=="+" && second.multiplier=="-") { 
     509            // convert a+(-b) into a-b 
     510            return ScalarFold(wrapInParens(combineMulWithCompound(first.expr, first.multiplier)) ~ "-" ~ 
     511            wrapInParens(second.expr), ""); 
     512        } 
     513        if (op=="+" && first.multiplier=="-") { 
     514            // convert (-a)+b into b-a 
     515            return ScalarFold(wrapInParens(combineMulWithCompound(second.expr, second.multiplier)) ~ "-" ~ 
     516            wrapInParens(first.expr), ""); 
     517        } 
     518        if (op=="-" && second.multiplier!="") { 
     519            // convert a-b into a+(-b) where possible. 
     520            return ScalarFold(wrapInParens(combineMulWithCompound(first.expr, first.multiplier)) ~ "+" ~ 
     521            wrapInParens(combineMulWithCompound(second.expr, "-" ~ wrapInParens(second.multiplier))), ""); 
     522        } 
    498523        return ScalarFold(wrapInParens(combineMulWithCompound(first.expr, first.multiplier)) ~ op ~ 
    499524            wrapInParens(combineMulWithCompound(second.expr, second.multiplier)), ""); 
     
    505530    if (left.length==0) return right; 
    506531    if (right.length==0) return left; 
     532    if (left=="-" && right=="-") return ""; 
     533    if (left=="-") return "-" ~ wrapInParens(right); 
     534    if (right=="-") return "-" ~ wrapInParens(left); 
    507535    return wrapInParens(left) ~ "*" ~ wrapInParens(right); 
    508536} 
     
    513541    assert(left.length>0); 
    514542    if (right.length==0) return left; 
     543    if (right=="-") return "-" ~ wrapInParens(left);     
    515544    if (right.length==1) return wrapInParens(left) ~ "*" ~ right; 
    516545    return wrapInParens(left) ~ "* {" ~ wrapInParens(right) ~ "} ";     
     
    528557    assert(foldScalars("A*=(B*C)", "100")== "A*= {(B*C)} "); 
    529558    assert(foldScalars("d(A,(A*d(A,A)))", "1")==" {(d(A,A))*(d(A,A))} "); 
    530 
     559    assert(foldScalars("A-(B*C)", "101")=="A+(C* {(-B)} )"); 
     560    assert(foldScalars("A-(B*(-C))", "101")=="A+(C* {(-(-B))} )"); 
     561    assert(foldScalars("A+(-C)", "101")=="A-C"); 
     562    assert(foldScalars("A-(-C)", "101")=="A+C"); 
     563    assert(foldScalars("(-A)-(-C)", "101")=="C-A"); 
     564    assert(foldScalars("A*=-(-B)", "10")=="A*= {(-(-B))} "); 
     565