Changeset 269
- Timestamp:
- 11/28/09 23:58:23 (2 years ago)
- Files:
-
- trunk/src/expression.c (modified) (3 diffs)
- trunk/src/expression.h (modified) (1 diff)
- trunk/src/idgen.c (modified) (2 diffs)
- trunk/src/lexer.c (modified) (3 diffs)
- trunk/src/lexer.h (modified) (2 diffs)
- trunk/src/opover.c (modified) (2 diffs)
- trunk/src/parse.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/expression.c
r257 r269 124 124 precedence[TOKdiv] = PREC_mul; 125 125 precedence[TOKmod] = PREC_mul; 126 precedence[TOKpow] = PREC_mul; 126 127 127 128 precedence[TOKadd] = PREC_add; … … 183 184 precedence[TOKdivass] = PREC_assign; 184 185 precedence[TOKmodass] = PREC_assign; 186 //precedence[TOKpowass] = PREC_assign; 185 187 precedence[TOKshlass] = PREC_assign; 186 188 precedence[TOKshrass] = PREC_assign; … … 9772 9774 } 9773 9775 9776 PowExp::PowExp(Loc loc, Expression *e1, Expression *e2) 9777 : BinExp(loc, TOKpow, sizeof(PowExp), e1, e2) 9778 { 9779 } 9780 9781 Expression *PowExp::semantic(Scope *sc) 9782 { Expression *e; 9783 9784 if (type) 9785 return this; 9786 9787 BinExp::semanticp(sc); 9788 e = op_overload(sc); 9789 if (e) 9790 return e; 9791 9792 static int importMathChecked = 0; 9793 if (!importMathChecked) 9794 { 9795 importMathChecked = 1; 9796 for (int i = 0; i < Module::amodules.dim; i++) 9797 { Module *mi = (Module *)Module::amodules.data[i]; 9798 //printf("\t[%d] %s\n", i, mi->toChars()); 9799 if (mi->ident == Id::math && 9800 mi->parent->ident == Id::std && 9801 !mi->parent->parent) 9802 goto L1; 9803 } 9804 error("must import std.math to use ^^ operator"); 9805 9806 L1: ; 9807 } 9808 9809 assert(e1->type && e2->type); 9810 if ( (e1->type->isintegral() || e1->type->isfloating()) && 9811 (e2->type->isintegral() || e2->type->isfloating())) 9812 { 9813 // For built-in numeric types, there are three cases: 9814 // x ^^ 1 ----> x 9815 // x ^^ 0.5 ----> sqrt(x) 9816 // x ^^ y ----> pow(x, y) 9817 // TODO: backend support, especially for e1 ^^ 2. 9818 bool wantSqrt = false; 9819 e2 = e2->optimize(0); 9820 if ((e2->op == TOKfloat64 && e2->toReal() == 1.0) || 9821 (e2->op == TOKint64 && e2->toInteger() == 1)) 9822 { 9823 return e1; // Replace x ^^ 1 with x. 9824 } 9825 9826 e = new IdentifierExp(loc, Id::empty); 9827 e = new DotIdExp(loc, e, Id::std); 9828 e = new DotIdExp(loc, e, Id::math); 9829 if (e2->op == TOKfloat64 && e2->toReal() == 0.5) 9830 { // Replace e1 ^^ 0.5 with .std.math.sqrt(x) 9831 e = new CallExp(loc, new DotIdExp(loc, e, Id::_sqrt), e1); 9832 } 9833 else 9834 { // Replace e1 ^^ e2 with .std.math.pow(e1, e2) 9835 e = new CallExp(loc, new DotIdExp(loc, e, Id::_pow), e1, e2); 9836 } 9837 e = e->semantic(sc); 9838 return e; 9839 } 9840 error("%s ^^ %s is not supported", e1->type->toChars(), e2->type->toChars() ); 9841 return new ErrorExp(); 9842 } 9843 9774 9844 /************************************************************/ 9775 9845 trunk/src/expression.h
r254 r269 1299 1299 }; 1300 1300 1301 #if DMDV2 1302 struct PowExp : BinExp 1303 { 1304 PowExp(Loc loc, Expression *e1, Expression *e2); 1305 Expression *semantic(Scope *sc); 1306 1307 // For operator overloading 1308 Identifier *opId(); 1309 Identifier *opId_r(); 1310 }; 1311 #endif 1312 1301 1313 struct ShlExp : BinExp 1302 1314 { trunk/src/idgen.c
r268 r269 212 212 { "opDispatch" }, 213 213 { "opImplicitCast" }, 214 { "pow", "opPow" }, 215 { "pow_r", "opPow_r" }, 216 //{ "powass", "opPowAssign" }, 214 217 215 218 { "classNew", "new" }, … … 272 275 { "tan" }, 273 276 { "_sqrt", "sqrt" }, 277 { "_pow", "pow" }, 274 278 { "fabs" }, 275 279 trunk/src/lexer.c
r249 r269 1152 1152 return; 1153 1153 1154 #if DMDV2 1155 case '^': 1156 p++; 1157 if (*p == '^') 1158 { p++; 1159 #if 0 1160 if (*p == '=') 1161 { p++; 1162 t->value = TOKpowass; // ^^= 1163 } 1164 else 1165 #endif 1166 t->value = TOKpow; // ^^ 1167 } 1168 else if (*p == '=') 1169 { p++; 1170 t->value = TOKxorass; // ^= 1171 } 1172 else 1173 t->value = TOKxor; // ^ 1174 return; 1175 #endif 1176 1154 1177 #define SINGLE(c,tok) case c: p++; t->value = tok; return; 1155 1178 … … 1182 1205 DOUBLE('*', TOKmul, '=', TOKmulass) 1183 1206 DOUBLE('%', TOKmod, '=', TOKmodass) 1207 #if DMDV1 1184 1208 DOUBLE('^', TOKxor, '=', TOKxorass) 1185 1209 #endif 1186 1210 #undef DOUBLE 1187 1211 … … 3085 3109 Token::tochars[TOKidentifier] = "identifier"; 3086 3110 Token::tochars[TOKat] = "@"; 3111 Token::tochars[TOKpow] = "^^"; 3112 //Token::tochars[TOKpowass] = "^^="; 3087 3113 3088 3114 // For debugging trunk/src/lexer.h
r249 r269 33 33 & | ^ &= |= ^= 34 34 = ! ~ @ 35 ^^ ^^= 35 36 ++ -- 36 37 . -> : , … … 163 164 TOKshared, 164 165 TOKat, 166 TOKpow, 167 //TOKpowass, 165 168 #endif 166 169 trunk/src/opover.c
r253 r269 105 105 Identifier *ModExp::opId() { return Id::mod; } 106 106 Identifier *ModExp::opId_r() { return Id::mod_r; } 107 108 #if DMDV2 109 Identifier *PowExp::opId() { return Id::pow; } 110 Identifier *PowExp::opId_r() { return Id::pow_r; } 111 #endif 107 112 108 113 Identifier *ShlExp::opId() { return Id::shl; } … … 143 148 Identifier *UshrAssignExp::opId() { return Id::ushrass; } 144 149 Identifier * CatAssignExp::opId() { return Id::catass; } 150 //Identifier * PowAssignExp::opId() { return Id::powass; } 145 151 146 152 int EqualExp::isCommutative() { return TRUE; } trunk/src/parse.c
r257 r269 5603 5603 { 5604 5604 case TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue; 5605 case TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue; 5606 case TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue; 5605 case TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue; 5606 case TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue; 5607 case TOKpow: nextToken(); e2 = parseUnaryExp(); e = new PowExp(loc,e,e2); continue; 5607 5608 5608 5609 default: … … 5949 5950 X(TOKdivass, DivAssignExp); 5950 5951 X(TOKmodass, ModAssignExp); 5952 //X(TOKpowass, PowAssignExp); 5951 5953 X(TOKandass, AndAssignExp); 5952 5954 X(TOKorass, OrAssignExp);
