Пример #1
0
            public Expr Parse(ParserContext pcon, object form)
            {
                int argCount = RT.count(form) - 1;
                if (argCount != 1)
                {
                    IPersistentMap exData = new PersistentArrayMap(new Object[] { FormKey, form });
                    throw new ExceptionInfo("Wrong number of args (" +
                                            argCount +
                                            ") passed to quote",
                                            exData);
                }

                object v = RT.second(form);
                if (v == null)
                    return Compiler.NilExprInstance;
                else if (v is Boolean)
                {
                    if ((bool)v)
                        return Compiler.TrueExprInstance;
                    else
                        return Compiler.FalseExprInstance;
                }
                else if (Util.IsNumeric(v))
                    return NumberExpr.Parse(v);
                else if (v is string)
                    return new StringExpr((String)v);
                else if (v is IPersistentCollection && ((IPersistentCollection)v).count() == 0)
                    return new EmptyExpr(v);
                else
                    return new ConstantExpr(v);
            }
Пример #2
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                // frm is: (deftype* tagname classname [fields] :implements [interfaces] :tag tagname methods*)

                ISeq rform = (ISeq)frm;
                rform = RT.next(rform);

                string tagname = ((Symbol)rform.first()).getName();
                rform = rform.next();
                Symbol classname = (Symbol)rform.first();
                rform = rform.next();
                IPersistentVector fields = (IPersistentVector)rform.first();
                rform = rform.next();
                IPersistentMap opts = PersistentHashMap.EMPTY;
                while (rform != null && rform.first() is Keyword)
                {
                    opts = opts.assoc(rform.first(), RT.second(rform));
                    rform = rform.next().next();
                }

                ObjExpr ret = Build((IPersistentVector)RT.get(opts, Compiler.ImplementsKeyword, PersistentVector.EMPTY), fields, null, tagname, classname,
                             (Symbol)RT.get(opts, RT.TagKey), rform, frm,opts);

                return ret;
            }
Пример #3
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keyvals = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr k = Compiler.Analyze(pconToUse, e.key());
                Expr v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (!(k is LiteralExpr && v is LiteralExpr))
                    constant = false;
            }
            Expr ret = new MapExpr(keyvals);

            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                // This 'optimzation' works, mostly, unless you have nested map values.
                // The nested map values do not participate in the constants map, so you end up with the code to create the keys.
                // Result: huge duplication of keyword creation.  3X increase in init time to the REPL.
                //IPersistentMap m = PersistentHashMap.EMPTY;
                //for (int i = 0; i < keyvals.length(); i += 2)
                //    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                //return new ConstantExpr(m);
                return ret;
            }
            else
                return ret;
        }
Пример #4
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                // frm is:  (reify this-name? [interfaces] (method-name [args] body)* )
                ISeq form = (ISeq)frm;
                ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref();
                string baseName = enclosingMethod != null
                    ? (ObjExpr.TrimGenId(enclosingMethod.Objx.Name) + "$")
                    : (Compiler.munge(Compiler.CurrentNamespace.Name.Name) + "$");
                string simpleName = "reify__" + RT.nextID();
                string className = baseName + simpleName;

                ISeq rform = RT.next(form);

                IPersistentVector interfaces = ((IPersistentVector)RT.first(rform)).cons(Symbol.intern("clojure.lang.IObj"));

                rform = RT.next(rform);

                ObjExpr ret = Build(interfaces, null, null, className, Symbol.intern(className), null, rform,frm, null);
                IObj iobj = frm as IObj;

                if (iobj != null && iobj.meta() != null)
                    return new MetaExpr(ret, MapExpr.Parse(pcon.EvalOrExpr(),iobj.meta()));
                else
                    return ret;
            }
Пример #5
0
        public static Expr Parse(ParserContext pcon, IPersistentVector form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector args = PersistentVector.EMPTY;
            for (int i = 0; i < form.count(); i++ )
            {
                Expr v = Compiler.Analyze(pconToUse, form.nth(i));
                args = (IPersistentVector)args.cons(v);
                if ( !(v is LiteralExpr) )
                    constant = false;
            }

            Expr ret = new VectorExpr(args);
            if ( form is IObj && ((IObj)form).meta() != null )
                return Compiler.OptionallyGenerateMetaInit(pcon,form, ret);
            else if ( constant )
            {
                IPersistentVector rv = PersistentVector.EMPTY;
                for ( int i=0; i<args.count(); i++ )
                {
                    LiteralExpr ve = (LiteralExpr)args.nth(i);
                    rv = (IPersistentVector)rv.cons(ve.Val);
                }
                return new ConstantExpr(rv);
            }
            else
                return ret;
        }
Пример #6
0
            public Expr Parse(ParserContext pcon, object form)
            {
                if (pcon.Rhc == RHC.Eval)
                    return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)), "throw__" + RT.nextID());

                return new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form)));
            }
Пример #7
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keyvals = PersistentVector.EMPTY;
            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr k = Compiler.Analyze(pconToUse, e.key());
                Expr v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (!(k is LiteralExpr && v is LiteralExpr))
                    constant = false;
            }
            Expr ret = new MapExpr(keyvals);
            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                IPersistentMap m = PersistentHashMap.EMPTY;
                for (int i = 0; i < keyvals.length(); i += 2)
                    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                return new ConstantExpr(m);
            }
            else
                return ret;
        }
Пример #8
0
        public static Expr Parse(ParserContext pcon, IPersistentSet form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keys = PersistentVector.EMPTY;
            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                object e = s.first();
                Expr expr = Compiler.Analyze(pconToUse, e);
                keys = (IPersistentVector)keys.cons(expr);
                if (!(expr is LiteralExpr))
                    constant = false;
            }
            Expr ret = new SetExpr(keys);
            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                IPersistentSet set = PersistentHashSet.EMPTY;
                for (int i = 0; i < keys.count(); i++)
                {
                    LiteralExpr ve = (LiteralExpr)keys.nth(i);
                    set = (IPersistentSet)set.cons(ve.Val);
                }
                return new ConstantExpr(set);
            }
            else
                return ret;
        }
Пример #9
0
 public Expr Parse(ParserContext pcon, object form)
 {
     Symbol sym = (Symbol)RT.second(form);
     Var v = Compiler.LookupVar(sym, false);
     if (v != null)
         return new TheVarExpr(v);
     throw new ParseException(string.Format("Unable to resolve var: {0} in this context", sym));
 }
