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

Side by Side Diff: lib/eval.dart

Issue 17553018: Initial stream support (Closed) Base URL: https://github.com/dart-lang/fancy-syntax.git@master
Patch Set: Created 7 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library fancy_syntax.eval; 5 library fancy_syntax.eval;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:mirrors'; 9 import 'dart:mirrors';
10 10
11 import 'package:mdv_observe/mdv_observe.dart'; 11 import 'package:mdv_observe/mdv_observe.dart';
12 12
13 import 'async.dart';
13 import 'expression.dart'; 14 import 'expression.dart';
14 import 'filter.dart'; 15 import 'filter.dart';
15 import 'visitor.dart'; 16 import 'visitor.dart';
16 import 'parser.dart'; 17 import 'parser.dart';
18 import 'src/mirrors.dart';
17 19
18 final _BINARY_OPERATORS = { 20 final _BINARY_OPERATORS = {
19 '+': (a, b) => a + b, 21 '+': (a, b) => a + b,
20 '-': (a, b) => a - b, 22 '-': (a, b) => a - b,
21 '*': (a, b) => a * b, 23 '*': (a, b) => a * b,
22 '/': (a, b) => a / b, 24 '/': (a, b) => a / b,
23 '==': (a, b) => a == b, 25 '==': (a, b) => a == b,
24 '!=': (a, b) => a != b, 26 '!=': (a, b) => a != b,
25 '>': (a, b) => a > b, 27 '>': (a, b) => a > b,
26 '>=': (a, b) => a >= b, 28 '>=': (a, b) => a >= b,
27 '<': (a, b) => a < b, 29 '<': (a, b) => a < b,
28 '<=': (a, b) => a <= b, 30 '<=': (a, b) => a <= b,
29 '||': (a, b) => a || b, 31 '||': (a, b) => a || b,
30 '&&': (a, b) => a && b, 32 '&&': (a, b) => a && b,
31 '|': (a, f) { 33 '|': (a, f) {
32 if (f is Transformer) return f.forward(a); 34 if (f is Transformer) return f.forward(a);
33 if (f is Filter) return f(a); 35 if (f is Filter) return f(a);
34 throw new EvalException("Filters must be a one-argument function."); 36 throw new EvalException("Filters must be a one-argument function.");
35 } 37 }
36 }; 38 };
37 39
38 final _UNARY_OPERATORS = { 40 final _UNARY_OPERATORS = {
39 '+': (a) => a, 41 '+': (a) => a,
40 '-': (a) => -a, 42 '-': (a) => -a,
41 '!': (a) => !a, 43 '!': (a) => !a,
42 }; 44 };
43 45
46 final _BOOLEAN_OPERATORS = ['!', '||', '&&'];
47
44 /** 48 /**
45 * Evaluation [expr] in the context of [scope]. 49 * Evaluation [expr] in the context of [scope].
46 */ 50 */
47 Object eval(Expression expr, Scope scope) => observe(expr, scope)._value; 51 Object eval(Expression expr, Scope scope) => observe(expr, scope)._value;
48 52
49 53
50 ExpressionObserver observe(Expression expr, Scope scope) { 54 ExpressionObserver observe(Expression expr, Scope scope) {
51 var observer = new ObserverBuilder(scope).visit(expr); 55 var observer = new ObserverBuilder(scope).visit(expr);
52 new Updater(scope).visit(observer); 56 new Updater(scope).visit(observer);
53 return observer; 57 return observer;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 : _variables = new ObservableMap.from(variables); 137 : _variables = new ObservableMap.from(variables);
134 138
135 InstanceMirror get _modelMirror { 139 InstanceMirror get _modelMirror {
136 if (__modelMirror != null) return __modelMirror; 140 if (__modelMirror != null) return __modelMirror;
137 __modelMirror = reflect(model); 141 __modelMirror = reflect(model);
138 return __modelMirror; 142 return __modelMirror;
139 } 143 }
140 144
141 Object operator[](String name) { 145 Object operator[](String name) {
142 if (_variables.containsKey(name)) { 146 if (_variables.containsKey(name)) {
143 return _variables[name]; 147 return _convert(_variables[name]);
144 } else if (model != null) { 148 } else if (model != null) {
145 var symbol = new Symbol(name); 149 var symbol = new Symbol(name);
146 var classMirror = _modelMirror.type; 150 var classMirror = _modelMirror.type;
147 if (classMirror.variables.containsKey(symbol) || 151 var memberMirror = getMemberMirror(classMirror, symbol);
148 classMirror.getters.containsKey(symbol)) { 152 if (memberMirror is VariableMirror ||
149 return _modelMirror.getField(symbol).reflectee; 153 (memberMirror is MethodMirror && memberMirror.isGetter)) {
150 } else if (classMirror.methods.containsKey(symbol)) { 154 return _convert(_modelMirror.getField(symbol).reflectee);
155 } else if (memberMirror is MethodMirror) {
151 return new Method(_modelMirror, symbol); 156 return new Method(_modelMirror, symbol);
152 } 157 }
153 } 158 }
154 if (parent != null) { 159 if (parent != null) {
155 return parent[name]; 160 return _convert(parent[name]);
156 } else { 161 } else {
157 throw new EvalException("variable not found: $name in $hashCode"); 162 throw new EvalException("variable not found: $name in $hashCode");
158 } 163 }
159 } 164 }
160 165
161 Object ownerOf(String name) { 166 Object ownerOf(String name) {
162 if (_variables.containsKey(name)) { 167 if (_variables.containsKey(name)) {
163 return _variables; 168 return _variables;
164 } else { 169 } else {
165 var symbol = new Symbol(name); 170 var symbol = new Symbol(name);
166 var classMirror = _modelMirror.type; 171 var classMirror = _modelMirror.type;
167 if (classMirror.variables.containsKey(symbol) || 172 if (getMemberMirror(classMirror, symbol) != null) {
168 classMirror.getters.containsKey(symbol) ||
169 classMirror.methods.containsKey(symbol)) {
170 return model; 173 return model;
171 } 174 }
172 } 175 }
173 if (parent != null) { 176 if (parent != null) {
174 return parent.ownerOf(name); 177 return parent.ownerOf(name);
175 } 178 }
176 } 179 }
180
181 bool contains(String name) {
182 if (_variables.containsKey(name)) {
183 return true;
184 } else {
185 var symbol = new Symbol(name);
186 var classMirror = _modelMirror.type;
187 if (getMemberMirror(classMirror, symbol) != null) {
188 return true;
189 }
190 }
191 if (parent != null) {
192 return parent.contains(name);
193 }
194 return false;
195 }
196
197 String toString() => 'Scope($hashCode $parent)';
198 }
199
200 Object _convert(v) {
201 if (v is Stream) return new StreamBinding(v);
202 return v;
177 } 203 }
178 204
179 abstract class ExpressionObserver<E extends Expression> implements Expression { 205 abstract class ExpressionObserver<E extends Expression> implements Expression {
180 final E _expr; 206 final E _expr;
181 ExpressionObserver _parent; 207 ExpressionObserver _parent;
182 208
183 StreamSubscription _subscription; 209 StreamSubscription _subscription;
184 Object _value; 210 Object _value;
185 211
186 StreamController _controller = new StreamController.broadcast(); 212 StreamController _controller = new StreamController.broadcast();
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 435
410 String get method => _expr.method; 436 String get method => _expr.method;
411 437
412 _updateSelf(Scope scope) { 438 _updateSelf(Scope scope) {
413 var args = (arguments == null) 439 var args = (arguments == null)
414 ? [] 440 ? []
415 : arguments.map((a) => a._value) 441 : arguments.map((a) => a._value)
416 .toList(growable: false); 442 .toList(growable: false);
417 var receiverValue = receiver._value; 443 var receiverValue = receiver._value;
418 if (receiverValue == null) { 444 if (receiverValue == null) {
419 return null; 445 _value = null;
420 } 446 } else if (_expr.method == null) {
421 if (_expr.method == null) {
422 if (_expr.isGetter) { 447 if (_expr.isGetter) {
423 _value = receiverValue; 448 _value = receiverValue;
424 } else { 449 } else {
425 assert(receiverValue is Function); 450 assert(receiverValue is Function);
426 _value = call(receiverValue, args); 451 _value = call(receiverValue, args);
427 } 452 }
428 } else { 453 } else {
429 // special case [] because we don't need mirrors 454 // special case [] because we don't need mirrors
430 if (_expr.method == '[]') { 455 if (_expr.method == '[]') {
431 assert(args.length == 1); 456 assert(args.length == 1);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 _value = new Comprehension(identifier.value, iterable); 493 _value = new Comprehension(identifier.value, iterable);
469 } 494 }
470 495
471 accept(Visitor v) => v.visitInExpression(this); 496 accept(Visitor v) => v.visitInExpression(this);
472 } 497 }
473 498
474 _toBool(v) => (v == null) ? false : v; 499 _toBool(v) => (v == null) ? false : v;
475 500
476 call(dynamic receiver, List args) { 501 call(dynamic receiver, List args) {
477 if (receiver is Method) { 502 if (receiver is Method) {
478 return receiver.mirror.invoke(receiver.symbol, args, null).reflectee; 503 return
504 _convert(receiver.mirror.invoke(receiver.symbol, args, null).reflectee);
479 } else { 505 } else {
480 return Function.apply(receiver, args, null); 506 return _convert(Function.apply(receiver, args, null));
481 } 507 }
482 } 508 }
483 509
484 /** 510 /**
485 * A comprehension declaration ("a in b"). 511 * A comprehension declaration ("a in b").
486 */ 512 */
487 class Comprehension { 513 class Comprehension {
488 final String identifier; 514 final String identifier;
489 final Iterable iterable; 515 final Iterable iterable;
490 Comprehension(this.identifier, this.iterable); 516 Comprehension(this.identifier, this.iterable);
491 } 517 }
492 518
493 /** 519 /**
494 * A method on a model object in a [Scope]. 520 * A method on a model object in a [Scope].
495 */ 521 */
496 class Method { //implements _FunctionWrapper { 522 class Method { //implements _FunctionWrapper {
497 final InstanceMirror mirror; 523 final InstanceMirror mirror;
498 final Symbol symbol; 524 final Symbol symbol;
499 525
500 Method(this.mirror, this.symbol); 526 Method(this.mirror, this.symbol);
501 527
502 dynamic call(List args) => mirror.invoke(symbol, args, null).reflectee; 528 dynamic call(List args) => mirror.invoke(symbol, args, null).reflectee;
503 } 529 }
504 530
505 class EvalException implements Exception { 531 class EvalException implements Exception {
506 final String message; 532 final String message;
507 EvalException(this.message); 533 EvalException(this.message);
508 String toString() => "EvalException: $message"; 534 String toString() => "EvalException: $message";
509 } 535 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698