| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'environment.dart'; | 5 import '../environment.dart'; |
| 6 | 6 |
| 7 /// A parsed Boolean expression AST. | 7 /// A parsed Boolean expression AST. |
| 8 abstract class Expression { | 8 abstract class Expression { |
| 9 /// Parses Boolean expressions in a .status file for Dart. | 9 /// Parses Boolean expressions in a .status file for Dart. |
| 10 /// | 10 /// |
| 11 /// The grammar is: | 11 /// The grammar is: |
| 12 /// | 12 /// |
| 13 /// expression := or | 13 /// expression := or |
| 14 /// or := and ( "||" and )* | 14 /// or := and ( "||" and )* |
| 15 /// and := primary ( "&&" primary )* | 15 /// and := primary ( "&&" primary )* |
| 16 /// primary := "$" identifier ( "==" | "!=" ) identifier | | 16 /// primary := "$" identifier ( "==" | "!=" ) identifier | |
| 17 /// "!"? "$" identifier | | 17 /// "!"? "$" identifier | |
| 18 /// "(" expression ")" | 18 /// "(" expression ")" |
| 19 /// identifier := regex "\w+" | 19 /// identifier := regex "\w+" |
| 20 /// | 20 /// |
| 21 /// Expressions evaluate as expected, with values of variables found in an | 21 /// Expressions evaluate as expected, with values of variables found in an |
| 22 /// environment passed to the evaluator. | 22 /// environment passed to the evaluator. |
| 23 static Expression parse(String expression) => | 23 static Expression parse(String expression) => |
| 24 new _ExpressionParser(expression).parse(); | 24 new _ExpressionParser(expression).parse(); |
| 25 | 25 |
| 26 /// Validates that this expression does not contain any invalid uses of | 26 /// Validates that this expression does not contain any invalid uses of |
| 27 /// variables. | 27 /// variables. |
| 28 /// | 28 /// |
| 29 /// Ensures that any variable names are known and that any literal values are | 29 /// Ensures that any variable names are known and that any literal values are |
| 30 /// allowed for their corresponding variable. If an invalid variable or value | 30 /// allowed for their corresponding variable. If an invalid variable or value |
| 31 /// is found, adds appropriate error messages to [errors]. | 31 /// is found, adds appropriate error messages to [errors]. |
| 32 void validate(List<String> errors); | 32 void validate(Environment environment, List<String> errors); |
| 33 | 33 |
| 34 /// Evaluates the expression where all variables are defined by the given | 34 /// Evaluates the expression where all variables are defined by the given |
| 35 /// [environment]. | 35 /// [environment]. |
| 36 bool evaluate(Environment environment); | 36 bool evaluate(Environment environment); |
| 37 } | 37 } |
| 38 | 38 |
| 39 /// Keyword token strings. | 39 /// Keyword token strings. |
| 40 class _Token { | 40 class _Token { |
| 41 static const leftParen = "("; | 41 static const leftParen = "("; |
| 42 static const rightParen = ")"; | 42 static const rightParen = ")"; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 /// $variable == someValue | 76 /// $variable == someValue |
| 77 /// ``` | 77 /// ``` |
| 78 /// Negate the result if [negate] is true. | 78 /// Negate the result if [negate] is true. |
| 79 class _ComparisonExpression implements Expression { | 79 class _ComparisonExpression implements Expression { |
| 80 final _Variable left; | 80 final _Variable left; |
| 81 final String right; | 81 final String right; |
| 82 final bool negate; | 82 final bool negate; |
| 83 | 83 |
| 84 _ComparisonExpression(this.left, this.right, this.negate); | 84 _ComparisonExpression(this.left, this.right, this.negate); |
| 85 | 85 |
| 86 void validate(List<String> errors) { | 86 void validate(Environment environment, List<String> errors) { |
| 87 Environment.validate(left.name, right, errors); | 87 environment.validate(left.name, right, errors); |
| 88 } | 88 } |
| 89 | 89 |
| 90 bool evaluate(Environment environment) { | 90 bool evaluate(Environment environment) { |
| 91 return negate != (left.lookup(environment) == right); | 91 return negate != (left.lookup(environment) == right); |
| 92 } | 92 } |
| 93 | 93 |
| 94 String toString() => "(\$${left.name} ${negate ? '!=' : '=='} $right)"; | 94 String toString() => "(\$${left.name} ${negate ? '!=' : '=='} $right)"; |
| 95 } | 95 } |
| 96 | 96 |
| 97 /// A reference to a variable defined in the environment. The expression | 97 /// A reference to a variable defined in the environment. The expression |
| (...skipping 12 matching lines...) Expand all Loading... |
| 110 /// is equivalent to | 110 /// is equivalent to |
| 111 /// ``` | 111 /// ``` |
| 112 /// $variable != true | 112 /// $variable != true |
| 113 /// ``` | 113 /// ``` |
| 114 class _VariableExpression implements Expression { | 114 class _VariableExpression implements Expression { |
| 115 final _Variable variable; | 115 final _Variable variable; |
| 116 final bool negate; | 116 final bool negate; |
| 117 | 117 |
| 118 _VariableExpression(this.variable, {this.negate = false}); | 118 _VariableExpression(this.variable, {this.negate = false}); |
| 119 | 119 |
| 120 void validate(List<String> errors) { | 120 void validate(Environment environment, List<String> errors) { |
| 121 // It must be a Boolean, so it should allow either Boolean value. | 121 // It must be a Boolean, so it should allow either Boolean value. |
| 122 Environment.validate(variable.name, "true", errors); | 122 environment.validate(variable.name, "true", errors); |
| 123 } | 123 } |
| 124 | 124 |
| 125 bool evaluate(Environment environment) => | 125 bool evaluate(Environment environment) => |
| 126 negate != (variable.lookup(environment) == "true"); | 126 negate != (variable.lookup(environment) == "true"); |
| 127 | 127 |
| 128 String toString() => "(bool ${negate ? "! " : ""}\$${variable.name})"; | 128 String toString() => "(bool ${negate ? "! " : ""}\$${variable.name})"; |
| 129 } | 129 } |
| 130 | 130 |
| 131 /// A logical `||` or `&&` expression. | 131 /// A logical `||` or `&&` expression. |
| 132 class _LogicExpression implements Expression { | 132 class _LogicExpression implements Expression { |
| 133 /// The operator, `||` or `&&`. | 133 /// The operator, `||` or `&&`. |
| 134 final String op; | 134 final String op; |
| 135 | 135 |
| 136 final Expression left; | 136 final Expression left; |
| 137 final Expression right; | 137 final Expression right; |
| 138 | 138 |
| 139 _LogicExpression(this.op, this.left, this.right); | 139 _LogicExpression(this.op, this.left, this.right); |
| 140 | 140 |
| 141 void validate(List<String> errors) { | 141 void validate(Environment environment, List<String> errors) { |
| 142 left.validate(errors); | 142 left.validate(environment, errors); |
| 143 right.validate(errors); | 143 right.validate(environment, errors); |
| 144 } | 144 } |
| 145 | 145 |
| 146 bool evaluate(Environment environment) => (op == _Token.and) | 146 bool evaluate(Environment environment) => (op == _Token.and) |
| 147 ? left.evaluate(environment) && right.evaluate(environment) | 147 ? left.evaluate(environment) && right.evaluate(environment) |
| 148 : left.evaluate(environment) || right.evaluate(environment); | 148 : left.evaluate(environment) || right.evaluate(environment); |
| 149 | 149 |
| 150 String toString() => "($left $op $right)"; | 150 String toString() => "($left $op $right)"; |
| 151 } | 151 } |
| 152 | 152 |
| 153 /// Parser for Boolean expressions in a .status file for Dart. | 153 /// Parser for Boolean expressions in a .status file for Dart. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 return true; | 283 return true; |
| 284 } | 284 } |
| 285 | 285 |
| 286 /// Consumes the current token and returns it. | 286 /// Consumes the current token and returns it. |
| 287 String advance() { | 287 String advance() { |
| 288 var previous = current; | 288 var previous = current; |
| 289 current = tokenIterator.moveNext() ? tokenIterator.current : null; | 289 current = tokenIterator.moveNext() ? tokenIterator.current : null; |
| 290 return previous; | 290 return previous; |
| 291 } | 291 } |
| 292 } | 292 } |
| OLD | NEW |