Пример #10
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                string source = (string)Compiler.SourceVar.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();  // Compiler.GetSourceSpanMap(form);
                
                ISeq form = (ISeq)frm;

                IPersistentVector loopLocals = (IPersistentVector)Compiler.LoopLocalsVar.deref();

                if (pcon.Rhc != RHC.Return || loopLocals == null)
                    throw new ParseException("Can only recur from tail position");

                if (Compiler.NoRecurVar.deref() != null)
                    throw new ParseException("Cannot recur across try");

                IPersistentVector args = PersistentVector.EMPTY;

                for (ISeq s = RT.seq(form.next()); s != null; s = s.next())
                    args = args.cons(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), s.first()));
                if (args.count() != loopLocals.count())
                    throw new ParseException(string.Format("Mismatched argument count to recur, expected: {0} args, got {1}",
                        loopLocals.count(), args.count()));

                for (int i = 0; i < loopLocals.count(); i++)
                {
                    LocalBinding lb = (LocalBinding)loopLocals.nth(i);
                    Type primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        bool mismatch = false;
                        Type pt = Compiler.MaybePrimitiveType((Expr)args.nth(i));
                        if (primt == typeof(long))
                        {
                            if (!(pt == typeof(long) || pt == typeof(int) || pt == typeof(short) || pt == typeof(uint) || pt == typeof(ushort) || pt == typeof(ulong)
                                || pt == typeof(char) || pt == typeof(byte) || pt == typeof(sbyte)))
                                mismatch = true;
                        }
                        else if (primt == typeof(double))
                        {
                            if (!(pt == typeof(double) || pt == typeof(float)))
                                mismatch = true;
                        }

                        if (mismatch)
                        {
                            lb.RecurMismatch = true;
                            if (RT.booleanCast(RT.WarnOnReflectionVar.deref()))
                                RT.errPrintWriter().WriteLine("{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                    source, spanMap != null ? (int)spanMap.valAt(RT.StartLineKey, 0) : 0,
                                    lb.Name, pt != null ? pt.Name : "Object", primt.Name);
                        }
                    }
                }

 
                return new RecurExpr(source, spanMap, loopLocals, args);
            }
Пример #11
0
 public Expr Parse(ParserContext pcon, object frm)
 {
     ISeq form = (ISeq)frm;
     if (RT.Length(form) != 3)
         throw new ArgumentException("Malformed assignment, expecting (set! target val)");
     Expr target = Compiler.Analyze(new ParserContext(RHC.Expression, true), RT.second(form));
     if (!(target is AssignableExpr))
         throw new ArgumentException("Invalid assignment target");
     return new AssignExpr((AssignableExpr)target,
         Compiler.Analyze(pcon.SetRhc(RHC.Expression),RT.third(form)));
 }
Пример #12
0
            public Expr Parse(ParserContext pcon, object form)
            {
                if (pcon.Rhc == RHC.Eval)
                    return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "throw__" + RT.nextID());

                if (RT.Length((ISeq)form) == 1)
                    return new ThrowExpr();

                if (RT.count(form) > 2)
                    throw new InvalidOperationException("Too many arguments to throw, throw expects a single Exception instance");

                return new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form)));
            }
Пример #13
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // (if test then) or (if test then else)

                if (form.count() > 4)
                    throw new ParseException("Too many arguments to if");

                if (form.count() < 3)
                    throw new ParseException("Too few arguments to if");


                Expr testExpr = Compiler.Analyze(pcon.EvalOrExpr().SetAssign(false),RT.second(form));
                Expr thenExpr = Compiler.Analyze(pcon.SetAssign(false), RT.third(form));
                Expr elseExpr = Compiler.Analyze(pcon.SetAssign(false), RT.fourth(form));

                return new IfExpr((IPersistentMap)Compiler.SourceSpanVar.deref(), testExpr, thenExpr, elseExpr);
            }
Пример #14
0
            public Expr Parse(ParserContext pcon, object frms)
            {
                ISeq forms = (ISeq)frms;

                if (Util.equals(RT.first(forms), Compiler.DoSym))
                    forms = RT.next(forms);

                IPersistentVector exprs = PersistentVector.EMPTY;

                for (; forms != null; forms = forms.next())
                {
                    Expr e = (pcon.Rhc != RHC.Eval && (pcon.Rhc == RHC.Statement || forms.next() != null))
                        ? Compiler.Analyze(pcon.SetRhc(RHC.Statement), forms.first())
                        : Compiler.Analyze(pcon, forms.first());
                    exprs = exprs.cons(e);
                }
                if (exprs.count() == 0)
                    exprs = exprs.cons(Compiler.NilExprInstance);

                return new BodyExpr(exprs);
            }
Пример #15
0
        private static void Compile1(TypeBuilder tb, CljILGen ilg,  ObjExpr objx, object form)
        {
            object line = LineVarDeref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.LineKey))
                line = RT.meta(form).valAt(RT.LineKey);
            object column = ColumnVarDeref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.ColumnKey))
                column = RT.meta(form).valAt(RT.ColumnKey);
            IPersistentMap sourceSpan = (IPersistentMap)SourceSpanVar.deref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.SourceSpanKey))
                sourceSpan = (IPersistentMap)RT.meta(form).valAt(RT.SourceSpanKey);

            ParserContext evPC = new ParserContext(RHC.Eval);

            Var.pushThreadBindings(RT.map(LineVar, line, ColumnVar, column, SourceSpanVar, sourceSpan));

            try
            {
                form = Macroexpand(form);
                if (form is ISeq && Util.Equals(RT.first(form), DoSym))
                {
                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                        Compile1(tb, ilg, objx, RT.first(s));
                }
                else
                {
                    Expr expr = Analyze(evPC, form);
                    objx.Keywords = (IPersistentMap)KeywordsVar.deref();
                    objx.Vars = (IPersistentMap)VarsVar.deref();
                    objx.Constants = (PersistentVector)ConstantsVar.deref();
                    objx.EmitConstantFieldDefs(tb);
                    expr.Emit(RHC.Expression,objx,ilg);
                    ilg.Emit(OpCodes.Pop);
                    expr.Eval();
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Пример #16
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (letfn*  [var1 (fn [args] body) ... ] body ... )

                IPersistentVector bindings = RT.second(form) as IPersistentVector;

                if (bindings == null)
                {
                    throw new ParseException("Bad binding form, expected vector");
                }

                if ((bindings.count() % 2) != 0)
                {
                    throw new ParseException("Bad binding form, expected matched symbol/expression pairs.");
                }

                ISeq body = RT.next(RT.next(form));

                if (pcon.Rhc == RHC.Eval)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnSym, PersistentVector.EMPTY, form)), "letfn__" + RT.nextID()));
                }

                IPersistentMap dynamicBindings = RT.map(
                    Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                    Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref());

                try
                {
                    Var.pushThreadBindings(dynamicBindings);

                    // pre-seed env (like Lisp labels)
                    IPersistentVector lbs = PersistentVector.EMPTY;
                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        if (!(bindings.nth(i) is Symbol))
                        {
                            throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i));
                        }

                        Symbol sym = (Symbol)bindings.nth(i);
                        if (sym.Namespace != null)
                        {
                            throw new ParseException("Can't let qualified name: " + sym);
                        }

                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null, false);
                        // b.CanBeCleared = false;
                        lbs = lbs.cons(b);
                    }

                    IPersistentVector bindingInits = PersistentVector.EMPTY;
                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        Symbol       sym  = (Symbol)bindings.nth(i);
                        Expr         init = Compiler.Analyze(pcon.SetRhc(RHC.Expression), bindings.nth(i + 1));
                        LocalBinding b    = (LocalBinding)lbs.nth(i / 2);
                        b.Init = init;
                        BindingInit bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);
                    }

                    return(new LetFnExpr(bindingInits, new BodyExpr.Parser().Parse(pcon, body)));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Пример #17
