Esempio n. 1
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            int n = _bindingInits.count();
            List <ParameterExpression> parms = new List <ParameterExpression>(n);
            List <Expression>          forms = new List <Expression>(n);

            /// First, set up the environment.
            for (int i = 0; i < n; i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                ParameterExpression parmExpr = Expression.Parameter(typeof(IFn), bi.Binding.Name);
                bi.Binding.ParamExpression = parmExpr;
                parms.Add(parmExpr);
            }

            // Then initialize
            for (int i = 0; i < n; i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                ParameterExpression parmExpr = (ParameterExpression)bi.Binding.ParamExpression;
                forms.Add(Expression.Assign(parmExpr, bi.Init.GenCode(RHC.Expression, objx, context)));
            }

            // The work
            forms.Add(_body.GenCode(rhc, objx, context));
            return(Expression.Block(parms, forms));
        }
Esempio n. 2
0
        void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed)
        {
            List <LocalBuilder> locals = new List <LocalBuilder>();

            for (int i = 0; i < _bindingInits.count(); i++)
            {
                BindingInit bi       = (BindingInit)_bindingInits.nth(i);
                Type        primType = Compiler.MaybePrimitiveType(bi.Init);
                if (primType != null)
                {
                    LocalBuilder local = ilg.DeclareLocal(primType);
                    locals.Add(local);
                    GenContext.SetLocalName(local, bi.Binding.Name);
                    bi.Binding.LocalVar = local;

                    ((MaybePrimitiveExpr)bi.Init).EmitUnboxed(RHC.Expression, objx, ilg);
                    ilg.Emit(OpCodes.Stloc, local);
                }
                else
                {
                    LocalBuilder local = ilg.DeclareLocal(typeof(Object));
                    locals.Add(local);
                    GenContext.SetLocalName(local, bi.Binding.Name);
                    bi.Binding.LocalVar = local;

                    bi.Init.Emit(RHC.Expression, objx, ilg);
                    ilg.Emit(OpCodes.Stloc, local);
                }
            }

            Label loopLabel = ilg.DefineLabel();

            ilg.MarkLabel(loopLabel);

            try
            {
                if (_isLoop)
                {
                    Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel));
                }

                if (emitUnboxed)
                {
                    ((MaybePrimitiveExpr)_body).EmitUnboxed(rhc, objx, ilg);
                }
                else
                {
                    _body.Emit(rhc, objx, ilg);
                }
            }
            finally
            {
                if (_isLoop)
                {
                    Var.popThreadBindings();
                }
            }
        }
Esempio n. 3
0
        private Expression GenCode(RHC rhc, ObjExpr objx, GenContext context, bool genUnboxed)
        {
            LabelTarget loopLabel = Expression.Label();

            List <ParameterExpression> parms = new List <ParameterExpression>();
            List <Expression>          forms = new List <Expression>();

            for (int i = 0; i < _bindingInits.count(); i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                Type                primType = Compiler.MaybePrimitiveType(bi.Init);
                ParameterExpression parmExpr;
                Expression          initExpr;
                if (primType != null)
                {
                    parmExpr = Expression.Parameter(primType, bi.Binding.Name);
                    initExpr = ((MaybePrimitiveExpr)bi.Init).GenCodeUnboxed(RHC.Expression, objx, context);
                }
                else
                {
                    parmExpr = Expression.Parameter(typeof(object), bi.Binding.Name);
                    initExpr = Compiler.MaybeBox(bi.Init.GenCode(RHC.Expression, objx, context));
                }
                bi.Binding.ParamExpression = parmExpr;
                parms.Add(parmExpr);
                forms.Add(Expression.Assign(parmExpr, initExpr));
            }


            forms.Add(Expression.Label(loopLabel));

            try
            {
                if (_isLoop)
                {
                    Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel));
                }

                Expression form = genUnboxed
                    ? ((MaybePrimitiveExpr)_body).GenCodeUnboxed(rhc, objx, context)
                    : _body.GenCode(rhc, objx, context);

                forms.Add(form);
            }
            finally
            {
                if (_isLoop)
                {
                    Var.popThreadBindings();
                }
            }

            Expression block = Expression.Block(parms, forms);

            return(block);
        }
