| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 void print(var obj) { | 5 void print(var obj) { |
| 6 obj = obj.toString(); | 6 obj = obj.toString(); |
| 7 var hasConsole = JS("bool", @"typeof console == 'object'"); | 7 var hasConsole = JS("bool", @"typeof console == 'object'"); |
| 8 if (hasConsole) { | 8 if (hasConsole) { |
| 9 JS("void", @"console.log($0)", obj); | 9 JS("void", @"console.log($0)", obj); |
| 10 } else { | 10 } else { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 return JS("num", @"$0 + $1", a, b); | 49 return JS("num", @"$0 + $1", a, b); |
| 50 } else if (JS("bool", @"typeof $0 === 'string'", a)) { | 50 } else if (JS("bool", @"typeof $0 === 'string'", a)) { |
| 51 b = b.toString(); | 51 b = b.toString(); |
| 52 if (JS("bool", @"typeof $0 === 'string'", b)) { | 52 if (JS("bool", @"typeof $0 === 'string'", b)) { |
| 53 return JS("String", @"$0 + $1", a, b); | 53 return JS("String", @"$0 + $1", a, b); |
| 54 } | 54 } |
| 55 // The following line is too long, but we can't break it using the + | 55 // The following line is too long, but we can't break it using the + |
| 56 // operator, since that's what we are defining here. | 56 // operator, since that's what we are defining here. |
| 57 throw "calling toString() on right hand operand of operator + did not return
a String"; | 57 throw "calling toString() on right hand operand of operator + did not return
a String"; |
| 58 } | 58 } |
| 59 throw "Unimplemented user-defined +."; | 59 return UNINTERCEPTED(a + b); |
| 60 } | 60 } |
| 61 | 61 |
| 62 div(var a, var b) { | 62 div(var a, var b) { |
| 63 if (checkNumbers(a, b, "num/ expects a number as second operand.")) { | 63 if (checkNumbers(a, b, "num/ expects a number as second operand.")) { |
| 64 return JS("num", @"$0 / $1", a, b); | 64 return JS("num", @"$0 / $1", a, b); |
| 65 } | 65 } |
| 66 throw "Unimplemented user-defined /."; | 66 return UNINTERCEPTED(a / b); |
| 67 } | 67 } |
| 68 | 68 |
| 69 mul(var a, var b) { | 69 mul(var a, var b) { |
| 70 if (checkNumbers(a, b, "num* expects a number as second operand.")) { | 70 if (checkNumbers(a, b, "num* expects a number as second operand.")) { |
| 71 return JS("num", @"$0 * $1", a, b); | 71 return JS("num", @"$0 * $1", a, b); |
| 72 } | 72 } |
| 73 throw "Unimplemented user-defined *."; | 73 return UNINTERCEPTED(a * b); |
| 74 } | 74 } |
| 75 | 75 |
| 76 sub(var a, var b) { | 76 sub(var a, var b) { |
| 77 if (checkNumbers(a, b, "num- expects a number as second operand.")) { | 77 if (checkNumbers(a, b, "num- expects a number as second operand.")) { |
| 78 return JS("num", @"$0 - $1", a, b); | 78 return JS("num", @"$0 - $1", a, b); |
| 79 } | 79 } |
| 80 throw "Unimplemented user-defined binary -."; | 80 return UNINTERCEPTED(a - b); |
| 81 } | 81 } |
| 82 | 82 |
| 83 mod(var a, var b) { | 83 mod(var a, var b) { |
| 84 if (checkNumbers(a, b, "int% expects an int as second operand.")) { | 84 if (checkNumbers(a, b, "int% expects an int as second operand.")) { |
| 85 // Euclidean Modulo. | 85 // Euclidean Modulo. |
| 86 int result = JS("num", @"$0 % $1", a, b); | 86 int result = JS("num", @"$0 % $1", a, b); |
| 87 if (result == 0) return 0; // Make sure we don't return -0.0. | 87 if (result == 0) return 0; // Make sure we don't return -0.0. |
| 88 if (result > 0) return result; | 88 if (result > 0) return result; |
| 89 if (b < 0) { | 89 if (b < 0) { |
| 90 return result - b; | 90 return result - b; |
| 91 } else { | 91 } else { |
| 92 return result + b; | 92 return result + b; |
| 93 } | 93 } |
| 94 } | 94 } |
| 95 throw "Unimplemented user-defined %."; | 95 return UNINTERCEPTED(a % b); |
| 96 } | 96 } |
| 97 | 97 |
| 98 tdiv(var a, var b) { | 98 tdiv(var a, var b) { |
| 99 if (checkNumbers(a, b, "num~/ expects a number as second operand.")) { | 99 if (checkNumbers(a, b, "num~/ expects a number as second operand.")) { |
| 100 var tmp = a / b; | 100 var tmp = a / b; |
| 101 // TODO(ngeoffray): Use tmp.floor and tmp.ceil when | 101 // TODO(ngeoffray): Use tmp.floor and tmp.ceil when |
| 102 // we can handle them. | 102 // we can handle them. |
| 103 if (tmp < 0) { | 103 if (tmp < 0) { |
| 104 return JS("num", @"Math.ceil($0)", tmp); | 104 return JS("num", @"Math.ceil($0)", tmp); |
| 105 } else { | 105 } else { |
| 106 return JS("num", @"Math.floor($0)", tmp); | 106 return JS("num", @"Math.floor($0)", tmp); |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 throw "Unimplemented user-defined ~/."; | 109 return UNINTERCEPTED(a ~/ b); |
| 110 } | 110 } |
| 111 | 111 |
| 112 eq(var a, var b) { | 112 eq(var a, var b) { |
| 113 if (JS("bool", @"typeof $0 === 'object'", a)) { | 113 if (JS("bool", @"typeof $0 === 'object'", a)) { |
| 114 if (JS("bool", @"$0.$equals", a)) { | 114 if (JS_HAS_EQUALS(a)) { |
| 115 return JS("bool", @"$0.$equals($1) === true", a, b); | 115 return UNINTERCEPTED(a == b) === true; |
| 116 } else { | 116 } else { |
| 117 return JS("bool", @"$0 === $1", a, b); | 117 return JS("bool", @"$0 === $1", a, b); |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 // TODO(lrn): is NaN === NaN ? Is -0.0 === 0.0 ? | 120 // TODO(lrn): is NaN === NaN ? Is -0.0 === 0.0 ? |
| 121 return JS("bool", @"$0 === $1", a, b); | 121 return JS("bool", @"$0 === $1", a, b); |
| 122 } | 122 } |
| 123 | 123 |
| 124 eqq(var a, var b) { | 124 eqq(var a, var b) { |
| 125 return JS("bool", @"$0 === $1", a, b); | 125 return JS("bool", @"$0 === $1", a, b); |
| 126 } | 126 } |
| 127 | 127 |
| 128 eqNull(var a) { | 128 eqNull(var a) { |
| 129 if (JS("bool", @"typeof $0 === 'object'", a)) { | 129 if (JS("bool", @"typeof $0 === 'object'", a)) { |
| 130 if (JS("bool", @"$0.$equals", a)) { | 130 if (JS_HAS_EQUALS(a)) { |
| 131 return JS("bool", @"$0.$equals(void 0) === true", a); | 131 return UNINTERCEPTED(a == null) === true; |
| 132 } else { | 132 } else { |
| 133 return false; | 133 return false; |
| 134 } | 134 } |
| 135 } else { | 135 } else { |
| 136 return JS("bool", @"typeof $0 === 'undefined'", a); | 136 return JS("bool", @"typeof $0 === 'undefined'", a); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 gt(var a, var b) { | 140 gt(var a, var b) { |
| 141 if (checkNumbers(a, b, "num> expects a number as second operand.")) { | 141 if (checkNumbers(a, b, "num> expects a number as second operand.")) { |
| 142 return JS("bool", @"$0 > $1", a, b); | 142 return JS("bool", @"$0 > $1", a, b); |
| 143 } | 143 } |
| 144 throw "Unimplemented user-defined binary >."; | 144 return UNINTERCEPTED(a > b); |
| 145 } | 145 } |
| 146 | 146 |
| 147 ge(var a, var b) { | 147 ge(var a, var b) { |
| 148 if (checkNumbers(a, b, "num>= expects a number as second operand.")) { | 148 if (checkNumbers(a, b, "num>= expects a number as second operand.")) { |
| 149 return JS("bool", @"$0 >= $1", a, b); | 149 return JS("bool", @"$0 >= $1", a, b); |
| 150 } | 150 } |
| 151 throw "Unimplemented user-defined binary >=."; | 151 return UNINTERCEPTED(a >= b); |
| 152 } | 152 } |
| 153 | 153 |
| 154 lt(var a, var b) { | 154 lt(var a, var b) { |
| 155 if (checkNumbers(a, b, "num< expects a number as second operand.")) { | 155 if (checkNumbers(a, b, "num< expects a number as second operand.")) { |
| 156 return JS("bool", @"$0 < $1", a, b); | 156 return JS("bool", @"$0 < $1", a, b); |
| 157 } | 157 } |
| 158 throw "Unimplemented user-defined binary <."; | 158 return UNINTERCEPTED(a < b); |
| 159 } | 159 } |
| 160 | 160 |
| 161 le(var a, var b) { | 161 le(var a, var b) { |
| 162 if (checkNumbers(a, b, "num<= expects a number as second operand.")) { | 162 if (checkNumbers(a, b, "num<= expects a number as second operand.")) { |
| 163 return JS("bool", @"$0 <= $1", a, b); | 163 return JS("bool", @"$0 <= $1", a, b); |
| 164 } | 164 } |
| 165 throw "Unimplemented user-defined binary <=."; | 165 return UNINTERCEPTED(a <= b); |
| 166 } | 166 } |
| 167 | 167 |
| 168 shl(var a, var b) { | 168 shl(var a, var b) { |
| 169 // TODO(floitsch): inputs must be integers. | 169 // TODO(floitsch): inputs must be integers. |
| 170 if (checkNumbers(a, b, "int<< expects an int as second operand.")) { | 170 if (checkNumbers(a, b, "int<< expects an int as second operand.")) { |
| 171 return JS("num", @"$0 << $1", a, b); | 171 return JS("num", @"$0 << $1", a, b); |
| 172 } | 172 } |
| 173 throw "Unimplemented user-defined binary <<."; | 173 return UNINTERCEPTED(a << b); |
| 174 } | 174 } |
| 175 | 175 |
| 176 shr(var a, var b) { | 176 shr(var a, var b) { |
| 177 // TODO(floitsch): inputs must be integers. | 177 // TODO(floitsch): inputs must be integers. |
| 178 if (checkNumbers(a, b, "int>> expects an int as second operand.")) { | 178 if (checkNumbers(a, b, "int>> expects an int as second operand.")) { |
| 179 return JS("num", @"$0 >> $1", a, b); | 179 return JS("num", @"$0 >> $1", a, b); |
| 180 } | 180 } |
| 181 throw "Unimplemented user-defined binary >>."; | 181 return UNINTERCEPTED(a >> b); |
| 182 } | 182 } |
| 183 | 183 |
| 184 and(var a, var b) { | 184 and(var a, var b) { |
| 185 // TODO(floitsch): inputs must be integers. | 185 // TODO(floitsch): inputs must be integers. |
| 186 if (checkNumbers(a, b, "int& expects an int as second operand.")) { | 186 if (checkNumbers(a, b, "int& expects an int as second operand.")) { |
| 187 return JS("num", @"$0 & $1", a, b); | 187 return JS("num", @"$0 & $1", a, b); |
| 188 } | 188 } |
| 189 throw "Unimplemented user-defined binary &."; | 189 return UNINTERCEPTED(a & b); |
| 190 } | 190 } |
| 191 | 191 |
| 192 or(var a, var b) { | 192 or(var a, var b) { |
| 193 // TODO(floitsch): inputs must be integers. | 193 // TODO(floitsch): inputs must be integers. |
| 194 if (checkNumbers(a, b, "int| expects an int as second operand.")) { | 194 if (checkNumbers(a, b, "int| expects an int as second operand.")) { |
| 195 return JS("num", @"$0 | $1", a, b); | 195 return JS("num", @"$0 | $1", a, b); |
| 196 } | 196 } |
| 197 throw "Unimplemented user-defined binary |."; | 197 return UNINTERCEPTED(a | b); |
| 198 } | 198 } |
| 199 | 199 |
| 200 xor(var a, var b) { | 200 xor(var a, var b) { |
| 201 // TODO(floitsch): inputs must be integers. | 201 // TODO(floitsch): inputs must be integers. |
| 202 if (checkNumbers(a, b, "int^ expects an int as second operand.")) { | 202 if (checkNumbers(a, b, "int^ expects an int as second operand.")) { |
| 203 return JS("num", @"$0 ^ $1", a, b); | 203 return JS("num", @"$0 ^ $1", a, b); |
| 204 } | 204 } |
| 205 throw "Unimplemented user-defined binary ^."; | 205 return UNINTERCEPTED(a ^ b); |
| 206 } | 206 } |
| 207 | 207 |
| 208 not(var a) { | 208 not(var a) { |
| 209 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"~$0", a); | 209 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"~$0", a); |
| 210 throw "Unimplemented user-defined ~."; | 210 return UNINTERCEPTED(~a); |
| 211 } | 211 } |
| 212 | 212 |
| 213 neg(var a) { | 213 neg(var a) { |
| 214 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"-$0", a); | 214 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"-$0", a); |
| 215 throw "Unimplemented user-defined unary-."; | 215 return UNINTERCEPTED(-a); |
| 216 } | 216 } |
| 217 | 217 |
| 218 index(var a, var index) { | 218 index(var a, var index) { |
| 219 if (JS("bool", @"typeof $0 === 'string'", a) || isJSArray(a)) { | 219 if (JS("bool", @"typeof $0 === 'string'", a) || isJSArray(a)) { |
| 220 if (!isInt(index)) $throw('Illegal argument'); | 220 if (!isInt(index)) $throw('Illegal argument'); |
| 221 if (index < 0 || index >= a.length) $throw('Out of bounds'); | 221 if (index < 0 || index >= a.length) $throw('Out of bounds'); |
| 222 return JS("Object", @"$0[$1]", a, index); | 222 return JS("Object", @"$0[$1]", a, index); |
| 223 } | 223 } |
| 224 throw "Unimplemented user-defined []."; | 224 return UNINTERCEPTED(a[index]); |
| 225 } | 225 } |
| 226 | 226 |
| 227 indexSet(var a, var index, var value) { | 227 indexSet(var a, var index, var value) { |
| 228 if (isJSArray(a)) { | 228 if (isJSArray(a)) { |
| 229 if (!isInt(index)) $throw('Illegal argument'); | 229 if (!isInt(index)) $throw('Illegal argument'); |
| 230 if (index < 0 || index >= a.length) $throw('Out of bounds'); | 230 if (index < 0 || index >= a.length) $throw('Out of bounds'); |
| 231 return JS("Object", @"$0[$1] = $2", a, index, value); | 231 return JS("Object", @"$0[$1] = $2", a, index, value); |
| 232 } | 232 } |
| 233 throw "Unimplemented user-defined []=."; | 233 return UNINTERCEPTED(a[index] = value); |
| 234 } | 234 } |
| 235 | 235 |
| 236 builtin$add$1(var receiver, var value) { | 236 builtin$add$1(var receiver, var value) { |
| 237 if (isJSArray(receiver)) { | 237 if (isJSArray(receiver)) { |
| 238 JS("Object", @"$0.push($1)", receiver, value); | 238 JS("Object", @"$0.push($1)", receiver, value); |
| 239 return; | 239 return; |
| 240 } | 240 } |
| 241 throw "Unimplemented user-defined add()."; | 241 return UNINTERCEPTED(receiver.add(value)); |
| 242 } | 242 } |
| 243 | 243 |
| 244 builtin$removeLast$0(var receiver) { | 244 builtin$removeLast$0(var receiver) { |
| 245 if (isJSArray(receiver)) { | 245 if (isJSArray(receiver)) { |
| 246 return JS("Object", @"$0.pop()", receiver); | 246 return JS("Object", @"$0.pop()", receiver); |
| 247 } | 247 } |
| 248 throw "Unimplemented user-defined removeLast()."; | 248 return UNINTERCEPTED(receiver.removeLast()); |
| 249 } | 249 } |
| 250 | 250 |
| 251 builtin$filter$1(var receiver, var predicate) { | 251 builtin$filter$1(var receiver, var predicate) { |
| 252 if (isJSArray(receiver)) { | 252 if (isJSArray(receiver)) { |
| 253 return JS("Object", @"$0.filter(function(v) { return $1(v) === true; })", | 253 return JS("Object", @"$0.filter(function(v) { return $1(v) === true; })", |
| 254 receiver, predicate); | 254 receiver, predicate); |
| 255 } | 255 } |
| 256 throw "Unimplemented user-defined filter()."; | 256 return UNINTERCEPTED(receiver.filter(predicate)); |
| 257 } | 257 } |
| 258 | 258 |
| 259 | 259 |
| 260 builtin$get$length(var receiver) { | 260 builtin$get$length(var receiver) { |
| 261 if (JS("bool", @"typeof $0 === 'string'", receiver) || isJSArray(receiver)) { | 261 if (JS("bool", @"typeof $0 === 'string'", receiver) || isJSArray(receiver)) { |
| 262 return JS("num", @"$0.length", receiver); | 262 return JS("num", @"$0.length", receiver); |
| 263 } | 263 } |
| 264 throw "Unimplemented user-defined length."; | 264 return UNINTERCEPTED(receiver.length); |
| 265 } | 265 } |
| 266 | 266 |
| 267 | 267 |
| 268 builtin$toString$0(var value) { | 268 builtin$toString$0(var value) { |
| 269 if (JS("bool", @"typeof $0 == 'object'", value)) { | 269 if (JS("bool", @"typeof $0 == 'object'", value)) { |
| 270 if (isJSArray(value)) { | 270 if (isJSArray(value)) { |
| 271 return "Instance of 'List'"; | 271 return "Instance of 'List'"; |
| 272 } | 272 } |
| 273 return UNINTERCEPTED(value.toString()); | 273 return UNINTERCEPTED(value.toString()); |
| 274 } | 274 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 ListIterator(List<T> this.list) : i = 0; | 370 ListIterator(List<T> this.list) : i = 0; |
| 371 bool hasNext() => i < JS("int", @"$0.length", list); | 371 bool hasNext() => i < JS("int", @"$0.length", list); |
| 372 T next() { | 372 T next() { |
| 373 var value = JS("Object", @"$0[$1]", list, i); | 373 var value = JS("Object", @"$0[$1]", list, i); |
| 374 i += 1; | 374 i += 1; |
| 375 return value; | 375 return value; |
| 376 } | 376 } |
| 377 } | 377 } |
| 378 | 378 |
| 379 class Expect { | 379 class Expect { |
| 380 // TODO(ngeoffray): add optional message parameters to these |
| 381 // methods. |
| 380 static void equals(var expected, var actual) { | 382 static void equals(var expected, var actual) { |
| 381 if (expected == actual) return; | 383 if (expected == actual) return; |
| 382 _fail('Expect.equals(expected: <$expected>, actual:<$actual> fails.'); | 384 _fail('Expect.equals(expected: <$expected>, actual:<$actual> fails.'); |
| 383 } | 385 } |
| 384 | 386 |
| 385 static void fail(String message) { | 387 static void fail(String message) { |
| 386 _fail("Expect.fail('$message')"); | 388 _fail("Expect.fail('$message')"); |
| 387 } | 389 } |
| 388 | 390 |
| 389 static void _fail(String message) { | 391 static void _fail(String message) { |
| 390 throw message; | 392 $throw(message); |
| 391 } | 393 } |
| 392 | 394 |
| 393 static void isTrue(var actual) { | 395 static void isTrue(var actual) { |
| 394 if (actual === true) return; | 396 if (actual === true) return; |
| 395 _fail("Expect.isTrue($actual) fails."); | 397 _fail("Expect.isTrue($actual) fails."); |
| 396 } | 398 } |
| 399 |
| 400 static void isFalse(var actual) { |
| 401 if (actual === false) return; |
| 402 _fail("Expect.isFalse($actual) fails."); |
| 403 } |
| 404 |
| 405 static void listEquals(List expected, List actual) { |
| 406 // We check on length at the end in order to provide better error |
| 407 // messages when an unexpected item is inserted in a list. |
| 408 if (expected.length != actual.length) { |
| 409 _fail('list not equals'); |
| 410 } |
| 411 |
| 412 for (int i = 0; i < expected.length; i++) { |
| 413 if (expected[i] != actual[i]) { |
| 414 _fail('list not equals'); |
| 415 } |
| 416 } |
| 417 } |
| 397 } | 418 } |
| 398 | 419 |
| 399 class Stopwatch { | 420 class Stopwatch { |
| 400 double startMs; | 421 double startMs; |
| 401 double elapsedMs; | 422 double elapsedMs; |
| 402 | 423 |
| 403 Stopwatch() { | 424 Stopwatch() { |
| 404 elapsedMs = 0.0; | 425 elapsedMs = 0.0; |
| 405 } | 426 } |
| 406 | 427 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 436 } else { | 457 } else { |
| 437 return | 458 return |
| 438 JS("num", @"Math.floor($0 + (Date.now() - $1))", elapsedMs, startMs); | 459 JS("num", @"Math.floor($0 + (Date.now() - $1))", elapsedMs, startMs); |
| 439 } | 460 } |
| 440 } | 461 } |
| 441 | 462 |
| 442 int frequency() { | 463 int frequency() { |
| 443 return 1000; | 464 return 1000; |
| 444 } | 465 } |
| 445 } | 466 } |
| OLD | NEW |