internal override Node Bind(Binder b) { Symbol = b.Lookup(Name); if (Affinity != BindAffinity.Invoke && Affinity != BindAffinity.Type) { if (Symbol.IsMethodOrMethodGroup()) { // IdExpr can't be a method // TODO (nvk): If delegates are supprted this needs to be revised! Symbol = null; } else if (Symbol is TypeSymbol) { Symbol = null; } else if (Symbol is NamespaceSymbol) { Symbol = null; } else if (Symbol is SymbolList) { Symbol = Symbol.UniqueIdent(); } } if (Symbol == null && Affinity != BindAffinity.Type) { if (Affinity == BindAffinity.Alias) { return(LiteralExpr.Bound(Constant.Create(Name))); } else { switch (b.Options.UndeclaredVariableResolution) { case VariableResolution.Error: throw Error(ErrorCode.IdentifierNotFound, Name); case VariableResolution.GenerateLocal: Symbol = b.AddVariable(Name, Compilation.Get(NativeType.Usual)); break; case VariableResolution.TreatAsField: return(AliasExpr.Bound(Name)); case VariableResolution.TreatAsFieldOrMemvar: if (Affinity == BindAffinity.Assign) { b.CreatesAutoVars = true; } return(AutoVarExpr.Bound(Name)); } } } Datatype = Symbol.Type(); return(null); }
internal override Node Bind(Binder b) { // check for macro expression // When & is followed by a ( // then this is parsed a so called ParenExpression // We consider this to be a macro // unless it is prefixed by a ":" or a "->" token. // The & could be the first token in the macro // so check to make sure that there is a Prev token // There is Always a next token after the &, either an ID or a LPAREN bool macroCompile = false; TokenType prev = this.Token.Prev != null ? this.Token.Prev.Type : TokenType.WS; if (this.Token.Next.Type == TokenType.LPAREN && prev != TokenType.COLON && prev != TokenType.ALIAS) { Expr = new MacroExpr(Expr, this.Token); macroCompile = true; } b.Bind(ref Expr); Expr.RequireGetAccess(); if (macroCompile) { b.Convert(ref Expr, Compilation.Get(NativeType.Usual)); } else { b.Convert(ref Expr, Compilation.Get(NativeType.String)); } switch (Affinity) { case BindAffinity.AliasField: return(AliasExpr.Bound(Expr)); case BindAffinity.Member: return(Expr); case BindAffinity.Access when macroCompile: return(Expr); default: ThrowError(ErrorCode.InvalidRuntimeIdExpr); break; } return(null); }
internal override Node Bind(Binder b) { b.Bind(ref Expr); Expr.RequireGetAccess(); b.Convert(ref Expr, Compilation.Get(NativeType.String)); switch (Affinity) { case BindAffinity.AliasField: return(AliasExpr.Bound(Expr)); case BindAffinity.Member: return(Expr); default: ThrowError(ErrorCode.InvalidRuntimeIdExpr); break; } return(null); }
internal override Node Bind(Binder b) { b.Bind(ref Expr, BindAffinity.Type); var s = Expr.Symbol.UniqueTypeOrNamespace(); if (s is TypeSymbol t) { Expr.Symbol = t; Symbol = b.Lookup(t, Member.LookupName) ?? ThrowError(Binder.LookupError(Expr, this)); Datatype = Symbol.Type(); } else if (s is NamespaceSymbol ns) { Expr.Symbol = ns; Symbol = b.Lookup(ns, Member.LookupName) ?? ThrowError(Binder.LookupError(Expr, this)); Datatype = Symbol.Type(); } if (Symbol == null) { if (b.Options.AllowDotAccess) { if (b.Options.UndeclaredVariableResolution != VariableResolution.TreatAsField) { Expr.Symbol = null; // re-bind Expr -- this is a hack!!! b.Bind(ref Expr, Affinity); } if (Expr.Symbol.UniqueIdent() != null) { return(MemberAccessExpr.Bound(b, Expr, Member, Affinity)); } if (Expr is NameExpr aname && Member is NameExpr fname) { return(AliasExpr.Bound(aname.LookupName, fname.LookupName)); } Expr.RequireValue(); } else { Expr.RequireType(); } } return(null); }