0
        private static Expr AnalyzeSeq(ParserContext pcon, ISeq form, string name )
        {
            object line = LineVarDeref();
            object column = ColumnVarDeref();
            IPersistentMap sourceSpan = (IPersistentMap)SourceSpanVar.deref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.LineKey))
                line = RT.meta(form).valAt(RT.LineKey);
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.ColumnKey))
                column = RT.meta(form).valAt(RT.ColumnKey);
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.SourceSpanKey))
                sourceSpan = (IPersistentMap)RT.meta(form).valAt(RT.SourceSpanKey);

            Var.pushThreadBindings(RT.map(LineVar, line, ColumnVar, column, SourceSpanVar, sourceSpan));

            try
            {

                object me = MacroexpandSeq1(form);
                if (me != form)
                    return Analyze(pcon, me, name);

                object op = RT.first(form);
                if (op == null)
                    throw new ArgumentNullException("form","Can't call nil");

                IFn inline = IsInline(op, RT.count(RT.next(form)));

                if (inline != null)
                    return Analyze(pcon, MaybeTransferSourceInfo(PreserveTag(form, inline.applyTo(RT.next(form))), form));

                IParser p;
                if (op.Equals(FnSym))
                    return FnExpr.Parse(pcon, form, name);
                if ((p = GetSpecialFormParser(op)) != null)
                    return p.Parse(pcon, form);
                else
                    return InvokeExpr.Parse(pcon, form);
            }
            catch (CompilerException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new CompilerException((String)SourcePathVar.deref(), LineVarDeref(), ColumnVarDeref(), e);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Пример #18
0
            //(case* expr shift mask  default map<minhash, [test then]> table-type test-type skip-check?)
            //prepared by case macro and presumed correct
            //case macro binds actual expr in let so expr is always a local,
            //no need to worry about multiple evaluation
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                if (pcon.Rhc == RHC.Eval)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnSym, PersistentVector.EMPTY, form)), "case__" + RT.nextID()));
                }

                PersistentVector args = PersistentVector.create(form.next());

                object         exprForm    = args.nth(0);
                int            shift       = Util.ConvertToInt(args.nth(1));
                int            mask        = Util.ConvertToInt(args.nth(2));
                object         defaultForm = args.nth(3);
                IPersistentMap caseMap     = (IPersistentMap)args.nth(4);
                Keyword        switchType  = (Keyword)args.nth(5);
                Keyword        testType    = (Keyword)args.nth(6);
                IPersistentSet skipCheck   = RT.count(args) < 8 ? null : (IPersistentSet)args.nth(7);

                ISeq             keys     = RT.keys(caseMap);
                int              low      = Util.ConvertToInt(RT.first(keys));
                int              high     = Util.ConvertToInt(RT.nth(keys, RT.count(keys) - 1));
                LocalBindingExpr testexpr = (LocalBindingExpr)Compiler.Analyze(pcon.SetRhc(RHC.Expression), exprForm);


                SortedDictionary <int, Expr> tests = new SortedDictionary <int, Expr>();
                Dictionary <int, Expr>       thens = new Dictionary <int, Expr>();

                foreach (IMapEntry me in caseMap)
                {
                    int    minhash  = Util.ConvertToInt(me.key());
                    object pair     = me.val(); // [test-val then-expr]
                    object first    = RT.first(pair);
                    Expr   testExpr = testType == _intKey
                        ? NumberExpr.Parse(Util.ConvertToInt(first))
                        : (first == null ? Compiler.NilExprInstance : new ConstantExpr(first));

                    tests[minhash] = testExpr;
                    Expr thenExpr;
                    thenExpr       = Compiler.Analyze(pcon, RT.second(pair));
                    thens[minhash] = thenExpr;
                }

                Expr defaultExpr;

                defaultExpr = Compiler.Analyze(pcon, defaultForm);

                return(new CaseExpr(
                           (IPersistentMap)Compiler.SourceSpanVar.deref(),
                           testexpr,
                           shift,
                           mask,
                           low,
                           high,
                           defaultExpr,
                           tests,
                           thens,
                           switchType,
                           testType,
                           skipCheck));
            }
Пример #19
0
            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);
                        Compiler.RegisterVar(v);
                    }

                    //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 > 2)
                {
                    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.ColumnKey,Compiler.ColumnVar.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);

                //  Following comment in JVM version
                //mm = mm.without(RT.DOC_KEY)
                //            .without(Keyword.intern(null, "arglists"))
                //            .without(RT.FILE_KEY)
                //            .without(RT.LINE_KEY)
                //            .without(RT.COLUMN_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(),
                    Compiler.LineVarDeref(),
                    Compiler.ColumnVarDeref(),
                    v, init, meta, initProvided,isDynamic);
            }
Пример #20
0
        internal static List<HostArg> ParseArgs(ParserContext pcon, ISeq argSeq)
        {
            List<HostArg> args = new List<HostArg>();

            for (ISeq s = argSeq; s != null; s = s.next())
            {
                object arg = s.first();

                HostArg.ParameterType paramType = HostArg.ParameterType.Standard;
                LocalBinding lb = null;

                if (arg is ISeq)
                {
                    Symbol op = RT.first(arg) as Symbol;
                    if (op != null && op.Equals(BY_REF))
                    {
                        if (RT.Length((ISeq)arg) != 2)
                            throw new ArgumentException("Wrong number of arguments to {0}", ((Symbol)op).Name);

                        object localArg = RT.second(arg);
                        if (!(localArg is Symbol) || (lb = Compiler.ReferenceLocal((Symbol)localArg)) == null)
                            throw new ArgumentException("Argument to {0} must be a local variable.", ((Symbol)op).Name);

                        paramType = HostArg.ParameterType.ByRef;

                        arg = localArg;
                    }
                }

                Expr expr = Compiler.Analyze(pcon.EvEx(),arg);

                args.Add(new HostArg(paramType, expr, lb));
            }

            return args;
        }
Пример #21
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (letfn*  [var1 (fn [args] body) ... ] body ... )

                IPersistentVector bindings = RT.second(form) as IPersistentVector;

                if (bindings == null)
                    throw new ParseException("Bad binding form, expected vector");

                if ((bindings.count() % 2) != 0)
                    throw new ParseException("Bad binding form, expected matched symbol/expression pairs.");

                ISeq body = RT.next(RT.next(form));

                if (pcon.Rhc == RHC.Eval)
                    return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "letfn__" + RT.nextID());

                IPersistentMap dynamicBindings = RT.map(
                    Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                    Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref());

                try
                {
                    Var.pushThreadBindings(dynamicBindings);

                    // pre-seed env (like Lisp labels)
                    IPersistentVector lbs = PersistentVector.EMPTY;
                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        if (!(bindings.nth(i) is Symbol))
                            throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i));

                        Symbol sym = (Symbol)bindings.nth(i);
                        if (sym.Namespace != null)
                            throw new ParseException("Can't let qualified name: " + sym);

                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null, typeof(Object), false);
                        // b.CanBeCleared = false;
                        lbs = lbs.cons(b);
                    }

                    IPersistentVector bindingInits = PersistentVector.EMPTY;
                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        Symbol sym = (Symbol)bindings.nth(i);
                        Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression),bindings.nth(i + 1),sym.Name);
                        LocalBinding b = (LocalBinding)lbs.nth(i / 2);
                        b.Init = init;
                        BindingInit bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);
                    }

                    return new LetFnExpr(bindingInits,new BodyExpr.Parser().Parse(pcon, body));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Пример #22
0
 public static Expr Analyze(ParserContext pcontext, object form)
 {
     return Analyze(pcontext, form, null);
 }
