Chromium Code Reviews| Index: lib/parser.dart |
| diff --git a/lib/parser.dart b/lib/parser.dart |
| index a715a9ab1cec412c6f29498b0f192f99e9445e49..5c2066069f2a16b366fac661bb30665de78572c8 100644 |
| --- a/lib/parser.dart |
| +++ b/lib/parser.dart |
| @@ -2188,6 +2188,8 @@ class _Parser { |
| var nameValue = identifier(); // Snarf up the ident we'll remap, maybe. |
| if (!ieFilter && _maybeEat(TokenKind.LPAREN)) { |
| + var calc = processCalc(nameValue); |
| + if (calc != null) return calc; |
| // FUNCTION |
| return processFunction(nameValue); |
| } |
| @@ -2442,6 +2444,66 @@ class _Parser { |
| } |
| } |
| + // TODO(terry): Hack to gobble up the calc expression as a string looking |
| + // for the matching RPAREN the expression is not parsed into the |
| + // AST. |
| + // |
| + // grammar should be: |
| + // |
| + // <calc()> = calc( <calc-sum> ) |
| + // <calc-sum> = <calc-product> [ [ '+' | '-' ] <calc-product> ]* |
| + // <calc-product> = <calc-value> [ '*' <calc-value> | '/' <number> ]* |
| + // <calc-value> = <number> | <dimension> | <percentage> | ( <calc-sum> ) |
| + // |
| + String processCalcExpression() { |
| + var start = _peekToken.span; |
|
kevmoo
2015/10/16 17:56:39
start seems to not be used
terry
2015/10/16 18:28:46
Right, not used now but will be when fully parsed.
|
| + |
| + var inString = tokenizer._inString; |
| + tokenizer._inString = false; |
| + |
| + // Gobble up everything until we hit our stop token. |
| + var stringValue = new StringBuffer(); |
| + var left = 1; |
| + var matchingParens = false; |
| + while (_peek() != TokenKind.END_OF_FILE && !matchingParens) { |
| + var token = _peek(); |
| + if (token == TokenKind.LPAREN) |
| + left++; |
| + else if (token == TokenKind.RPAREN) |
| + left--; |
| + |
| + matchingParens = left == 0; |
| + if (!matchingParens) stringValue.write(_next().text); |
| + } |
| + |
| + if (!matchingParens) { |
| + _error("problem parsing function expected ), ", _peekToken.span); |
| + } |
| + |
| + tokenizer._inString = inString; |
| + |
| + return stringValue.toString(); |
| + } |
| + |
| + processCalc(Identifier func) { |
|
yjbanov
2015/10/16 17:39:55
missing return type
terry
2015/10/16 18:28:46
Done.
|
| + var start = _peekToken.span; |
| + |
| + var name = func.name; |
| + if (name == 'calc') { |
| + // TODO(terry): Implement expression parsing properly. |
| + String expression = processCalcExpression(); |
| + var calcExpr = new LiteralTerm(expression, expression, _makeSpan(start)); |
| + |
| + if (!_maybeEat(TokenKind.RPAREN)) { |
| + _error("problem parsing function expected ), ", _peekToken.span); |
| + } |
| + |
| + return new CalcTerm(name, name, calcExpr, _makeSpan(start)); |
| + } |
| + |
| + return null; |
| + } |
| + |
| // Function grammar: |
| // |
| // function: IDENT '(' expr ')' |
| @@ -2466,9 +2528,6 @@ class _Parser { |
| } |
| return new UriTerm(urlParam, _makeSpan(start)); |
| - case 'calc': |
| - // TODO(terry): Implement expression handling... |
| - break; |
| case 'var': |
| // TODO(terry): Consider handling var in IE specific filter/progid. This |
| // will require parsing entire IE specific syntax e.g., |