SetRhc() публичный Метод

public SetRhc ( RHC rhc ) : ParserContext
rhc RHC
Результат ParserContext
Пример #1
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));
            }
Пример #2
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)));
            }
Пример #3
0
            public Expr Parse(ParserContext pcon, object form)
            {
                if (pcon.Rhc == RHC.Eval)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnSym, PersistentVector.EMPTY, form)), "throw__" + RT.nextID()));
                }

                return(new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form))));
            }
Пример #4
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;
                if (RT.Length(form) != 3)
                    throw new ParseException("Malformed assignment, expecting (set! target val)");
                Expr target = Compiler.Analyze(new ParserContext(RHC.Expression, true), RT.second(form));

                AssignableExpr ae = target as AssignableExpr;
                if (ae == null)
                    throw new ParseException("Invalid assignment target");

                return new AssignExpr(ae, Compiler.Analyze(pcon.SetRhc(RHC.Expression),RT.third(form)));
            }
Пример #5
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)));
            }
Пример #6
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                if (RT.Length(form) != 3)
                {
                    throw new ParseException("Malformed assignment, expecting (set! target val)");
                }
                Expr target = Compiler.Analyze(new ParserContext(RHC.Expression, true), RT.second(form));

                if (!(target is AssignableExpr ae))
                {
                    throw new ParseException("Invalid assignment target");
                }

                return(new AssignExpr(ae, Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.third(form))));
            }
Пример #7
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))));
            }
Пример #8
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);
            }
Пример #9
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            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,
                                                    RT.listStar(Symbol.intern(".invokePrim"),
                                                                ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))),
                                                                form.next())));
                        }
                        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));
        }
Пример #10
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.LOOP);

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

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

                if ((bindings.count() % 2) != 0)
                    throw new ArgumentException("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.FN, PersistentVector.EMPTY, form)),"let__"+RT.nextID());

                ObjMethod method = (ObjMethod)Compiler.METHOD.deref();
                IPersistentMap backupMethodLocals = method.Locals;
                IPersistentMap backupMethodIndexLocals = method.IndexLocals;
                IPersistentVector recurMismatches = null;

                // we might repeat once if a loop with a recurMismatch, return breaks
                while (true)
                {

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

                    if (isLoop)
                        dynamicBindings = dynamicBindings.assoc(Compiler.LOOP_LOCALS, 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 ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i));

                            Symbol sym = (Symbol)bindings.nth(i);
                            if (sym.Namespace != null)
                                throw new Exception("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 && ((LocalBinding)recurMismatches.nth(i / 2)).RecurMistmatch)
                            //    {
                            //        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", has);
                            //        if (RT.booleanCast(RT.WARN_ON_REFLECTION.deref()))
                            //            RT.errPrintWriter().WriteLine("Auto-boxing loop arg: " + sym);
                            //    }
                            //    else if (Compiler.MaybePrimitiveType(init) == typeof(int))
                            //    {
                            //        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), "longCast", has);
                            //    }
                            //    else if (Compiler.MaybePrimitiveType(init) == typeof(float))
                            //    {
                            //        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), "doubleCast", has);
                            //    }
                            //}

                            // 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.LOOP_LOCALS.set(loopLocals);

                        Expr bodyExpr;
                        try
                        {
                            if (isLoop)
                            {
                                // stuff with clear paths
                            }
                            bodyExpr = new BodyExpr.Parser().Parse(isLoop ? pcon.SetRhc(RHC.Return) : pcon, body);
                        }
                        finally
                        {
                            if (isLoop)
                            {
                                // stuff with clear paths
                                recurMismatches = null;
                                for (int i = 0; i < loopLocals.count(); i++)
                                {
                                    LocalBinding lb = (LocalBinding)loopLocals.nth(i);
                                    if (lb.RecurMistmatch)
                                        recurMismatches = loopLocals;
                                }
                            }
                        }

                        if (recurMismatches == null)
                            return new LetExpr(bindingInits, bodyExpr, isLoop);

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

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

                if (!(RT.second(form) is IPersistentVector bindings))
                {
                    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();
                }
            }
Пример #13
0
            //(case* expr shift mask low high default map<minhash, [test then]> identity?)
            //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.FN, PersistentVector.EMPTY, form)),"case__"+RT.nextID());

                PersistentVector args = PersistentVector.create(form.next());
                Dictionary<int,Expr> tests = new Dictionary<int,Expr>();
                Dictionary<int,Expr> thens = new Dictionary<int,Expr>();

                LocalBindingExpr testexpr = (LocalBindingExpr)Compiler.Analyze(pcon.SetRhc(RHC.Expression),args.nth(0));
                //testexpr.shouldClear = false;

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

                foreach ( IMapEntry e in ((IPersistentMap)args.nth(6)) )
                {
                    int minhash = (int)e.key();
                    IMapEntry me = (IMapEntry)e.val();
                    Expr testExpr = new ConstantExpr(me.key());
                    tests[minhash] = testExpr;
                    Expr thenExpr;
                    //try
                    //{
                    //    Var.pushThreadBindings(
                    //        RT.map(CLEAR_PATH, new PathNode(PATHTYPE.PATH,branch)));
                    thenExpr = Compiler.Analyze(pcon,me.val());
                    //}
                    //finally
                    //{
                    //    Var.popThreadBindings();
                    //}
                    thens[minhash] = thenExpr;
                }

                Expr defaultExpr;
                //try
                //{
                //    Var.pushThreadBindings(
                //        RT.map(CLEAR_PATH, new PathNode(PATHTYPE.PATH,branch)));
                defaultExpr = Compiler.Analyze(pcon,args.nth(5));
                //}
                //finally
                //{
                //    Var.popThreadBindings();
                //}

                return new CaseExpr(
                (IPersistentMap) Compiler.SOURCE_SPAN.deref(),
                testexpr,
                (int)args.nth(1),
                (int)args.nth(2),
                (int)args.nth(3),
                (int)args.nth(4),
                defaultExpr,
                tests,
                thens,
                RT.booleanCast(args.nth(7)));
            }