Пример #23
0
        public static object eval(object form)
        {
            object line = LineVarDeref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.LineKey))
                line = RT.meta(form).valAt(RT.LineKey);
            object column = ColumnVarDeref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.ColumnKey))
                column = RT.meta(form).valAt(RT.ColumnKey);
            IPersistentMap sourceSpan = (IPersistentMap)SourceSpanVar.deref();
            if (RT.meta(form) != null && RT.meta(form).containsKey(RT.SourceSpanKey))
                sourceSpan = (IPersistentMap)RT.meta(form).valAt(RT.SourceSpanKey);

            ParserContext pconExpr = new ParserContext(RHC.Expression);
            ParserContext pconEval = new ParserContext(RHC.Eval);

            Var.pushThreadBindings(RT.map(LineVar, line, ColumnVar, column, SourceSpanVar, sourceSpan, CompilerContextVar, null));
            try
            {
                form = Macroexpand(form);

                if (form is ISeq && Util.equals(RT.first(form), DoSym))
                {
                    ISeq s = RT.next(form);
                    for (; RT.next(s) != null; s = RT.next(s))
                        eval(RT.first(s));
                    return eval(RT.first(s));
                }
                else if ( (form is IType) ||
                    (form is IPersistentCollection && !(RT.first(form) is Symbol && ((Symbol)RT.first(form)).Name.StartsWith("def"))))
                {
                    ObjExpr objx = (ObjExpr)Analyze(pconExpr, RT.list(FnSym, PersistentVector.EMPTY, form), "eval__" + RT.nextID());
                    IFn fn = (IFn)objx.Eval();
                    return fn.invoke();
                }
                else
                {
                    Expr expr = Analyze(pconEval, form);
                    return expr.Eval();

                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Пример #24
0
        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));
        }
Пример #25
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (let  [var1 val1 var2 val2 ... ] body ... )
                //      or (loop [var1 val1 var2 val2 ... ] body ... )

                bool isLoop = RT.first(form).Equals(Compiler.LoopSym);

                IPersistentVector bindings = RT.second(form) as IPersistentVector;

                if (bindings == null)
                {
                    throw new ParseException("Bad binding form, expected vector");
                }

                if ((bindings.count() % 2) != 0)
                {
                    throw new ParseException("Bad binding form, expected matched symbol/value pairs.");
                }

                ISeq body = RT.next(RT.next(form));

                if (pcon.Rhc == RHC.Eval ||
                    (pcon.Rhc == RHC.Expression && isLoop))
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "let__" + RT.nextID()));
                }

                ObjMethod      method                  = (ObjMethod)Compiler.MethodVar.deref();
                IPersistentMap backupMethodLocals      = method.Locals;
                IPersistentMap backupMethodIndexLocals = method.IndexLocals;

                IPersistentVector recurMismatches = PersistentVector.EMPTY;

                for (int i = 0; i < bindings.count() / 2; i++)
                {
                    recurMismatches = recurMismatches.cons(false);
                }

                // may repeat once for each binding with a mismatch, return breaks
                while (true)
                {
                    IPersistentMap dynamicBindings = RT.map(
                        Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                        Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref());
                    method.SetLocals(backupMethodLocals, backupMethodIndexLocals);

                    if (isLoop)
                    {
                        dynamicBindings = dynamicBindings.assoc(Compiler.LoopLocalsVar, null);
                    }

                    try
                    {
                        Var.pushThreadBindings(dynamicBindings);

                        IPersistentVector bindingInits = PersistentVector.EMPTY;
                        IPersistentVector loopLocals   = PersistentVector.EMPTY;

                        for (int i = 0; i < bindings.count(); i += 2)
                        {
                            if (!(bindings.nth(i) is Symbol))
                            {
                                throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i));
                            }

                            Symbol sym = (Symbol)bindings.nth(i);
                            if (sym.Namespace != null)
                            {
                                throw new ParseException("Can't let qualified name: " + sym);
                            }

                            Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), bindings.nth(i + 1), sym.Name);
                            if (isLoop)
                            {
                                if (recurMismatches != null && RT.booleanCast(recurMismatches.nth(i / 2)))
                                {
                                    HostArg        ha  = new HostArg(HostArg.ParameterType.Standard, init, null);
                                    List <HostArg> has = new List <HostArg>(1);
                                    has.Add(ha);
                                    init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "box", null, has, false);
                                    if (RT.booleanCast(RT.WarnOnReflectionVar.deref()))
                                    {
                                        RT.errPrintWriter().WriteLine("Auto-boxing loop arg: " + sym);
                                    }
                                }
                                else if (Compiler.MaybePrimitiveType(init) == typeof(int))
                                {
                                    List <HostArg> args = new List <HostArg>();
                                    args.Add(new HostArg(HostArg.ParameterType.Standard, init, null));
                                    init = new StaticMethodExpr("", null, null, typeof(RT), "longCast", null, args, false);
                                }
                                else if (Compiler.MaybePrimitiveType(init) == typeof(float))
                                {
                                    List <HostArg> args = new List <HostArg>();
                                    args.Add(new HostArg(HostArg.ParameterType.Standard, init, null));
                                    init = new StaticMethodExpr("", null, null, typeof(RT), "doubleCast", null, args, false);
                                }
                            }

                            // Sequential enhancement of env (like Lisp let*)
                            LocalBinding b  = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init, false);
                            BindingInit  bi = new BindingInit(b, init);
                            bindingInits = bindingInits.cons(bi);

                            if (isLoop)
                            {
                                loopLocals = loopLocals.cons(b);
                            }
                        }
                        if (isLoop)
                        {
                            Compiler.LoopLocalsVar.set(loopLocals);
                        }

                        Expr bodyExpr;
                        bool moreMismatches = false;
                        try
                        {
                            if (isLoop)
                            {
                                // stuff with clear paths,
                                Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, null));
                            }
                            bodyExpr = new BodyExpr.Parser().Parse(isLoop ? pcon.SetRhc(RHC.Return) : pcon, body);
                        }
                        finally
                        {
                            if (isLoop)
                            {
                                Var.popThreadBindings();

                                for (int i = 0; i < loopLocals.count(); i++)
                                {
                                    LocalBinding lb = (LocalBinding)loopLocals.nth(i);
                                    if (lb.RecurMismatch)
                                    {
                                        recurMismatches = (IPersistentVector)recurMismatches.assoc(i, true);
                                        moreMismatches  = true;
                                    }
                                }
                            }
                        }

                        if (!moreMismatches)
                        {
                            return(new LetExpr(bindingInits, bodyExpr, isLoop));
                        }
                    }
                    finally
                    {
                        Var.popThreadBindings();
                    }
                }
            }
Пример #26
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));

            fn.Src = form;

            Keyword   retKey          = Keyword.intern(null, "rettag"); // TODO: make static
            object    retTag          = RT.get(RT.meta(form), retKey);
            ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref();

            fn._hasEnclosingMethod = enclosingMethod != null;


            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;
                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;
                    bool     usesThis       = false;

                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                    {
                        FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), retTag);
                        if (f.UsesThis)
                        {
                            //Console.WriteLine("{0} uses this",fn.Name);
                            usesThis = true;
                        }
                        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.");
                    }

                    fn.CanBeDirect = !fn._hasEnclosingMethod && fn.Closes.count() == 0 && !usesThis;

                    IPersistentCollection allMethods = null;
                    foreach (FnMethod method in methods.Values)
                    {
                        allMethods = RT.conj(allMethods, method);
                    }
                    if (variadicMethod != null)
                    {
                        allMethods = RT.conj(allMethods, variadicMethod);
                    }

                    if (fn.CanBeDirect)
                    {
                        for (ISeq s = RT.seq(allMethods); s != null; s = s.next())
                        {
                            FnMethod fm = s.first() as FnMethod;
                            if (fm.Locals != null)
                            {
                                for (ISeq sl = RT.seq(RT.keys(fm.Locals)); sl != null; sl = sl.next())
                                {
                                    LocalBinding lb = sl.first() as LocalBinding;
                                    if (lb.IsArg)
                                    {
                                        lb.Index -= 1;
                                    }
                                }
                            }
                        }
                    }

                    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).without(retKey);
                }
                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();
                }
            }
        }
