public override object invoke(Object obj) { return(RT.get(obj, this)); }
public override object invoke(Object obj, Object notFound) { return(RT.get(obj, this, notFound)); }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args, bool tailPosition) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; _tailPosition = tailPosition; VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null) { Var fvar = varFexpr.Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.ProtocolKeyword); if (pvar != null && Compiler.ProtocolCallsitesVar.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); IList <MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) { throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } _onMethod = (MethodInfo)methods[0]; } } } if (tag != null) { _tag = tag; } else if (varFexpr != null) { object arglists = RT.get(RT.meta(varFexpr.Var), Compiler.ArglistsKeyword); object sigTag = null; for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { APersistentVector sig = (APersistentVector)s.first(); int restOffset = sig.IndexOf(Compiler.AmpersandSym); if (args.count() == sig.count() || (restOffset > -1 && args.count() >= restOffset)) { sigTag = Compiler.TagOf(sig); break; } } _tag = sigTag ?? varFexpr.Tag; } else { _tag = null; } }
public static Expr Parse(ParserContext pcon, ISeq form, string name) { ISeq origForm = form; FnExpr fn = new FnExpr(Compiler.TagOf(form)); fn._src = form; if (((IMeta)form.first()).meta() != null) { fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); } fn.ComputeNames(form, name); List <string> prims = new List <string>(); //arglist might be preceded by symbol naming this fn Symbol nm = RT.second(form) as Symbol; if (nm != null) { fn._thisName = nm.Name; fn._isStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY)); form = RT.cons(Compiler.FnSym, RT.next(RT.next(form))); } // Normalize body //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...) //turn former into latter if (RT.second(form) is IPersistentVector) { form = RT.list(Compiler.FnSym, RT.next(form)); } fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); GenContext newContext = null; GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext; newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext)); try { try { Var.pushThreadBindings(RT.mapUniqueKeys( Compiler.ConstantsVar, PersistentVector.EMPTY, Compiler.ConstantIdsVar, new IdentityHashMap(), Compiler.KeywordsVar, PersistentHashMap.EMPTY, Compiler.VarsVar, PersistentHashMap.EMPTY, Compiler.KeywordCallsitesVar, PersistentVector.EMPTY, Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY, Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(), Compiler.NoRecurVar, null)); SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>(); FnMethod variadicMethod = null; for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), fn._isStatic); if (f.IsVariadic) { if (variadicMethod == null) { variadicMethod = f; } else { throw new ParseException("Can't have more than 1 variadic overload"); } } else if (!methods.ContainsKey(f.RequiredArity)) { methods[f.RequiredArity] = f; } else { throw new ParseException("Can't have 2 overloads with the same arity."); } if (f.Prim != null) { prims.Add(f.Prim); } } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) { throw new ParseException("Can't have fixed arity methods with more params than the variadic method."); } if (fn._isStatic && fn.Closes.count() > 0) { throw new ParseException("static fns can't be closures"); } IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) { allMethods = RT.conj(allMethods, method); } if (variadicMethod != null) { allMethods = RT.conj(allMethods, variadicMethod); } fn._methods = allMethods; fn._variadicMethod = variadicMethod; fn.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref(); fn.Vars = (IPersistentMap)Compiler.VarsVar.deref(); fn.Constants = (PersistentVector)Compiler.ConstantsVar.deref(); fn.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref(); fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref(); fn.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref(); fn._constantsID = RT.nextID(); } finally { Var.popThreadBindings(); } IPersistentMap fmeta = RT.meta(origForm); if (fmeta != null) { fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey); } fn._hasMeta = RT.count(fmeta) > 0; IPersistentVector primTypes = PersistentVector.EMPTY; foreach (string typename in prims) { primTypes = primTypes.cons(Type.GetType(typename)); } fn.Compile( fn.IsVariadic ? typeof(RestFn) : typeof(AFunction), null, primTypes, fn._onceOnly, newContext); if (fn.SupportsMeta) { return(new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta))); } else { return(fn); } } finally { if (newContext != null) { Var.popThreadBindings(); } } }
public static Expr Parse(ParserContext pcon, ISeq form) { bool tailPosition = Compiler.InTailCall(pcon.Rhc); pcon = pcon.EvalOrExpr(); Expr fexpr = Compiler.Analyze(pcon, form.first()); VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar) && RT.count(form) == 3) { Expr sexpr = Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form)); ConstantExpr csexpr = sexpr as ConstantExpr; if (csexpr != null) { Type tval = csexpr.Val as Type; if (tval != null) { return(new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), tval, Compiler.Analyze(pcon, RT.third(form)))); } } } if (varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { IPersistentVector sargs = (IPersistentVector)s.first(); if (sargs.count() == arity) { string primc = FnMethod.PrimInterface(sargs); if (primc != null) { return(Compiler.Analyze(pcon, ((IObj)RT.listStar(Symbol.intern(".invokePrim"), ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))), form.next())).withMeta((IPersistentMap)RT.conj(RT.meta(v), RT.meta(form))))); } break; } } } KeywordExpr kwFexpr = fexpr as KeywordExpr; if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound) { Expr target = Compiler.Analyze(pcon, RT.second(form)); return(new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target)); } IPersistentVector args = PersistentVector.EMPTY; for (ISeq s = RT.seq(form.next()); s != null; s = s.next()) { args = args.cons(Compiler.Analyze(pcon, s.first())); } //if (args.count() > Compiler.MAX_POSITIONAL_ARITY) // throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY)); return(new InvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form), Compiler.TagOf(form), fexpr, args, tailPosition)); }
/// <summary> /// (:keyword arg default) => (get arg :keyword default) /// </summary> /// <param name="arg1">The object to access.</param> /// <param name="arg2">Default value if not found.</param> /// <returns></returns> public override object invoke(object arg1, object arg2) { return(RT.get(arg1, this, arg2)); }
public static Expr Parse(object frm, string name) { ISeq form = (ISeq)frm; FnExpr fn = new FnExpr(Compiler.TagOf(form)); if (((IMeta)form.first()).meta() != null) { fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); fn._superName = (string)RT.get(RT.meta(form.first()), KW_SUPER_NAME); } fn.ComputeNames(form, name); try { Var.pushThreadBindings(RT.map( Compiler.CONSTANTS, PersistentVector.EMPTY, Compiler.KEYWORDS, PersistentHashMap.EMPTY, Compiler.VARS, PersistentHashMap.EMPTY)); //arglist might be preceded by symbol naming this fn if (RT.second(form) is Symbol) { fn._thisName = ((Symbol)RT.second(form)).Name; form = RT.cons(Compiler.FN, RT.next(RT.next(form))); } // Normalize body // If it is (fn [arg...] body ...), turn it into // (fn ([arg...] body...)) // so that we can treat uniformly as (fn ([arg...] body...) ([arg...] body...) ... ) if (RT.second(form) is IPersistentVector) { form = RT.list(Compiler.FN, RT.next(form)); } FnMethod variadicMethod = null; SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>(); for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s)); if (f.IsVariadic) { if (variadicMethod == null) { variadicMethod = f; } else { throw new Exception("Can't have more than 1 variadic overload"); } } else if (!methods.ContainsKey(f.RequiredArity)) { methods[f.RequiredArity] = f; } else { throw new Exception("Can't have 2 overloads with the same arity."); } } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) { throw new Exception("Can't have fixed arity methods with more params than the variadic method."); } IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) { allMethods = RT.conj(allMethods, method); } if (variadicMethod != null) { allMethods = RT.conj(allMethods, variadicMethod); } fn._methods = allMethods; fn._variadicMethod = variadicMethod; fn._keywords = (IPersistentMap)Compiler.KEYWORDS.deref(); fn._vars = (IPersistentMap)Compiler.VARS.deref(); fn._constants = (PersistentVector)Compiler.CONSTANTS.deref(); fn._constantsID = RT.nextID(); } finally { Var.popThreadBindings(); } // JAVA: fn.compile(); return(fn); }
public Expr Parse(ParserContext pcon, object form) { // (def x) or (def x initexpr) or (def x "docstring" initexpr) string docstring = null; if (RT.count(form) == 4 && (RT.third(form) is String)) { docstring = (String)RT.third(form); form = RT.list(RT.first(form), RT.second(form), RT.fourth(form)); } if (RT.count(form) > 3) { throw new ParseException("Too many arguments to def"); } if (RT.count(form) < 2) { throw new ParseException("Too few arguments to def"); } Symbol sym = RT.second(form) as Symbol; if (sym == null) { throw new ParseException("First argument to def must be a Symbol."); } //Console.WriteLine("Def {0}", sym.Name); Var v = Compiler.LookupVar(sym, true); if (v == null) { throw new ParseException("Can't refer to qualified var that doesn't exist"); } if (!v.Namespace.Equals(Compiler.CurrentNamespace)) { if (sym.Namespace == null) { v = Compiler.CurrentNamespace.intern(sym); } //throw new Exception(string.Format("Name conflict, can't def {0} because namespace: {1} refers to: {2}", // sym, Compiler.CurrentNamespace.Name, v)); else { throw new ParseException("Can't create defs outside of current namespace"); } } IPersistentMap mm = sym.meta(); bool isDynamic = RT.booleanCast(RT.get(mm, Compiler.DynamicKeyword)); if (isDynamic) { v.setDynamic(); } if (!isDynamic && sym.Name.StartsWith("*") && sym.Name.EndsWith("*") && sym.Name.Length > 1) { RT.errPrintWriter().WriteLine("Warning: {0} not declared dynamic and thus is not dynamically rebindable, " + "but its name suggests otherwise. Please either indicate ^:dynamic {0} or change the name. ({1}:{2}\n", sym, Compiler.SourcePathVar.get(), Compiler.LineVar.get()); } if (RT.booleanCast(RT.get(mm, Compiler.ArglistsKeyword))) { IPersistentMap vm = v.meta(); //vm = (IPersistentMap)RT.assoc(vm, Compiler.STATIC_KEY, true); // drop quote vm = (IPersistentMap)RT.assoc(vm, Compiler.ArglistsKeyword, RT.second(mm.valAt(Compiler.ArglistsKeyword))); v.setMeta(vm); } Object source_path = Compiler.SourcePathVar.get(); source_path = source_path ?? "NO_SOURCE_FILE"; mm = (IPersistentMap)RT.assoc(mm, RT.LineKey, Compiler.LineVar.get()) .assoc(RT.FileKey, source_path); //.assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref()); if (docstring != null) { mm = (IPersistentMap)RT.assoc(mm, RT.DocKey, docstring); } //mm = mm.without(RT.DOC_KEY) // .without(Keyword.intern(null, "arglists")) // .without(RT.FILE_KEY) // .without(RT.LINE_KEY) // .without(Keyword.intern(null, "ns")) // .without(Keyword.intern(null, "name")) // .without(Keyword.intern(null, "added")) // .without(Keyword.intern(null, "static")); mm = (IPersistentMap)Compiler.ElideMeta(mm); Expr meta = mm == null || mm.count() == 0 ? null : Compiler.Analyze(pcon.EvalOrExpr(), mm); Expr init = Compiler.Analyze(pcon.EvalOrExpr(), RT.third(form), v.Symbol.Name); bool initProvided = RT.count(form) == 3; return(new DefExpr( (string)Compiler.SourceVar.deref(), (int)Compiler.LineVar.deref(), v, init, meta, initProvided, isDynamic)); }
internal bool IsVolatile(LocalBinding lb) { return(RT.booleanCast(RT.contains(_fields, lb.Symbol)) && RT.booleanCast(RT.get(lb.Symbol.meta(), Keyword.intern("volatile-mutable")))); }