예제 #1
0
        public override IUnboundExpr Transform(LetExpr expr)
        {
            // a let expression desugars like this:
            //
            //      let a b <- Foo then Bar else Bang
            //
            // becomes...
            //
            //      def let__ <- Foo
            //      if Some? let__ then
            //          def a b <- 0 SomeValue let__
            //          Bar
            //      else Bang
            var c = new CodeBuilder(mNameGenerator, expr.Position);
            var option = c.TempName();

            return c.Block(
                c.Def(option, expr.Condition),
                c.If(c.Call("Some?", option),
                    c.Block(
                        c.Def(expr.Names, c.Call("SomeValue", option)),
                        expr.ThenBody),
                    expr.ElseBody));
        }
예제 #2
0
        public override IUnboundExpr Transform(LetExpr expr)
        {
            // a let expression desugars like this:
            //
            //      let a b <- Foo then Bar else Bang
            //
            // becomes...
            //
            //      def let__ <- Foo
            //      if Some? let__ then
            //          def a b <- 0 SomeValue let__
            //          Bar
            //      else Bang
            var c      = new CodeBuilder(mNameGenerator, expr.Position);
            var option = c.TempName();

            return(c.Block(
                       c.Def(option, expr.Condition),
                       c.If(c.Call("Some?", option),
                            c.Block(
                                c.Def(expr.Names, c.Call("SomeValue", option)),
                                expr.ThenBody),
                            expr.ElseBody)));
        }
예제 #3
0
        public override IUnboundExpr Transform(LoopExpr expr)
        {
            // a for expression is basically syntactic sugar for a while expression
            // and one or more iterators. for example, the following:
            //
            // for foo <- bar do
            //     Print foo
            // end
            //
            // is equivalent to:
            //
            // def _fooIter <- Iterate bar
            // while MoveNext _fooIter do
            //     def foo <- Current _fooIter
            //     Print foo
            // end
            //
            // so, to bind a for expression, we just desugar it, then bind that.

            var c = new CodeBuilder(mNameGenerator, expr.Position);

            var topExprs = new List<IUnboundExpr>();
            var conditionExpr = (IUnboundExpr)null;
            var whileExprs = new List<IUnboundExpr>();

            // instantiate each clause
            foreach (var clause in expr.Clauses)
            {
                c.SetPosition(clause.Position);

                var condition = (IUnboundExpr)null;

                if (clause.IsWhile)
                {
                    condition = clause.Expression;
                }
                else
                {
                    var iterName = mNameGenerator.Generate();
                    topExprs.Add(c.Def(iterName, c.Call("Iterate", clause.Expression)));
                    whileExprs.Add(c.Def(clause.Name, c.Call("Current", iterName)));

                    condition = c.Call("MoveNext", iterName);
                }

                if (conditionExpr == null)
                {
                    conditionExpr = condition;
                }
                else
                {
                    // combine with previous condition(s)
                    conditionExpr = c.Op(conditionExpr, "&", condition);
                }
            }

            // create the while loop
            c.SetPosition(expr.Position);
            whileExprs.Add(expr.Body);
            var whileExpr = c.While(
                conditionExpr,
                c.Block(whileExprs));
            topExprs.Add(whileExpr);

            // build the whole block
            return c.Block(topExprs);
        }
예제 #4
0
        public override IUnboundExpr Transform(LoopExpr expr)
        {
            // a for expression is basically syntactic sugar for a while expression
            // and one or more iterators. for example, the following:
            //
            // for foo <- bar do
            //     Print foo
            // end
            //
            // is equivalent to:
            //
            // def _fooIter <- Iterate bar
            // while MoveNext _fooIter do
            //     def foo <- Current _fooIter
            //     Print foo
            // end
            //
            // so, to bind a for expression, we just desugar it, then bind that.

            var c = new CodeBuilder(mNameGenerator, expr.Position);

            var topExprs = new List<IUnboundExpr>();
            var conditionExpr = (IUnboundExpr)null;
            var whileExprs = new List<IUnboundExpr>();

            // instantiate each clause
            foreach (var clause in expr.Clauses)
            {
                c.SetPosition(clause.Position);

                var condition = (IUnboundExpr)null;

                if (clause.IsWhile)
                {
                    condition = clause.Expression;
                }
                else
                {
                    var iterName = mNameGenerator.Generate();
                    topExprs.Add(c.Def(iterName, c.Call("Iterate", clause.Expression)));
                    whileExprs.Add(c.Def(clause.Name, c.Call("Current", iterName)));

                    condition = c.Call("MoveNext", iterName);
                }

                if (conditionExpr == null)
                {
                    conditionExpr = condition;
                }
                else
                {
                    // combine with previous condition(s)
                    conditionExpr = c.Op(conditionExpr, "&", condition);
                }
            }

            // create the while loop
            c.SetPosition(expr.Position);
            whileExprs.Add(expr.Body);
            var whileExpr = c.While(
                conditionExpr,
                c.Block(whileExprs));
            topExprs.Add(whileExpr);

            // build the whole block
            return c.Block(topExprs);
        }