Пример #27
0
            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));
            }
Пример #28
0
 public Expr Parse(ParserContext pcon, object frm)
 {
     return(new ImportExpr((string)RT.second(frm)));
 }
Пример #29
0
        public static Expr Analyze(ParserContext pcontext, object form, string name)
        {
            try
            {
                if (form is LazySeq)
                {
                    form = RT.seq(form);
                    if (form == null)
                        form = PersistentList.EMPTY;
                }
                if (form == null)
                    return NilExprInstance;
                else if (form is Boolean)
                    return ((bool)form) ? TrueExprInstance : FalseExprInstance;

                Type type = form.GetType();

                if (type == typeof(Symbol))
                    return AnalyzeSymbol((Symbol)form);
                else if (type == typeof(Keyword))
                    return RegisterKeyword((Keyword)form);
                else if (Util.IsNumeric(form))
                    return NumberExpr.Parse(form);
                else if (type == typeof(String))
                    return new StringExpr(String.Intern((String)form));
                else if (form is IPersistentCollection && ((IPersistentCollection)form).count() == 0)
                    return OptionallyGenerateMetaInit(pcontext, form, new EmptyExpr(form));
                else if (form is ISeq)
                    return AnalyzeSeq(pcontext, (ISeq)form, name);
                else if (form is IPersistentVector)
                    return VectorExpr.Parse(pcontext, (IPersistentVector)form);
                else if (form is IRecord)
                    return new ConstantExpr(form);
                else if (form is IType)
                    return new ConstantExpr(form);
                else if (form is IPersistentMap)
                    return MapExpr.Parse(pcontext, (IPersistentMap)form);
                else if (form is IPersistentSet)
                    return SetExpr.Parse(pcontext, (IPersistentSet)form);
                else
                    return new ConstantExpr(form);
            }
            catch (CompilerException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new CompilerException((String)SourcePathVar.deref(), LineVarDeref(), ColumnVarDeref(), e);
            }
        }
Пример #30
0
 public Expr Parse(ParserContext pcon, object form)
 {
     return(new MonitorEnterExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form))));
 }
Пример #31
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                string         source  = (string)Compiler.SourceVar.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();  // Compiler.GetSourceSpanMap(form);

                ISeq form = (ISeq)frm;

                IPersistentVector loopLocals = (IPersistentVector)Compiler.LoopLocalsVar.deref();

                if (pcon.Rhc != RHC.Return || loopLocals == null)
                {
                    throw new ParseException("Can only recur from tail position");
                }

                if (Compiler.NoRecurVar.deref() != null)
                {
                    throw new ParseException("Cannot recur across try");
                }

                IPersistentVector args = PersistentVector.EMPTY;

                for (ISeq s = RT.seq(form.next()); s != null; s = s.next())
                {
                    args = args.cons(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), s.first()));
                }
                if (args.count() != loopLocals.count())
                {
                    throw new ParseException(string.Format("Mismatched argument count to recur, expected: {0} args, got {1}",
                                                           loopLocals.count(), args.count()));
                }

                for (int i = 0; i < loopLocals.count(); i++)
                {
                    LocalBinding lb    = (LocalBinding)loopLocals.nth(i);
                    Type         primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        bool mismatch = false;
                        Type pt       = Compiler.MaybePrimitiveType((Expr)args.nth(i));
                        if (primt == typeof(long))
                        {
                            if (!(pt == typeof(long) || pt == typeof(int) || pt == typeof(short) || pt == typeof(uint) || pt == typeof(ushort) || pt == typeof(ulong) ||
                                  pt == typeof(char) || pt == typeof(byte) || pt == typeof(sbyte)))
                            {
                                mismatch = true;
                            }
                        }
                        else if (primt == typeof(double))
                        {
                            if (!(pt == typeof(double) || pt == typeof(float)))
                            {
                                mismatch = true;
                            }
                        }

                        if (mismatch)
                        {
                            lb.RecurMismatch = true;
                            if (RT.booleanCast(RT.WarnOnReflectionVar.deref()))
                            {
                                RT.errPrintWriter().WriteLine("{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                                              source, spanMap != null ? (int)spanMap.valAt(RT.StartLineKey, 0) : 0,
                                                              lb.Name, pt != null ? pt.Name : "Object", primt.Name);
                            }
                        }
                    }
                }


                return(new RecurExpr(source, spanMap, loopLocals, args));
            }
Пример #32
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                if (pcon.Rhc != RHC.Return)
                    return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)), "try__" + RT.nextID());

                // (try try-expr* catch-expr* finally-expr?)
                // catch-expr: (catch class sym expr*)
                // finally-expr: (finally expr*)

                IPersistentVector body = PersistentVector.EMPTY;
                IPersistentVector catches = PersistentVector.EMPTY;
                Expr bodyExpr = null;
                Expr finallyExpr = null;
                bool caught = false;

                int retLocal = Compiler.GetAndIncLocalNum();
                int finallyLocal = Compiler.GetAndIncLocalNum();

                for (ISeq fs = form.next(); fs != null; fs = fs.next())
                {
                    object f = fs.first();
                    object op = (f is ISeq) ? ((ISeq)f).first() : null;
                    if (!Util.equals(op, Compiler.CATCH) && !Util.equals(op, Compiler.FINALLY))
                    {
                        if (caught)
                            throw new Exception("Only catch or finally clause can follow catch in try expression");
                        body = body.cons(f);
                    }
                    else
                    {
                        if (bodyExpr == null)
                            bodyExpr = new BodyExpr.Parser().Parse(pcon.SetAssign(false),RT.seq(body));
                        if (Util.equals(op, Compiler.CATCH))
                        {
                            Type t = HostExpr.MaybeType(RT.second(f), false);
                            if (t == null)
                                throw new ArgumentException("Unable to resolve classname: " + RT.second(f));
                            if (!(RT.third(f) is Symbol))
                                throw new ArgumentException("Bad binding form, expected symbol, got: " + RT.third(f));
                            Symbol sym = (Symbol)RT.third(f);
                            if (sym.Namespace != null)
                                throw new Exception("Can't bind qualified name: " + sym);

                            IPersistentMap dynamicBindings = RT.map(
                                Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(),
                                Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref(),
                                Compiler.IN_CATCH_FINALLY, true);

                            try
                            {
                                Var.pushThreadBindings(dynamicBindings);
                                LocalBinding lb = Compiler.RegisterLocal(sym,
                                    (Symbol)(RT.second(f) is Symbol ? RT.second(f) : null),
                                    null,false);
                                Expr handler = (new BodyExpr.Parser()).Parse(pcon.SetAssign(false), RT.next(RT.next(RT.next(f))));
                                catches = catches.cons(new CatchClause(t, lb, handler)); ;
                            }
                            finally
                            {
                                Var.popThreadBindings();
                            }
                            caught = true;
                        }
                        else // finally
                        {
                            if (fs.next() != null)
                                throw new Exception("finally clause must be last in try expression");
                            try
                            {
                                //Var.pushThreadBindings(RT.map(Compiler.IN_CATCH_FINALLY, RT.T));
                                Var.pushThreadBindings(RT.map(Compiler.IN_CATCH_FINALLY, true));
                                finallyExpr = (new BodyExpr.Parser()).Parse(pcon.SetRhc(RHC.Statement).SetAssign(false), RT.next(f));
                            }
                            finally
                            {
                                Var.popThreadBindings();
                            }
                        }
                    }
                }

                if ( bodyExpr == null )
                    bodyExpr = (new BodyExpr.Parser()).Parse(pcon, RT.seq(body));
                return new TryExpr(bodyExpr, catches, finallyExpr, retLocal, finallyLocal);
            }