Esempio n. 4
0
        public override Expression GenDlr(GenContext context)
        {
            LabelTarget loopLabel = Expression.Label();

            List <ParameterExpression> parms = new List <ParameterExpression>();
            List <Expression>          forms = new List <Expression>();

            for (int i = 0; i < _bindingInits.count(); i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                Type                primType = Compiler.MaybePrimitiveType(bi.Init);
                ParameterExpression parmExpr = Expression.Parameter(primType ?? typeof(object), bi.Binding.Name);
                bi.Binding.ParamExpression = parmExpr;
                parms.Add(parmExpr);
                //forms.Add(Expression.Assign(parmExpr, Compiler.MaybeBox(bi.Init.GenDlr(context))));
                Expression initExpr = primType != null ? ((MaybePrimitiveExpr)bi.Init).GenDlrUnboxed(context) : Compiler.MaybeBox(bi.Init.GenDlr(context));
                forms.Add(Expression.Assign(parmExpr, initExpr));
            }


            forms.Add(Expression.Label(loopLabel));

            try
            {
                if (_isLoop)
                {
                    Var.pushThreadBindings(PersistentHashMap.create(Compiler.LOOP_LABEL, loopLabel));
                }

                forms.Add(_body.GenDlr(context));
            }
            finally
            {
                if (_isLoop)
                {
                    Var.popThreadBindings();
                }
            }

            Expression block = Expression.Block(parms, forms);

            return(block);
        }
Esempio n. 5
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            int n = _bindingInits.count();

            // Define our locals
            for (int i = 0; i < n; i++)
            {
                BindingInit  bi    = (BindingInit)_bindingInits.nth(i);
                LocalBuilder local = ilg.DeclareLocal(typeof(IFn));
                bi.Binding.LocalVar = local;
                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Stloc, local);
            }

            // Then initialize

            IPersistentSet lbset = PersistentHashSet.EMPTY;

            for (int i = 0; i < n; i++)
            {
                BindingInit bi = (BindingInit)_bindingInits.nth(i);
                lbset = (IPersistentSet)lbset.cons(bi.Binding);

                bi.Init.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Stloc, bi.Binding.LocalVar);
            }

            for (int i = 0; i < n; i++)
            {
                BindingInit bi = (BindingInit)_bindingInits.nth(i);
                ObjExpr     fe = (ObjExpr)bi.Init;

                ilg.Emit(OpCodes.Ldloc, bi.Binding.LocalVar);
                fe.EmitLetFnInits(ilg, bi.Binding.LocalVar, objx, lbset);
            }

            _body.Emit(rhc, objx, ilg);
        }
Esempio n. 6
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();
                }
            }
Esempio n. 7
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();
                }
            }
Esempio n. 8
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();
                    }
                }
            }
Esempio n. 9
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();
                    }
                }
            }
Esempio n. 10
0
            public Expr Parse(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 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));

                // TODO: This is one place where context makes a difference.  Need to figure this out.
                // if (ctxt == C.EVAL)
                //    return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));


                IPersistentMap dynamicBindings = RT.map(
                    Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(),
                    Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.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 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);
                        }

                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null);
                        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.GenerateAST(bindings.nth(i + 1), sym.Name);
                        // Sequential enhancement of env (like Lisp let*)
                        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(body)));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Esempio n. 11
0
            public Expr Parse(object frm, bool isRecurContext)
            {
                ISeq form = (ISeq)frm;

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

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

                IPersistentMap dynamicBindings = RT.map(
                    Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(),
                    Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.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 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);

                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null);
                        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.GenerateAST(bindings.nth(i + 1),sym.Name,false);
                        // Sequential enhancement of env (like Lisp let*)
                        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(body,isRecurContext));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Esempio n. 12
0
            public Expr Parse(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));

                // TODO: This is one place where context makes a difference.  Need to figure this out.
                //  Second test clause added in Rev 1216.
                // if (ctxt == C.EVAL || (context == c.EXPRESSION && isLoop))
                //    return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));

                // As of Rev 1216, I tried tjos out.
                // However, it goes into an infinite loop.  Still need to figure this out.
                //if (isLoop)
                //    Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));

                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.GenerateAST(bindings.nth(i + 1));
                        // Sequential enhancement of env (like Lisp let*)
                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init);
                        BindingInit bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);

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

                    return new LetExpr(bindingInits,
                        new BodyExpr.Parser().Parse(body),
                        isLoop);
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Esempio n. 13
0
            public Expr Parse(object frm, bool isRecurContext)
            {
                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));

                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.GenerateAST(bindings.nth(i + 1),false);
                        // Sequential enhancement of env (like Lisp let*)
                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init);
                        BindingInit bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);

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

                    return new LetExpr(bindingInits,
                        new BodyExpr.Parser().Parse(body,isLoop || isRecurContext),
                        isLoop);
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Esempio n. 14
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();
                    }
                }
            }
Esempio n. 15
0
            public Expr Parse(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));

                // TODO: This is one place where context makes a difference.  Need to figure this out.
                //  Second test clause added in Rev 1216.
                // if (ctxt == C.EVAL || (context == c.EXPRESSION && isLoop))
                //    return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));

                // As of Rev 1216, I tried tjos out.
                // However, it goes into an infinite loop.  Still need to figure this out.
                //if (isLoop)
                //    Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));

                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.GenerateAST(bindings.nth(i + 1));
                        // Sequential enhancement of env (like Lisp let*)
                        LocalBinding b  = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init);
                        BindingInit  bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);

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

                    return(new LetExpr(bindingInits,
                                       new BodyExpr.Parser().Parse(body),
                                       isLoop));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }