From 6798fec4390a72b7943a49505f8a245b6016c84b Mon Sep 17 00:00:00 2001 From: Zach Snow Date: Mon, 22 Apr 2013 17:42:34 -0700 Subject: feat($parse): add support for ternary operators to parser Add '?' token to lexer, add ternary rule to parser at (hopefully) proper precedence and associativity (based on https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence). Since (exp1 && exp2 || exp3) is supported by the parser, and (exp1 ? exp2 : exp3) works the same way, it seems reasonable to add this minor form of control to templates (see #719). --- src/ng/parse.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ng/parse.js b/src/ng/parse.js index 26c41a90..4616d15d 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -58,7 +58,7 @@ function lex(text, csp){ (token=tokens[tokens.length-1])) { token.json = token.text.indexOf('.') == -1; } - } else if (is('(){}[].,;:')) { + } else if (is('(){}[].,;:?')) { tokens.push({ index:index, text:ch, @@ -359,6 +359,14 @@ function parser(text, json, $filter, csp){ }); } + function ternaryFn(left, middle, right){ + return extend(function(self, locals){ + return left(self, locals) ? middle(self, locals) : right(self, locals); + }, { + constant: left.constant && middle.constant && right.constant + }); + } + function binaryFn(left, fn, right) { return extend(function(self, locals) { return fn(self, locals, left, right); @@ -429,7 +437,7 @@ function parser(text, json, $filter, csp){ } function _assignment() { - var left = logicalOR(); + var left = ternary(); var right; var token; if ((token = expect('='))) { @@ -437,7 +445,7 @@ function parser(text, json, $filter, csp){ throwError("implies assignment but [" + text.substring(0, token.index) + "] can not be assigned to", token); } - right = logicalOR(); + right = ternary(); return function(scope, locals){ return left.assign(scope, right(scope, locals), locals); }; @@ -446,6 +454,24 @@ function parser(text, json, $filter, csp){ } } + function ternary() { + var left = logicalOR(); + var middle; + var token; + if((token = expect('?'))){ + middle = ternary(); + if((token = expect(':'))){ + return ternaryFn(left, middle, ternary()); + } + else { + throwError('expected :', token); + } + } + else { + return left; + } + } + function logicalOR() { var left = logicalAND(); var token; -- cgit v1.2.3