public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { base.Analyze(scope, diagnostic); // Rewrite assignment to function call when assigned to array, e.g. array(index) = value => array.update(index, value) if (Left is RppSelector) { RppSelector selector = (RppSelector) Left; if (selector.Path.Name == "apply") { RppFuncCall applyFuncCall = selector.Path as RppFuncCall; if (applyFuncCall != null && applyFuncCall.Function.DeclaringType.Name == "Array") { RppSelector updateArray = new RppSelector(selector.Target, new RppFuncCall("update", new List<IRppExpr> {applyFuncCall.Args.First(), Right})); return updateArray.Analyze(scope, diagnostic); } } else if (selector.Path is RppFieldSelector) // Rewrite assignment to field as a call to setter of the field { RppFieldSelector fieldSelector = (RppFieldSelector) selector.Path; return CallSetter(selector.Target, fieldSelector.Field, Right).Analyze(scope, diagnostic); } } else if (Left is RppId) { RppId id = (RppId) Left; if (id.IsField && !id.IsFieldAccessedDirectly) { return CallSetter(new RppThis(), id.Field, Right).Analyze(scope, diagnostic); } } if (!Equals(Left.Type, Right.Type)) { if (!Left.Type.Value.IsAssignable(Right.Type.Value)) { throw SemanticExceptionFactory.TypeMismatch(Right.Token, Left.Type.Value.Name, Right.Type.Value.Name); } } return this; }
public override void Visit(RppSelector node) { node.Target.Accept(this); _inSelector = true; node.Path.Accept(this); _inSelector = false; }
public override void Visit(RppSelector node) { node.Target.Accept(this); node.Path.Accept(this); }
public virtual void Visit(RppSelector node) { }