Пример #14
0
 public Expr Parse(ParserContext pcon, object form)
 {
     return(new MonitorEnterExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form))));
 }
Пример #15
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.Locals = backupMethodLocals;
                    method.IndexLocals = 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();
                    }
                }
            }
Пример #16
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));
            }
Пример #17
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

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

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

                if (Compiler.IN_CATCH_FINALLY.deref() != null)
                    throw new InvalidOperationException("Cannot recur from catch/finally.");

                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 ArgumentException(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 (pt == 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 (pt == typeof(double))
                //        {
                //            if (!(pt == typeof(double) || pt == typeof(float)))
                //                mismatch = true;
                //        }

                //        if (mismatch)
                //        {
                //            lb.RecurMistmatch = true;
                //            if (RT.booleanCast(RT.WARN_ON_REFLECTION.deref()))
                //                RT.errPrintWriter().WriteLine("{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                //                    "Source", "Line", lb.Name, pt != null ? pt.Name : "Object", primt.Name);
                //        }
                //    }
                //}
                return new RecurExpr(loopLocals, args);
            }
Пример #18
0
 public Expr Parse(ParserContext pcon, object form)
 {
     return new MonitorEnterExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form)));
 }
Пример #19
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();
                }
            }
Пример #20
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));
                if (sexpr is ConstantExpr csexpr)
                {
                    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 (RT.booleanCast(Compiler.GetCompilerOption(Compiler.DirectLinkingKeyword)) &&
                varFexpr != null &&
                pcon.Rhc != RHC.Eval)
            {
                Var v = varFexpr.Var;
                if (!v.isDynamic() && !RT.booleanCast(RT.get(v.meta(), Compiler.RedefKeyword, false)) && !RT.booleanCast(RT.get(v.meta(), RT.DeclaredKey, false)))
                {
                    Symbol formTag = Compiler.TagOf(form);
                    //object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword);
                    int    arity  = RT.count(form.next());
                    object sigtag = SigTag(arity, v);
                    object vtag   = RT.get(RT.meta(v), RT.TagKey);
                    if (StaticInvokeExpr.Parse(v, RT.next(form), formTag ?? sigtag ?? vtag) is StaticInvokeExpr ret && !((Compiler.IsCompiling || Compiler.IsCompilingDefType) && GenContext.IsInternalAssembly(ret.Method.DeclaringType.Assembly)))
                    {
                        //Console.WriteLine("invoke direct: {0}", v);
                        return(ret);
                    }
                    //Console.WriteLine("NOT direct: {0}", v);
                }
            }

            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;
                    }
                }
            }

            if (fexpr is KeywordExpr kwFexpr && 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));
        }
