feat(parser): adds support for variable bindings

This commit is contained in:
vsavkin
2014-11-26 09:44:31 -08:00
parent a3d9f0fead
commit 1863d50978
7 changed files with 155 additions and 19 deletions

View File

@ -1,5 +1,6 @@
import {FIELD, autoConvertAdd, isBlank, isPresent, FunctionWrapper, BaseException} from "facade/lang";
import {List, Map, ListWrapper, MapWrapper} from "facade/collection";
import {ContextWithVariableBindings} from "./context_with_variable_bindings";
export class AST {
eval(context) {
@ -97,7 +98,16 @@ export class AccessMember extends AST {
}
eval(context) {
return this.getter(this.receiver.eval(context));
var evaluatedContext = this.receiver.eval(context);
while (evaluatedContext instanceof ContextWithVariableBindings) {
if (evaluatedContext.hasBinding(this.name)) {
return evaluatedContext.get(this.name);
}
evaluatedContext = evaluatedContext.parent;
}
return this.getter(evaluatedContext);
}
get isAssignable() {
@ -105,7 +115,16 @@ export class AccessMember extends AST {
}
assign(context, value) {
return this.setter(this.receiver.eval(context), value);
var evaluatedContext = this.receiver.eval(context);
while (evaluatedContext instanceof ContextWithVariableBindings) {
if (evaluatedContext.hasBinding(this.name)) {
throw new BaseException(`Cannot reassign a variable binding ${this.name}`)
}
evaluatedContext = evaluatedContext.parent;
}
return this.setter(evaluatedContext, value);
}
visit(visitor, args) {

View File

@ -0,0 +1,20 @@
import {MapWrapper} from 'facade/collection';
export class ContextWithVariableBindings {
parent:any;
/// varBindings are read-only. updating/adding keys is not supported.
varBindings:Map;
constructor(parent:any, varBindings:Map) {
this.parent = parent;
this.varBindings = varBindings;
}
hasBinding(name:string):boolean {
return MapWrapper.contains(this.varBindings, name);
}
get(name:string) {
return MapWrapper.get(this.varBindings, name);
}
}