Пример #33
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form is one of:
                //  (. x fieldname-sym)
                //  (. x 0-ary-method)
                //  (. x propertyname-sym)
                //  (. x methodname-sym args)+
                //  (. x (methodname-sym args?))
                //  (. x (generic-m

                if (RT.Length(form) < 3)
                    throw new ArgumentException("Malformed member expression, expecting (. target member ... )");

                string source = (string)Compiler.SOURCE.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SOURCE_SPAN.deref();  // Compiler.GetSourceSpanMap(form);

                Symbol tag = Compiler.TagOf(form);

                // determine static or instance
                // static target must be symbol, either fully.qualified.Typename or Typename that has been imported

                Type t = HostExpr.MaybeType(RT.second(form), false);
                // at this point, t will be non-null if static

                Expr instance = null;
                if (t == null)
                    instance = Compiler.Analyze(pcon.EvEx(),RT.second(form));

                bool isZeroArityCall = RT.Length(form) == 3 && (RT.third(form) is Symbol || RT.third(form) is Keyword);

                if (isZeroArityCall)
                {
                    PropertyInfo pinfo = null;
                    FieldInfo finfo = null;
                    MethodInfo minfo = null;

                    Symbol sym = (RT.third(form) is Keyword) ? ((Keyword)RT.third(form)).Symbol : (Symbol)RT.third(form);
                    string fieldName = Compiler.munge(sym.Name);
                    // The JVM version does not have to worry about Properties.  It captures 0-arity methods under fields.
                    // We have to put in special checks here for this.
                    // Also, when reflection is required, we have to capture 0-arity methods under the calls that
                    //   are generated by StaticFieldExpr and InstanceFieldExpr.
                    if (t != null)
                    {
                        if ((finfo = Reflector.GetField(t, fieldName, true)) != null)
                            return new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo);
                        if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null)
                            return new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo);
                        if ((minfo = Reflector.GetArityZeroMethod(t, fieldName, true)) != null)
                            return new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List<HostArg>());
                        throw new MissingMemberException(t.Name, fieldName);
                    }
                    else if (instance != null && instance.HasClrType && instance.ClrType != null)
                    {
                        Type instanceType = instance.ClrType;
                        if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null)
                            return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo);
                        if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null)
                            return new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo);
                        if ((minfo = Reflector.GetArityZeroMethod(instanceType, fieldName, false)) != null)
                            return new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List<HostArg>());
                        if (pcon.IsAssignContext)
                            return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        else
                            return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);
                    }
                    else
                    {
                        //  t is null, so we know this is not a static call
                        //  If instance is null, we are screwed anyway.
                        //  If instance is not null, then we don't have a type.
                        //  So we must be in an instance call to a property, field, or 0-arity method.
                        //  The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo
                        //     will generate code to do a runtime call to a Reflector method that will check all three.
                        //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);
                        if (pcon.IsAssignContext)
                            return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        else
                            return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);

                    }
                }

                //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                ISeq call;
                List<Type> typeArgs = null;

                   //object third = RT.third(form);

                //if (third is ISeq && RT.first(third) is Symbol && ((Symbol)RT.first(third)).Equals(GENERIC))
                //{
                //    // We have a generic method call
                //    // (. thing (generic methodname type1 ...) args...)
                //    typeArgs = ParseGenericMethodTypeArgs(RT.next(RT.next(third)));
                //    call = RT.listStar(RT.second(third), RT.next(RT.next(RT.next(form))));
                //}
                //else
                //    call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                object fourth = RT.fourth(form);
                if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TYPE_ARGS))
                 {
                    // We have a type args supplied for a generic method call
                    // (. thing methodname (type-args type1 ... ) args ...)
                    typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth));
                    call = RT.listStar(RT.third(form), RT.next(RT.next(RT.next(RT.next(form)))));
                }
                else
                    call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                if (!(RT.first(call) is Symbol))
                    throw new ArgumentException("Malformed member exception");

                string methodName = Compiler.munge(((Symbol)RT.first(call)).Name);

                List<HostArg> args = ParseArgs(pcon, RT.next(call));

                return t != null
                    ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args))
                    : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args));
            }
Пример #34
0
        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);

            // Java: fn.objtype = Type.getObjectType(fn.internalName) -- makes no sense for us, this is ASM only.

            List<string> prims = new List<string>();

            try
            {
                Var.pushThreadBindings(RT.map(
                    Compiler.CONSTANTS, PersistentVector.EMPTY,
                    Compiler.CONSTANT_IDS, new IdentityHashMap(),
                    Compiler.KEYWORDS, PersistentHashMap.EMPTY,
                    Compiler.VARS, PersistentHashMap.EMPTY,
                    Compiler.KEYWORD_CALLSITES,PersistentVector.EMPTY,
                    Compiler.PROTOCOL_CALLSITES,PersistentVector.EMPTY,
                    Compiler.VAR_CALLSITES,Compiler.EmptyVarCallSites(),
                    Compiler.NO_RECUR,null));

                //arglist might be preceded by symbol naming this fn
                if (RT.second(form) is Symbol)
                {
                    Symbol nm = (Symbol)RT.second(form);
                    fn._thisName = nm.Name;
                    fn.IsStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY));
                    form = RT.cons(Compiler.FN, 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.FN, RT.next(form));

                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 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 (f.Prim != null)
                        prims.Add(f.Prim);
                }

                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.");

                if ( fn.IsStatic && fn.Closes.count() > 0 )
                    throw new ArgumentException("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.KEYWORDS.deref();
                fn.Vars = (IPersistentMap)Compiler.VARS.deref();
                fn.Constants = (PersistentVector)Compiler.CONSTANTS.deref();
                fn.KeywordCallsites = (IPersistentVector)Compiler.KEYWORD_CALLSITES.deref();
                fn.ProtocolCallsites = (IPersistentVector)Compiler.PROTOCOL_CALLSITES.deref();
                fn.VarCallsites = (IPersistentSet)Compiler.VAR_CALLSITES.deref();

                fn._constantsID = RT.nextID();
            }
            finally
            {
                Var.popThreadBindings();
            }

            IPersistentMap fmeta = RT.meta(origForm);
            if (fmeta != null)
                fmeta = fmeta.without(RT.LINE_KEY).without(RT.FILE_KEY);
            fn._hasMeta = RT.count(fmeta) > 0;

            if (Compiler.IsCompiling || prims.Count > 0)
            {
                GenContext context = Compiler.COMPILER_CONTEXT.get() as GenContext ?? Compiler.EvalContext;
                GenContext genC = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());

                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,
                    genC);
            }
            else
            {
                fn.CompiledType = fn.GetPrecompiledType();
                fn.FnMode = FnMode.Light;
            }

            if (fn.SupportsMeta)
                return new MetaExpr(fn, MapExpr.Parse(pcon.EvEx(),fmeta));
            else
                return fn;
        }