Пример #21
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            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,
                                RT.listStar(Symbol.intern(".invokePrim"),
                                            ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))),
                                            form.next()));
                        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);
        }
Пример #22
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();
                    ISeq fSeq = f as ISeq;
                    object op = fSeq != null ? 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.InTryBlockVar, true));
                                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(recursePcon, RT.seq(body));
                    }
                    finally
                    {
                        Var.popThreadBindings();
                    }
                    return bodyExpr;
                }
                return new TryExpr(bodyExpr, catches, finallyExpr, retLocal, finallyLocal);
            }
Пример #23
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);
            }
Пример #24
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);

                if (!(RT.second(form) is IPersistentVector bindings))
                {
                    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)
                                    {
                                        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>
                                    {
                                        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>
                                    {
                                        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, typeof(Object), 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)
                            {
                                object methodReturnContext = pcon.Rhc == RHC.Return ? Compiler.MethodReturnContextVar.deref() : null;
                                // stuff with clear paths,
                                Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, null,
                                                              Compiler.MethodReturnContextVar, methodReturnContext));
                            }
                            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();
                    }
                }
            }
Пример #25
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.FnOnceSym, PersistentVector.EMPTY, form)), "case__" + RT.nextID()));
                }

                IPersistentVector args = LazilyPersistentVector.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));
            }
Пример #26
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();
                    ISeq   fSeq = f as ISeq;
                    object op   = fSeq != null?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));
                                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, 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)
                {
                    try
                    {
                        Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, true));
                        bodyExpr = (new BodyExpr.Parser()).Parse(recursePcon, RT.seq(body));
                    }
                    finally
                    {
                        Var.popThreadBindings();
                    }
                }
                return(new TryExpr(bodyExpr, catches, finallyExpr, retLocal, finallyLocal));
            }
Пример #27
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.InCatchFinallyVar.deref() != null)
                    throw new ParseException("Cannot recur from catch/finally.");

                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);
            }
Пример #28
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 ( RT.booleanCast(Compiler.GetCompilerOption(Compiler.DirectLinkingKeyword))
                && varFexpr != null
                && pcon.Rhc != RHC.Eval )
            {
                Var v = varFexpr.Var;
                if ( ! v.isDynamic() && !RT.booleanCast(RT.get(v.meta(), Compiler.RedefKeyword, false)) && !RT.booleanCast(RT.get(v.meta(), RT.DeclaredKey, false)) )
                {
                    Symbol formTag = Compiler.TagOf(form);
                    object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword);
                    int arity = RT.count(form.next());
                    object sigtag = SigTag(arity, v);
                    object vtag = RT.get(RT.meta(v), RT.TagKey);
                    StaticInvokeExpr ret = StaticInvokeExpr.Parse(v, RT.next(form), formTag ?? sigtag ?? vtag) as StaticInvokeExpr;
                    if (ret != null && !((Compiler.IsCompiling || Compiler.IsCompilingDefType) && GenContext.IsInternalAssembly(ret.Method.DeclaringType.Assembly)))
                    {
                        //Console.WriteLine("invoke direct: {0}", v);
                        return ret;
                    }
                    //Console.WriteLine("NOT direct: {0}", v);
                }
            }

            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);
        }