| // 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. |
| |
| // @dart = 2.9 |
| |
| 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 class ExpressionWithEval { |
| int get eval; |
| } |
| |
| abstract class AdditionWithEval<E extends ExpressionWithEval> { |
| E get operand1; |
| E get operand2; |
| int get eval => operand1.eval + operand2.eval; |
| } |
| |
| abstract class SubtractionWithEval<E extends ExpressionWithEval> { |
| E get operand1; |
| E get operand2; |
| int get eval => operand1.eval - operand2.eval; |
| } |
| |
| abstract 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 class MultiplicationWithEval<E extends ExpressionWithEval> { |
| E get operand1; |
| E get operand2; |
| int get eval => operand1.eval * operand2.eval; |
| } |
| |
| // library string_converter; |
| |
| abstract class ExpressionWithStringConversion { |
| String toString(); |
| } |
| |
| abstract class AdditionWithStringConversion< |
| E extends ExpressionWithStringConversion> { |
| E get operand1; |
| E get operand2; |
| String toString() => '($operand1 + $operand2))'; |
| } |
| |
| abstract class SubtractionWithStringConversion< |
| E extends ExpressionWithStringConversion> { |
| E get operand1; |
| E get operand2; |
| String toString() => '($operand1 - $operand2)'; |
| } |
| |
| abstract class NumberWithStringConversion { |
| int get val; |
| String toString() => val.toString(); |
| } |
| |
| abstract 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}'); |
| } |