Пример #35
0
 public Expr Parse(ParserContext pcon, object form)
 {
     object v = RT.second(form);
     if (v == null)
         return Compiler.NIL_EXPR;
     else
         return new ConstantExpr(v);
 }
Пример #36
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                if (pcon.Rhc != RHC.Return)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "try__" + RT.nextID()));
                }

                // (try try-expr* catch-expr* finally-expr?)
                // catch-expr: (catch class sym expr*)
                // finally-expr: (finally expr*)

                IPersistentVector body    = PersistentVector.EMPTY;
                IPersistentVector catches = PersistentVector.EMPTY;
                Expr bodyExpr             = null;
                Expr finallyExpr          = null;
                bool caught = false;

                ParserContext recursePcon = new ParserContext(RHC.Expression, false);

                int retLocal     = Compiler.GetAndIncLocalNum();
                int finallyLocal = Compiler.GetAndIncLocalNum();

                for (ISeq fs = form.next(); fs != null; fs = fs.next())
                {
                    object f  = fs.first();
                    object op = f is ISeq fSeq?fSeq.first() : null;

                    if (!Util.equals(op, Compiler.CatchSym) && !Util.equals(op, Compiler.FinallySym))
                    {
                        if (caught)
                        {
                            throw new ParseException("Only catch or finally clause can follow catch in try expression");
                        }
                        body = body.cons(f);
                    }
                    else
                    {
                        if (bodyExpr == null)
                        {
                            try
                            {
                                Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, true, Compiler.MethodReturnContextVar, null));
                                bodyExpr = new BodyExpr.Parser().Parse(pcon, RT.seq(body));
                            }
                            finally
                            {
                                Var.popThreadBindings();
                            }
                        }
                        if (Util.equals(op, Compiler.CatchSym))
                        {
                            Type t = HostExpr.MaybeType(RT.second(f), false);
                            if (t == null)
                            {
                                throw new ParseException("Unable to resolve classname: " + RT.second(f));
                            }
                            if (!(RT.third(f) is Symbol))
                            {
                                throw new ParseException("Bad binding form, expected symbol, got: " + RT.third(f));
                            }
                            Symbol sym = (Symbol)RT.third(f);
                            if (sym.Namespace != null)
                            {
                                throw new ParseException("Can't bind qualified name: " + sym);
                            }

                            IPersistentMap dynamicBindings = RT.map(
                                Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                                Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref(),
                                Compiler.InCatchFinallyVar, true);

                            try
                            {
                                Var.pushThreadBindings(dynamicBindings);
                                LocalBinding lb = Compiler.RegisterLocal(sym,
                                                                         (Symbol)(RT.second(f) is Symbol ? RT.second(f) : null),
                                                                         null, typeof(Object), false);
                                Expr handler = (new BodyExpr.Parser()).Parse(recursePcon, RT.next(RT.next(RT.next(f))));
                                catches = catches.cons(new CatchClause(t, lb, handler));;
                            }
                            finally
                            {
                                Var.popThreadBindings();
                            }
                            caught = true;
                        }
                        else // finally
                        {
                            if (fs.next() != null)
                            {
                                throw new InvalidOperationException("finally clause must be last in try expression");
                            }
                            try
                            {
                                //Var.pushThreadBindings(RT.map(Compiler.IN_CATCH_FINALLY, RT.T));
                                Var.pushThreadBindings(RT.map(Compiler.InCatchFinallyVar, true));
                                finallyExpr = (new BodyExpr.Parser()).Parse(pcon.SetRhc(RHC.Statement).SetAssign(false), RT.next(f));
                            }
                            finally
                            {
                                Var.popThreadBindings();
                            }
                        }
                    }
                }

                if (bodyExpr == null)
                {
                    // this codepath is hit when there is neither catch nor finally, e.g., (try (expr))
                    // return a body expr directly
                    try
                    {
                        Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, true));
                        bodyExpr = (new BodyExpr.Parser()).Parse(pcon, RT.seq(body));
                    }
                    finally
                    {
                        Var.popThreadBindings();
                    }
                    return(bodyExpr);
                }
                return(new TryExpr(bodyExpr, catches, finallyExpr, retLocal, finallyLocal));
            }
Пример #37
0
 public Expr Parse(ParserContext pcon, object form)
 {
     return new MonitorEnterExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form)));
 }
Пример #38
0
            public Expr Parse(ParserContext pcon, object form)
            {
                ISeq sform = (ISeq)form;

                // form is one of:
                //  (. x fieldname-sym)
                //  (. x 0-ary-method)
                //  (. x propertyname-sym)
                //  (. x methodname-sym args)+
                //  (. x (methodname-sym args?))
                //  (. x (generic-m

                if (RT.Length(sform) < 3)
                {
                    throw new ParseException("Malformed member expression, expecting (. target member ... )");
                }

                string         source  = (string)Compiler.SourceVar.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();  // Compiler.GetSourceSpanMap(form);

                Symbol tag = Compiler.TagOf(sform);

                // determine static or instance
                // static target must be symbol, either fully.qualified.Typename or Typename that has been imported

                Type t = HostExpr.MaybeType(RT.second(sform), false);
                // at this point, t will be non-null if static

                Expr instance = null;

                if (t == null)
                {
                    instance = Compiler.Analyze(pcon.EvalOrExpr(), RT.second(sform));
                }

                bool isZeroArityCall = RT.Length(sform) == 3 && RT.third(sform) is Symbol;

                if (isZeroArityCall)
                {
                    PropertyInfo pinfo = null;
                    FieldInfo    finfo = null;

                    // TODO: Figure out if we want to handle the -propname otherwise.

                    bool   isPropName = false;
                    Symbol sym        = (Symbol)RT.third(sform);
                    if (sym.Name[0] == '-')
                    {
                        isPropName = true;
                        sym        = Symbol.intern(sym.Name.Substring(1));
                    }

                    string fieldName = Compiler.munge(sym.Name);
                    // The JVM version does not have to worry about Properties.  It captures 0-arity methods under fields.
                    // We have to put in special checks here for this.
                    // Also, when reflection is required, we have to capture 0-arity methods under the calls that
                    //   are generated by StaticFieldExpr and InstanceFieldExpr.
                    if (t != null)
                    {
                        if ((finfo = Reflector.GetField(t, fieldName, true)) != null)
                        {
                            return(new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo));
                        }
                        if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null)
                        {
                            return(new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo));
                        }
                        if (!isPropName && Reflector.GetArityZeroMethod(t, fieldName, true) != null)
                        {
                            return(new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List <HostArg>()));
                        }
                        throw new MissingMemberException(t.Name, fieldName);
                    }
                    else if (instance != null && instance.HasClrType && instance.ClrType != null)
                    {
                        Type instanceType = instance.ClrType;
                        if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null)
                        {
                            return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo));
                        }
                        if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null)
                        {
                            return(new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo));
                        }
                        if (!isPropName && Reflector.GetArityZeroMethod(instanceType, fieldName, false) != null)
                        {
                            return(new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List <HostArg>()));
                        }
                        if (pcon.IsAssignContext)
                        {
                            return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null
                        }
                        else
                        {
                            return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName));
                        }
                    }
                    else
                    {
                        //  t is null, so we know this is not a static call
                        //  If instance is null, we are screwed anyway.
                        //  If instance is not null, then we don't have a type.
                        //  So we must be in an instance call to a property, field, or 0-arity method.
                        //  The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo
                        //     will generate code to do a runtime call to a Reflector method that will check all three.
                        //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);
                        if (pcon.IsAssignContext)
                        {
                            return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null
                        }
                        else
                        {
                            return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName));
                        }
                    }
                }

                //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                ISeq        call;
                List <Type> typeArgs = null;

                object fourth = RT.fourth(sform);

                if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TypeArgsSym))
                {
                    // We have a type args supplied for a generic method call
                    // (. thing methodname (type-args type1 ... ) args ...)
                    typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth));
                    call     = RT.listStar(RT.third(sform), RT.next(RT.next(RT.next(RT.next(sform)))));
                }
                else
                {
                    call = RT.third(sform) is ISeq ? (ISeq)RT.third(sform) : RT.next(RT.next(sform));
                }

                if (!(RT.first(call) is Symbol))
                {
                    throw new ParseException("Malformed member exception");
                }

                string methodName = Compiler.munge(((Symbol)RT.first(call)).Name);

                List <HostArg> args = ParseArgs(pcon, RT.next(call));

                return(t != null
                    ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args))
                    : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args)));
            }
