diff --git a/lib/src/parser.dart b/lib/src/parser.dart index f709c3c..25d3af9 100644 --- a/lib/src/parser.dart +++ b/lib/src/parser.dart @@ -9,7 +9,7 @@ class ExpressionParser { (l) => l[1] == null ? l[0] : ConditionalExpression(l[0], l[1][0], l[1][1]))); - token.set((literal | unaryExpression | variable).cast()); + token.set((unaryExpression | variable).cast()); } // Gobbles only identifiers @@ -99,6 +99,10 @@ class ExpressionParser { mapLiteral) .cast(); + Parser get _primary => + (literal | group | thisExpression | identifier.map((v) => Variable(v))) + .cast(); + // An individual part of a binary expression: // e.g. `foo.bar(baz)`, `1`, `'abc'`, `(a % 2)` (because it's in parenthesis) final SettableParser token = undefined(); @@ -207,9 +211,8 @@ class ExpressionParser { // e.g. `foo`, `bar.baz`, `foo['bar'].baz` // It also gobbles function calls: // e.g. `Math.acos(obj.angle)` - Parser get variable => groupOrIdentifier - .seq((memberArgument.cast() | indexArgument | callArgument).star()) - .map((l) { + Parser get variable => + _primary.seq((memberArgument.cast() | indexArgument | callArgument).star()).map((l) { var a = l[0] as Expression; var b = l[1] as List; return b.fold(a, (Expression object, argument) { @@ -234,9 +237,6 @@ class ExpressionParser { Parser get group => (char('(') & expression.trim() & char(')')).pick(1).cast(); - Parser get groupOrIdentifier => - (group | thisExpression | identifier.map((v) => Variable(v))).cast(); - Parser get memberArgument => (char('.') & identifier).pick(1).cast(); diff --git a/test/expressions_test.dart b/test/expressions_test.dart index d60f804..7133bc0 100644 --- a/test/expressions_test.dart +++ b/test/expressions_test.dart @@ -254,6 +254,15 @@ void main() { }); group('member expressions', () { + test('literal members', () { + var evaluator = ExpressionEvaluator(memberAccessors: [ + MemberAccessor({'length': (v) => v.length}), + MemberAccessor({'length': (v) => v.length}) + ]); + expect(evaluator.eval(Expression.parse('[1,2,3].length'), {}), 3); + expect(evaluator.eval(Expression.parse("'hello'.length"), {}), 5); + }); + test('toString member', () { var evaluator = ExpressionEvaluator(memberAccessors: [ MemberAccessor({'toString': (v) => v.toString})