@ -60,6 +60,20 @@ export class Conditional extends AST {
|
||||
visit(visitor: AstVisitor) { return visitor.visitConditional(this); }
|
||||
}
|
||||
|
||||
export class If extends AST {
|
||||
constructor(public condition: AST, public trueExp: AST, public falseExp?: AST) { super(); }
|
||||
|
||||
eval(context, locals) {
|
||||
if (this.condition.eval(context, locals)) {
|
||||
this.trueExp.eval(context, locals);
|
||||
} else if (isPresent(this.falseExp)) {
|
||||
this.falseExp.eval(context, locals);
|
||||
}
|
||||
}
|
||||
|
||||
visit(visitor: AstVisitor) { return visitor.visitIf(this); }
|
||||
}
|
||||
|
||||
export class AccessMember extends AST {
|
||||
constructor(public receiver: AST, public name: string, public getter: Function,
|
||||
public setter: Function) {
|
||||
@ -321,6 +335,7 @@ export interface AstVisitor {
|
||||
visitBinary(ast: Binary): any;
|
||||
visitChain(ast: Chain): any;
|
||||
visitConditional(ast: Conditional): any;
|
||||
visitIf(ast: If): any;
|
||||
visitPipe(ast: Pipe): any;
|
||||
visitFunctionCall(ast: FunctionCall): any;
|
||||
visitImplicitReceiver(ast: ImplicitReceiver): any;
|
||||
@ -398,6 +413,8 @@ export class AstTransformer implements AstVisitor {
|
||||
visitChain(ast: Chain) { throw new BaseException('Not implemented'); }
|
||||
|
||||
visitAssignment(ast: Assignment) { throw new BaseException('Not implemented'); }
|
||||
|
||||
visitIf(ast: If) { throw new BaseException('Not implemented'); }
|
||||
}
|
||||
|
||||
var _evalListCache = [
|
||||
|
@ -59,6 +59,10 @@ export class Token {
|
||||
|
||||
isKeywordTrue(): boolean { return (this.type == TOKEN_TYPE_KEYWORD && this.strValue == "true"); }
|
||||
|
||||
isKeywordIf(): boolean { return (this.type == TOKEN_TYPE_KEYWORD && this.strValue == "if"); }
|
||||
|
||||
isKeywordElse(): boolean { return (this.type == TOKEN_TYPE_KEYWORD && this.strValue == "else"); }
|
||||
|
||||
isKeywordFalse(): boolean {
|
||||
return (this.type == TOKEN_TYPE_KEYWORD && this.strValue == "false");
|
||||
}
|
||||
@ -463,4 +467,5 @@ var OPERATORS = SetWrapper.createFromList([
|
||||
]);
|
||||
|
||||
|
||||
var KEYWORDS = SetWrapper.createFromList(['var', 'null', 'undefined', 'true', 'false']);
|
||||
var KEYWORDS =
|
||||
SetWrapper.createFromList(['var', 'null', 'undefined', 'true', 'false', 'if', 'else']);
|
||||
|
@ -33,6 +33,7 @@ import {
|
||||
Binary,
|
||||
PrefixNot,
|
||||
Conditional,
|
||||
If,
|
||||
Pipe,
|
||||
Assignment,
|
||||
Chain,
|
||||
@ -412,6 +413,19 @@ class _ParseAST {
|
||||
this.advance();
|
||||
return new LiteralPrimitive(false);
|
||||
|
||||
} else if (this.parseAction && this.next.isKeywordIf()) {
|
||||
this.advance();
|
||||
this.expectCharacter($LPAREN);
|
||||
let condition = this.parseExpression();
|
||||
this.expectCharacter($RPAREN);
|
||||
let ifExp = this.parseExpressionOrBlock();
|
||||
let elseExp;
|
||||
if (this.next.isKeywordElse()) {
|
||||
this.advance();
|
||||
elseExp = this.parseExpressionOrBlock();
|
||||
}
|
||||
return new If(condition, ifExp, elseExp)
|
||||
|
||||
} else if (this.optionalCharacter($LBRACKET)) {
|
||||
var elements = this.parseExpressionList($RBRACKET);
|
||||
this.expectCharacter($RBRACKET);
|
||||
@ -494,6 +508,37 @@ class _ParseAST {
|
||||
return positionals;
|
||||
}
|
||||
|
||||
parseExpressionOrBlock(): AST {
|
||||
if (this.optionalCharacter($LBRACE)) {
|
||||
let block = this.parseBlockContent();
|
||||
this.expectCharacter($RBRACE);
|
||||
return block;
|
||||
}
|
||||
|
||||
return this.parseExpression();
|
||||
}
|
||||
|
||||
parseBlockContent(): AST {
|
||||
if (!this.parseAction) {
|
||||
this.error("Binding expression cannot contain chained expression");
|
||||
}
|
||||
var exprs = [];
|
||||
while (this.index < this.tokens.length && !this.next.isCharacter($RBRACE)) {
|
||||
var expr = this.parseExpression();
|
||||
ListWrapper.push(exprs, expr);
|
||||
|
||||
if (this.optionalCharacter($SEMICOLON)) {
|
||||
while (this.optionalCharacter($SEMICOLON)) {
|
||||
} // read all semicolons
|
||||
}
|
||||
}
|
||||
if (exprs.length == 0) return new EmptyExpr();
|
||||
if (exprs.length == 1) return exprs[0];
|
||||
|
||||
return new Chain(exprs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An identifier, a keyword, a string with an optional `-` inbetween.
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
Binary,
|
||||
Chain,
|
||||
Conditional,
|
||||
If,
|
||||
Pipe,
|
||||
FunctionCall,
|
||||
ImplicitReceiver,
|
||||
@ -201,6 +202,8 @@ class _ConvertAstIntoProtoRecords implements AstVisitor {
|
||||
|
||||
visitChain(ast: Chain) { throw new BaseException('Not supported'); }
|
||||
|
||||
visitIf(ast: If) { throw new BaseException('Not supported'); }
|
||||
|
||||
_visitAll(asts: List<any>) {
|
||||
var res = ListWrapper.createFixedSize(asts.length);
|
||||
for (var i = 0; i < asts.length; ++i) {
|
||||
|
Reference in New Issue
Block a user