Пример #39
0
 public Expr Parse(ParserContext pcon, object frm)
 {
     return new ImportExpr((string)RT.second(frm));
 }
Пример #40
0
            //(case* expr shift mask  default map<minhash, [test then]> table-type test-type skip-check?)
            //prepared by case macro and presumed correct
            //case macro binds actual expr in let so expr is always a local,
            //no need to worry about multiple evaluation
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq) frm;

                if (pcon.Rhc == RHC.Eval)
                    return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnSym, PersistentVector.EMPTY, form)),"case__"+RT.nextID());

                PersistentVector args = PersistentVector.create(form.next());

                object exprForm = args.nth(0);
                int shift = Util.ConvertToInt(args.nth(1));
                int mask = Util.ConvertToInt(args.nth(2));
                object defaultForm = args.nth(3);
                IPersistentMap caseMap = (IPersistentMap)args.nth(4);
                Keyword switchType = (Keyword)args.nth(5);
                Keyword testType = (Keyword)args.nth(6);
                IPersistentSet skipCheck = RT.count(args) < 8 ? null : (IPersistentSet)args.nth(7);

                ISeq keys = RT.keys(caseMap);
                int low = Util.ConvertToInt(RT.first(keys));
                int high = Util.ConvertToInt(RT.nth(keys,RT.count(keys)-1));
                LocalBindingExpr testexpr = (LocalBindingExpr)Compiler.Analyze(pcon.SetRhc(RHC.Expression),exprForm);

                SortedDictionary<int,Expr> tests = new SortedDictionary<int,Expr>();
                Dictionary<int,Expr> thens = new Dictionary<int,Expr>();

                //testexpr.shouldClear = false;
                //PathNode branch = new PathNode(PATHTYPE.BRANCH, (PathNode) CLEAR_PATH.get());

                foreach ( IMapEntry me in caseMap )
                {
                    int minhash = Util.ConvertToInt(me.key());
                    object pair = me.val(); // [test-val then-expr]
                    object first = RT.first(pair);
                    Expr testExpr = testType == _intKey
                        ? NumberExpr.Parse(Util.ConvertToInt(first))
                        : (first == null ? Compiler.NilExprInstance : new ConstantExpr(first));

                    tests[minhash] = testExpr;
                    Expr thenExpr;
                    //try
                    //{
                    //    Var.pushThreadBindings(
                    //        RT.map(CLEAR_PATH, new PathNode(PATHTYPE.PATH,branch)));
                    thenExpr = Compiler.Analyze(pcon,RT.second(pair));
                    //}
                    //finally
                    //{
                    //    Var.popThreadBindings();
                    //}
                    thens[minhash] = thenExpr;
                }

                Expr defaultExpr;
                //try
                //{
                //    Var.pushThreadBindings(
                //        RT.map(CLEAR_PATH, new PathNode(PATHTYPE.PATH,branch)));
                defaultExpr = Compiler.Analyze(pcon,defaultForm);
                //}
                //finally
                //{
                //    Var.popThreadBindings();
                //}
                return new CaseExpr(
                (IPersistentMap) Compiler.SourceSpanVar.deref(),
                testexpr,
                shift,
                mask,
                low,
                high,
                defaultExpr,
                tests,
                thens,
                switchType,
                testType,
                skipCheck);
            }
Пример #41
0
        internal static Expr OptionallyGenerateMetaInit(ParserContext pcon, object form, Expr expr)
        {
            Expr ret = expr;

            if ( RT.meta(form) != null )
                ret = new MetaExpr(ret, (MapExpr)MapExpr.Parse(pcon.EvalOrExpr(),((IObj)form).meta()));

            return ret;
        }
Пример #42
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvalOrExpr();

            bool           keysConstant          = true;
            bool           valsConstant          = true;
            bool           allConstantKeysUnique = true;
            IPersistentSet constantKeys          = PersistentHashSet.EMPTY;

            IPersistentVector keyvals = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr      k = Compiler.Analyze(pconToUse, e.key());
                Expr      v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (k is LiteralExpr)
                {
                    object kval = k.Eval();
                    if (constantKeys.contains(kval))
                    {
                        allConstantKeysUnique = false;
                    }
                    else
                    {
                        constantKeys = (IPersistentSet)constantKeys.cons(kval);
                    }
                }
                else
                {
                    keysConstant = false;
                }
                if (!(v is LiteralExpr))
                {
                    valsConstant = false;
                }
            }

            Expr ret = new MapExpr(keyvals);

            IObj iobjForm = form as IObj;

            if (iobjForm != null && iobjForm.meta() != null)
            {
                return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret));
            }
            //else if (constant)
            //{
            // This 'optimzation' works, mostly, unless you have nested map values.
            // The nested map values do not participate in the constants map, so you end up with the code to create the keys.
            // Result: huge duplication of keyword creation.  3X increase in init time to the REPL.
            //    //IPersistentMap m = PersistentHashMap.EMPTY;
            //    //for (int i = 0; i < keyvals.length(); i += 2)
            //    //    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
            //    //return new ConstantExpr(m);
            //    return ret;
            //}
            else if (keysConstant)
            {
                // TBD: Add more detail to exception thrown below.
                if (!allConstantKeysUnique)
                {
                    throw new ArgumentException("Duplicate constant keys in map");
                }
                if (valsConstant)
                {
                    // This 'optimzation' works, mostly, unless you have nested map values.
                    // The nested map values do not participate in the constants map, so you end up with the code to create the keys.
                    // Result: huge duplication of keyword creation.  3X increase in init time to the REPL.
                    //IPersistentMap m = PersistentArrayMap.EMPTY;
                    //for (int i = 0; i < keyvals.length(); i += 2)
                    //    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                    //return new ConstantExpr(m);
                    return(ret);
                }
                else
                {
                    return(ret);
                }
            }
            else
            {
                return(ret);
            }
        }