|  | // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  |  | 
|  | // library abstract_expressions; | 
|  |  | 
|  | abstract class AbstractExpression {} | 
|  |  | 
|  | abstract class AbstractAddition<E> { | 
|  | E operand1, operand2; | 
|  | AbstractAddition(this.operand1, this.operand2); | 
|  | } | 
|  |  | 
|  | abstract class AbstractSubtraction<E> { | 
|  | E operand1, operand2; | 
|  | AbstractSubtraction(this.operand1, this.operand2); | 
|  | } | 
|  |  | 
|  | abstract class AbstractNumber { | 
|  | int val; | 
|  | AbstractNumber(this.val); | 
|  | } | 
|  |  | 
|  | // library evaluator; | 
|  |  | 
|  | abstract mixin class ExpressionWithEval { | 
|  | int get eval; | 
|  | } | 
|  |  | 
|  | abstract mixin class AdditionWithEval<E extends ExpressionWithEval> { | 
|  | E get operand1; | 
|  | E get operand2; | 
|  | int get eval => operand1.eval + operand2.eval; | 
|  | } | 
|  |  | 
|  | abstract mixin class SubtractionWithEval<E extends ExpressionWithEval> { | 
|  | E get operand1; | 
|  | E get operand2; | 
|  | int get eval => operand1.eval - operand2.eval; | 
|  | } | 
|  |  | 
|  | abstract mixin class NumberWithEval { | 
|  | int get val; | 
|  | int get eval => val; | 
|  | } | 
|  |  | 
|  | // library multiplication; | 
|  |  | 
|  | abstract class AbstractMultiplication<E> { | 
|  | E operand1, operand2; | 
|  | AbstractMultiplication(this.operand1, this.operand2); | 
|  | } | 
|  |  | 
|  | // library multiplicationEvaluator; | 
|  |  | 
|  | // import 'evaluator.dart' show ExpressionWithEval; | 
|  |  | 
|  | abstract mixin class MultiplicationWithEval<E extends ExpressionWithEval> { | 
|  | E get operand1; | 
|  | E get operand2; | 
|  | int get eval => operand1.eval * operand2.eval; | 
|  | } | 
|  |  | 
|  | // library string_converter; | 
|  |  | 
|  | abstract mixin class ExpressionWithStringConversion { | 
|  | String toString(); | 
|  | } | 
|  |  | 
|  | abstract mixin class AdditionWithStringConversion< | 
|  | E extends ExpressionWithStringConversion> { | 
|  | E get operand1; | 
|  | E get operand2; | 
|  | String toString() => '($operand1 + $operand2))'; | 
|  | } | 
|  |  | 
|  | abstract mixin class SubtractionWithStringConversion< | 
|  | E extends ExpressionWithStringConversion> { | 
|  | E get operand1; | 
|  | E get operand2; | 
|  | String toString() => '($operand1 - $operand2)'; | 
|  | } | 
|  |  | 
|  | abstract mixin class NumberWithStringConversion { | 
|  | int get val; | 
|  | String toString() => val.toString(); | 
|  | } | 
|  |  | 
|  | abstract mixin class MultiplicationWithStringConversion< | 
|  | E extends ExpressionWithStringConversion> { | 
|  | E get operand1; | 
|  | E get operand2; | 
|  | String toString() => '($operand1 * $operand2)'; | 
|  | } | 
|  |  | 
|  | // library expressions; | 
|  |  | 
|  | // import 'abstractExpressions.dart'; | 
|  | // import 'evaluator.dart'; | 
|  | // import 'multiplication.dart'; | 
|  | // import 'multiplicationEvaluator.dart'; | 
|  | // import 'stringConverter.dart'; | 
|  |  | 
|  | abstract class Expression = AbstractExpression | 
|  | with ExpressionWithEval, ExpressionWithStringConversion; | 
|  |  | 
|  | class Addition = AbstractAddition<Expression> | 
|  | with AdditionWithEval<Expression>, AdditionWithStringConversion<Expression> | 
|  | implements Expression; | 
|  |  | 
|  | class Subtraction = AbstractSubtraction<Expression> | 
|  | with | 
|  | SubtractionWithEval<Expression>, | 
|  | SubtractionWithStringConversion<Expression> | 
|  | implements Expression; | 
|  |  | 
|  | class Number = AbstractNumber | 
|  | with NumberWithEval, NumberWithStringConversion | 
|  | implements Expression; | 
|  |  | 
|  | class Multiplication = AbstractMultiplication<Expression> | 
|  | with | 
|  | MultiplicationWithEval<Expression>, | 
|  | MultiplicationWithStringConversion<Expression> | 
|  | implements Expression; | 
|  |  | 
|  | void main() { | 
|  | Expression e = new Multiplication(new Addition(new Number(4), new Number(2)), | 
|  | new Subtraction(new Number(10), new Number(7))); | 
|  | Expect.equals('((4 + 2)) * (10 - 7)) = 18', '$e = ${e.eval}'); | 
|  | } |