Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(683)

Side by Side Diff: frog/lib/corelib_impl.dart

Issue 10548047: Remove frog from the repository. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Move test and update apidoc.gyp. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/lib/corelib.dart ('k') | frog/lib/date_implementation.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 #library("dart:coreimpl");
6
7 #source("../../corelib/src/implementation/dual_pivot_quicksort.dart");
8 #source("../../corelib/src/implementation/duration_implementation.dart");
9 #source("../../corelib/src/implementation/exceptions.dart");
10 #source("../../corelib/src/implementation/collections.dart");
11 #source("../../corelib/src/implementation/future_implementation.dart");
12 #source("../../corelib/src/implementation/hash_map_set.dart");
13 // TODO(jimhug): Re-explore tradeoffs with using builtin JS maps.
14 #source("../../corelib/src/implementation/linked_hash_map.dart");
15 #source("../../corelib/src/implementation/maps.dart");
16 #source("../../corelib/src/implementation/options.dart");
17 #source("../../corelib/src/implementation/queue.dart");
18 #source("../../corelib/src/implementation/stopwatch_implementation.dart");
19 #source("../../corelib/src/implementation/splay_tree.dart");
20
21 #source("string_buffer.dart");
22 #source("string_base.dart");
23 #source("string_implementation.dart");
24 #source("arrays.dart");
25 #source("date_implementation.dart");
26
27 #source("function_implementation.dart");
28
29 /**
30 * The default implementation of the [List<E>] interface. Essentially a growable
31 * array that will expand automatically as more elements are added.
32 */
33 class ListFactory<E> implements List<E> native "Array" {
34 ListFactory([int length]) native;
35
36 // TODO(jmesserly): type parameters aren't working here
37 factory ListFactory.from(Iterable other) {
38 final list = [];
39 for (final e in other) {
40 list.add(e);
41 }
42 return list;
43 }
44
45 // TODO(jimhug): Only works for Arrays.
46 factory ListFactory.fromList(List other, int startIndex, int endIndex)
47 native 'return other.slice(startIndex, endIndex);';
48
49 int length; // all fields on natives are implied native.
50
51 // List<E> members:
52 E operator [](int index) native;
53 void operator []=(int index, E value) native;
54 void add(E value) native "this.push(value);";
55 void addLast(E value) native "this.push(value);";
56 void addAll(Collection<E> collection) {
57 for (E item in collection) add(item);
58 }
59 void sort(int compare(E a, E b)) native;
60 void copyFrom(List<Object> src, int srcStart, int dstStart, int count) native;
61 int indexOf(E element, [int start]) native;
62 int lastIndexOf(E element, [int start]) native;
63 void clear() { length = 0; }
64
65 E removeLast() native "return this.pop();";
66
67 E last() => this[this.length-1];
68
69 ListFactory<E> getRange(int start, int rangeLength) {
70 if (rangeLength == 0) return [];
71 if (rangeLength < 0) throw new IllegalArgumentException('length');
72 if (start < 0 || start + rangeLength > this.length)
73 throw new IndexOutOfRangeException(start);
74 return this._slice(start, start + rangeLength);
75 }
76
77 void setRange(int start, int rangeLength, List<E> from, [int startFrom = 0]) {
78 // length of 0 prevails and should not throw exceptions.
79 if (rangeLength == 0) return;
80 if (rangeLength < 0) {
81 throw new IllegalArgumentException('length is negative');
82 }
83
84 if (start < 0) throw new IndexOutOfRangeException(start);
85
86 int end = start + rangeLength;
87 if (end > this.length) throw new IndexOutOfRangeException(end);
88
89 if (startFrom < 0) throw new IndexOutOfRangeException(startFrom);
90
91 int endFrom = startFrom + rangeLength;
92 if (endFrom > from.length) throw new IndexOutOfRangeException(endFrom);
93
94 for (var i = 0; i < rangeLength; ++i)
95 this[start + i] = from[startFrom + i];
96 }
97
98 void removeRange(int start, int rangeLength) {
99 if (rangeLength == 0) return;
100 if (rangeLength < 0) throw new IllegalArgumentException('length');
101 if (start < 0 || start + rangeLength > this.length)
102 throw new IndexOutOfRangeException(start);
103 this._splice(start, rangeLength);
104 }
105
106 void insertRange(int start, int rangeLength, [E initialValue]) {
107 if (rangeLength == 0) return;
108 if (rangeLength < 0) throw new IllegalArgumentException('length');
109 if (start < 0 || start > this.length)
110 throw new IndexOutOfRangeException(start);
111
112 // Splice in the values with a minimum of array allocations.
113 var args = new ListFactory(rangeLength + 2);
114 args[0] = start;
115 args[1] = 0;
116 for (var i = 0; i < rangeLength; i++) {
117 args[i + 2] = initialValue;
118 }
119 this._splice_apply(args);
120 }
121
122 // Collection<E> members:
123 void forEach(void f(E element)) native;
124 ListFactory<E> filter(bool f(E element)) native;
125 ListFactory map(f(E element)) native;
126 bool every(bool f(E element)) native;
127 bool some(bool f(E element)) native;
128 bool isEmpty() => length == 0;
129
130 // Iterable<E> members:
131 Iterator<E> iterator() => new ListIterator(this);
132
133 String toString() => Collections.collectionToString(this);
134
135 // Native methods.
136 ListFactory<E> _slice(start, end) native 'slice';
137 void _splice(start, length) native 'splice';
138 void _splice_apply(args) native 'this.splice.apply(this, args)';
139 }
140
141 // Iterator for lists.
142 class ListIterator<T> implements Iterator<T> {
143 ListIterator(List<T> array)
144 : _array = array,
145 _pos = 0 {
146 }
147
148 bool hasNext() {
149 return _array.length > _pos;
150 }
151
152 T next() {
153 // TODO(jmesserly): this check is redundant in a for-in loop
154 // Must we do it?
155 if (!hasNext()) {
156 throw const NoMoreElementsException();
157 }
158 return _array[_pos++];
159 }
160
161 final List<T> _array;
162 int _pos;
163 }
164
165 // TODO(jimhug): Enforce immutability on IE
166 ImmutableList _constList(List other) native '''
167 other.__proto__ = ImmutableList.prototype;
168 return other;
169 '''
170 { new ImmutableList(other.length); }
171
172
173 /** An immutable list. Attempting to modify the list will throw an exception. */
174 class ImmutableList<E> extends ListFactory<E> {
175 // TODO(jimhug): Can this go away now?
176 int get length() native "return this.length;";
177
178 void set length(int length) {
179 throw const IllegalAccessException();
180 }
181
182 ImmutableList(int length) : super(length);
183
184 factory ImmutableList.from(List other) {
185 return _constList(other);
186 }
187
188 void operator []=(int index, E value) {
189 throw const IllegalAccessException();
190 }
191
192 void copyFrom(List src, int srcStart, int dstStart, int count) {
193 throw const IllegalAccessException();
194 }
195
196 void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
197 throw const IllegalAccessException();
198 }
199
200 void removeRange(int start, int length) {
201 throw const IllegalAccessException();
202 }
203
204 void insertRange(int start, int length, [E initialValue = null]) {
205 throw const IllegalAccessException();
206 }
207
208 void sort(int compare(E a, E b)) {
209 throw const IllegalAccessException();
210 }
211
212 void add(E element) {
213 throw const IllegalAccessException();
214 }
215
216 void addLast(E element) {
217 throw const IllegalAccessException();
218 }
219
220 void addAll(Collection<E> elements) {
221 throw const IllegalAccessException();
222 }
223
224 void clear() {
225 throw const IllegalAccessException();
226 }
227
228 E removeLast() {
229 throw const IllegalAccessException();
230 }
231
232 String toString() => Collections.collectionToString(this);
233 }
234
235
236 LinkedHashMapImplementation _map(List itemsAndKeys) {
237 LinkedHashMapImplementation ret = new LinkedHashMapImplementation();
238 for (int i=0; i < itemsAndKeys.length;) {
239 ret[itemsAndKeys[i++]] = itemsAndKeys[i++];
240 }
241 return ret;
242 }
243
244 ImmutableMap _constMap(List itemsAndKeys) {
245 return new ImmutableMap(itemsAndKeys);
246 }
247
248 /** An immutable map. */
249 class ImmutableMap<K, V> implements Map<K, V> {
250 final Map<K, V> _internal;
251
252 ImmutableMap(List keyValuePairs) : _internal = _map(keyValuePairs);
253
254 V operator [](K key) => _internal[key];
255
256 bool isEmpty() => _internal.isEmpty();
257
258 int get length() => _internal.length;
259
260 void forEach(void f(K key, V value)) {
261 _internal.forEach(f);
262 }
263
264 Collection<K> getKeys() => _internal.getKeys();
265
266 Collection<V> getValues() => _internal.getValues();
267
268 bool containsKey(K key) => _internal.containsKey(key);
269
270 bool containsValue(V value) => _internal.containsValue(value);
271
272 void operator []=(K key, V value) {
273 throw const IllegalAccessException();
274 }
275
276 V putIfAbsent(K key, V ifAbsent()) {
277 throw const IllegalAccessException();
278 }
279
280 void clear() {
281 throw const IllegalAccessException();
282 }
283
284 V remove(K key) {
285 throw const IllegalAccessException();
286 }
287
288 String toString() => Maps.mapToString(this);
289 }
290
291
292 // TODO(jmesserly): this should wrap real RegExp when we can
293 // We can't do it yet because we'd need a way to redirect the const
294 // default constructor.
295 // TODO(jimhug): One way to resolve this is to make the const constructor
296 // very special in order for it to generate JS regex literals into the code
297 // and then treat the constructor as a factory.
298 class JSSyntaxRegExp implements RegExp {
299 final String pattern;
300 final bool multiLine;
301 final bool ignoreCase;
302
303 const JSSyntaxRegExp(String pattern, [bool multiLine, bool ignoreCase]):
304 this._create(pattern,
305 (multiLine == true ? 'm' : '') + (ignoreCase == true ? 'i' : ''));
306
307 const JSSyntaxRegExp._create(String pattern, String flags) native
308 '''this.re = new RegExp(pattern, flags);
309 this.pattern = pattern;
310 this.multiLine = this.re.multiline;
311 this.ignoreCase = this.re.ignoreCase;''';
312
313 Match firstMatch(String str) {
314 List<String> m = _exec(str);
315 return m == null ? null
316 : new MatchImplementation(pattern, str, _matchStart(m), _lastIndex, m);
317 }
318
319 List<String> _exec(String str) native "return this.re.exec(str);" {
320 // Note: this code is just a hint to tell the frog compiler the dependencies
321 // this native code might have. It is not an implementation.
322 return [];
323 }
324 int _matchStart(m) native "return m.index;";
325 int get _lastIndex() native "return this.re.lastIndex;";
326
327 bool hasMatch(String str) native "return this.re.test(str);";
328
329 String stringMatch(String str) {
330 var match = firstMatch(str);
331 return match === null ? null : match.group(0);
332 }
333
334 Iterable<Match> allMatches(String str) => new _AllMatchesIterable(this, str);
335
336 /**
337 * Returns a new RegExp with the same pattern as this one and with the
338 * "global" flag set. This allows us to match this RegExp against a string
339 * multiple times, to support things like [allMatches] and
340 * [String.replaceAll].
341 *
342 * Note that the returned RegExp disobeys the normal API in that it maintains
343 * state about the location of the last match.
344 */
345 JSSyntaxRegExp get _global() => new JSSyntaxRegExp._create(pattern,
346 'g' + (multiLine ? 'm' : '') + (ignoreCase ? 'i' : ''));
347 }
348
349 class MatchImplementation implements Match {
350 const MatchImplementation(
351 String this.pattern,
352 String this.str,
353 int this._start,
354 int this._end,
355 List<String> this._groups);
356
357 final String pattern;
358 final String str;
359 final int _start;
360 final int _end;
361 final List<String> _groups;
362
363 int start() => _start;
364 int end() => _end;
365 String group(int groupIndex) => _groups[groupIndex];
366 String operator [](int groupIndex) => _groups[groupIndex];
367 int groupCount() => _groups.length;
368
369 List<String> groups(List<int> groupIndices) {
370 List<String> out = [];
371 groupIndices.forEach((int groupIndex) => out.add(_groups[groupIndex]));
372 return out;
373 }
374 }
375
376 class _AllMatchesIterable implements Iterable<Match> {
377 final JSSyntaxRegExp _re;
378 final String _str;
379
380 const _AllMatchesIterable(this._re, this._str);
381
382 Iterator<Match> iterator() => new _AllMatchesIterator(_re, _str);
383 }
384
385 class _AllMatchesIterator implements Iterator<Match> {
386 final RegExp _re;
387 final String _str;
388 Match _next;
389 bool _done;
390
391 _AllMatchesIterator(JSSyntaxRegExp re, String this._str)
392 : _done = false, _re = re._global;
393
394 Match next() {
395 if (!hasNext()) {
396 throw const NoMoreElementsException();
397 }
398
399 // _next is set by #hasNext
400 var result = _next;
401 _next = null;
402 return result;
403 }
404
405 bool hasNext() {
406 if (_done) {
407 return false;
408 } else if (_next != null) {
409 return true;
410 }
411
412 _next = _re.firstMatch(_str);
413 if (_next == null) {
414 _done = true;
415 return false;
416 } else {
417 return true;
418 }
419 }
420 }
421
422
423 class NumImplementation implements int, double native "Number" {
424 // Arithmetic operations.
425 num operator +(num other) native;
426 num operator -(num other) native;
427 num operator *(num other) native;
428 num operator %(num other) native;
429 num operator /(num other) native;
430 // Truncating division.
431 // TODO(jimhug): Implement
432 num operator ~/(num other) native;
433 // The unary '-' operator.
434 num operator negate() native "'use strict'; return -this;";
435
436 // Relational operations.
437 bool operator <(num other) native;
438 bool operator <=(num other) native;
439 bool operator >(num other) native;
440 bool operator >=(num other) native;
441
442 bool operator ==(var other) native;
443
444 // Bitwise operations
445 int operator &(int other) native;
446 int operator |(int other) native;
447 int operator ^(int other) native;
448 int operator ~() native;
449 int operator <<(int shiftAmount) native;
450 int operator >>(int shiftAmount) native;
451
452
453 // TODO(jimhug): Move these out of methods to avoid boxing when not needed.
454 // TODO(jmesserly): for now I'm avoiding boxing with "use strict", however,
455 // we might want to do something better. It would be nice if operators and
456 // methods on String/num were handled in a uniform way.
457 num remainder(num other) native "'use strict'; return this % other;";
458
459 bool isEven() native "'use strict'; return ((this & 1) == 0);";
460 bool isOdd() native "'use strict'; return ((this & 1) == 1);";
461 bool isNaN() native "'use strict'; return isNaN(this);";
462 bool isNegative() native
463 "'use strict'; return this == 0 ? (1 / this) < 0 : this < 0;";
464 bool isInfinite() native
465 "'use strict'; return (this == Infinity) || (this == -Infinity);";
466
467 num abs() native "'use strict'; return Math.abs(this);";
468 num round() native "'use strict'; return Math.round(this);";
469 num floor() native "'use strict'; return Math.floor(this);";
470 num ceil() native "'use strict'; return Math.ceil(this);";
471 num truncate() native
472 "'use strict'; return (this < 0) ? Math.ceil(this) : Math.floor(this);";
473
474 int hashCode() native "'use strict'; return this & 0x1FFFFFFF;";
475
476 // If truncated is -0.0 return +0. The test will also trigger for positive
477 // 0s but that's not a problem.
478 int toInt() native '''
479 'use strict';
480 if (isNaN(this)) \$throw(new BadNumberFormatException("NaN"));
481 if ((this == Infinity) || (this == -Infinity)) {
482 \$throw(new BadNumberFormatException("Infinity"));
483 }
484 var truncated = (this < 0) ? Math.ceil(this) : Math.floor(this);
485 if (truncated == -0.0) return 0;
486 return truncated;''' { throw new BadNumberFormatException(""); }
487
488 double toDouble() native "'use strict'; return this + 0;";
489
490 String toStringAsFixed(int fractionDigits) native
491 "'use strict'; return this.toFixed(fractionDigits);";
492 String toStringAsExponential(int fractionDigits) native
493 "'use strict'; return this.toExponential(fractionDigits)";
494 String toStringAsPrecision(int precision) native
495 "'use strict'; return this.toPrecision(precision)";
496 String toRadixString(int radix) native
497 "'use strict'; return this.toString(radix)";
498
499 // CompareTo has to give a complete order, including -0/+0, NaN and
500 // Infinities.
501 // Order is: -Inf < .. < -0.0 < 0.0 .. < +inf < NaN.
502 int compareTo(NumImplementation other) {
503 // Don't use the 'this' object (which is a JS Number object), but get the
504 // primitive JS number by invoking toDouble().
505 num thisValue = toDouble();
506 // Remember that NaN return false for any comparison.
507 if (thisValue < other) {
508 return -1;
509 } else if (thisValue > other) {
510 return 1;
511 } else if (thisValue == other) {
512 if (thisValue == 0) {
513 bool thisIsNegative = isNegative();
514 bool otherIsNegative = other.isNegative();
515 if (thisIsNegative == otherIsNegative) return 0;
516 if (thisIsNegative) return -1;
517 return 1;
518 }
519 return 0;
520 } else if (isNaN()) {
521 if (other.isNaN()) {
522 return 0;
523 }
524 return 1;
525 } else {
526 return -1;
527 }
528 }
529 }
OLDNEW
« no previous file with comments | « frog/lib/corelib.dart ('k') | frog/lib/date_implementation.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698