Exemplo n.º 1
0
        public override void Accept(TupleExpression tuple)
        {
            IodineLabel startLabel = methodBuilder.CreateLabel();
            IodineLabel endLabel   = methodBuilder.CreateLabel();
            int         item       = methodBuilder.CreateTemporary();

            PatternCompiler compiler = new PatternCompiler(symbolTable, methodBuilder,
                                                           item,
                                                           parentVisitor);

            for (int i = 0; i < tuple.Children.Count; i++)
            {
                if (tuple.Children [i] is NameExpression &&
                    ((NameExpression)tuple.Children [i]).Value == "_")
                {
                    continue;
                }
                methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadLocal, temporary);
                methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadConst,
                                              methodBuilder.Module.DefineConstant(new IodineInteger(i)));
                methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadIndex);
                methodBuilder.EmitInstruction(tuple.Location, Opcode.StoreLocal, item);
                tuple.Children [i].Visit(compiler);
                methodBuilder.EmitInstruction(tuple.Location, Opcode.JumpIfFalse, endLabel);
            }
            methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadTrue);
            methodBuilder.EmitInstruction(tuple.Location, Opcode.Jump, startLabel);

            methodBuilder.MarkLabelPosition(endLabel);
            methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadFalse);

            methodBuilder.MarkLabelPosition(startLabel);
        }
Exemplo n.º 2
0
        public override void Accept(MatchExpression match)
        {
            AstNode value = match.Children [0];

            value.Visit(this);
            int temporary = methodBuilder.CreateTemporary();

            methodBuilder.EmitInstruction(match.Location, Opcode.StoreLocal, temporary);
            PatternCompiler compiler = new PatternCompiler(symbolTable, methodBuilder,
                                                           temporary,
                                                           this);
            IodineLabel nextLabel = methodBuilder.CreateLabel();
            IodineLabel endLabel  = methodBuilder.CreateLabel();

            for (int i = 1; i < match.Children.Count; i++)
            {
                if (i > 1)
                {
                    methodBuilder.MarkLabelPosition(nextLabel);
                    nextLabel = methodBuilder.CreateLabel();
                }
                CaseExpression clause = match.Children [i] as CaseExpression;
                clause.Pattern.Visit(compiler);
                methodBuilder.EmitInstruction(match.Location, Opcode.JumpIfFalse, nextLabel);
                if (clause.Condition != null)
                {
                    clause.Condition.Visit(this);
                    methodBuilder.EmitInstruction(match.Location, Opcode.JumpIfFalse, nextLabel);
                }
                clause.Value.Visit(this);
                methodBuilder.EmitInstruction(match.Location, Opcode.Jump, endLabel);
            }
            methodBuilder.MarkLabelPosition(endLabel);
        }
Exemplo n.º 3
0
        public override void Accept(ForeachStatement foreachStmt)
        {
            IodineLabel foreachLabel = methodBuilder.CreateLabel();
            IodineLabel breakLabel   = methodBuilder.CreateLabel();

            breakLabels.Push(breakLabel);
            continueLabels.Push(foreachLabel);
            foreachStmt.Iterator.Visit(this);
            int tmp = methodBuilder.CreateTemporary();

            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.Dup);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.StoreLocal, tmp);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.IterReset);
            methodBuilder.MarkLabelPosition(foreachLabel);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.LoadLocal, tmp);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.IterMoveNext);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.JumpIfFalse,
                                          breakLabel);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.LoadLocal, tmp);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.IterGetNext);
            methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.StoreLocal,
                                          symbolTable.GetSymbol
                                              (foreachStmt.Item).Index);
            foreachStmt.Body.Visit(this);
            methodBuilder.EmitInstruction(foreachStmt.Body.Location, Opcode.Jump, foreachLabel);
            methodBuilder.MarkLabelPosition(breakLabel);
            breakLabels.Pop();
            continueLabels.Pop();
        }
Exemplo n.º 4
0
        public override void Accept(TryExceptStatement tryExcept)
        {
            IodineLabel exceptLabel = methodBuilder.CreateLabel();
            IodineLabel endLabel    = methodBuilder.CreateLabel();

            methodBuilder.EmitInstruction(tryExcept.Location, Opcode.PushExceptionHandler, exceptLabel);
            tryExcept.TryBody.Visit(this);
            methodBuilder.EmitInstruction(tryExcept.TryBody.Location, Opcode.PopExceptionHandler);
            methodBuilder.EmitInstruction(tryExcept.TryBody.Location, Opcode.Jump, endLabel);
            methodBuilder.MarkLabelPosition(exceptLabel);
            tryExcept.TypeList.Visit(this);
            if (tryExcept.TypeList.Children.Count > 0)
            {
                methodBuilder.EmitInstruction(tryExcept.ExceptBody.Location, Opcode.BeginExcept,
                                              tryExcept.TypeList.Children.Count);
            }
            if (tryExcept.ExceptionIdentifier != null)
            {
                methodBuilder.EmitInstruction(tryExcept.ExceptBody.Location, Opcode.LoadException);
                methodBuilder.EmitInstruction(tryExcept.ExceptBody.Location, Opcode.StoreLocal,
                                              symbolTable.GetSymbol(tryExcept.ExceptionIdentifier).Index);
            }
            tryExcept.ExceptBody.Visit(this);
            methodBuilder.MarkLabelPosition(endLabel);
        }
Exemplo n.º 5
0
        public override void Accept(TernaryExpression ifExpr)
        {
            IodineLabel elseLabel = methodBuilder.CreateLabel();
            IodineLabel endLabel  = methodBuilder.CreateLabel();

            ifExpr.Condition.Visit(this);
            methodBuilder.EmitInstruction(ifExpr.Expression.Location, Opcode.JumpIfFalse, elseLabel);
            ifExpr.Expression.Visit(this);
            methodBuilder.EmitInstruction(ifExpr.ElseExpression.Location, Opcode.Jump, endLabel);
            methodBuilder.MarkLabelPosition(elseLabel);
            ifExpr.ElseExpression.Visit(this);
            methodBuilder.MarkLabelPosition(endLabel);
        }
Exemplo n.º 6
0
        public override void Accept(IfStatement ifStmt)
        {
            IodineLabel elseLabel = methodBuilder.CreateLabel();
            IodineLabel endLabel  = methodBuilder.CreateLabel();

            ifStmt.Condition.Visit(this);
            methodBuilder.EmitInstruction(ifStmt.Body.Location, Opcode.JumpIfFalse, elseLabel);
            ifStmt.Body.Visit(this);
            methodBuilder.EmitInstruction(ifStmt.ElseBody.Location, Opcode.Jump, endLabel);
            methodBuilder.MarkLabelPosition(elseLabel);
            ifStmt.ElseBody.Visit(this);
            methodBuilder.MarkLabelPosition(endLabel);
        }
Exemplo n.º 7
0
        public override void Accept(GivenStatement switchStmt)
        {
            foreach (AstNode node in switchStmt.WhenStatements.Children)
            {
                WhenStatement caseStmt = node as WhenStatement;
                caseStmt.Values.Visit(this);
                caseStmt.Body.Visit(this);
            }
            switchStmt.GivenValue.Visit(this);
            methodBuilder.EmitInstruction(switchStmt.Location, Opcode.SwitchLookup, switchStmt.WhenStatements.Children.Count);
            IodineLabel endLabel = methodBuilder.CreateLabel();

            methodBuilder.EmitInstruction(switchStmt.Location, Opcode.JumpIfTrue, endLabel);
            switchStmt.DefaultStatement.Visit(this);
            methodBuilder.MarkLabelPosition(endLabel);
        }
Exemplo n.º 8
0
        public override void Accept(DoStatement doStmt)
        {
            IodineLabel doLabel    = methodBuilder.CreateLabel();
            IodineLabel breakLabel = methodBuilder.CreateLabel();

            breakLabels.Push(breakLabel);
            continueLabels.Push(doLabel);
            methodBuilder.MarkLabelPosition(doLabel);
            doStmt.Body.Visit(this);
            doStmt.Condition.Visit(this);
            methodBuilder.EmitInstruction(doStmt.Condition.Location, Opcode.JumpIfTrue,
                                          doLabel);
            methodBuilder.MarkLabelPosition(breakLabel);
            breakLabels.Pop();
            continueLabels.Pop();
        }
Exemplo n.º 9
0
        public override void Accept(WhileStatement whileStmt)
        {
            IodineLabel whileLabel = methodBuilder.CreateLabel();
            IodineLabel breakLabel = methodBuilder.CreateLabel();

            breakLabels.Push(breakLabel);
            continueLabels.Push(whileLabel);
            methodBuilder.MarkLabelPosition(whileLabel);
            whileStmt.Condition.Visit(this);
            methodBuilder.EmitInstruction(whileStmt.Condition.Location, Opcode.JumpIfFalse,
                                          breakLabel);
            whileStmt.Body.Visit(this);
            methodBuilder.EmitInstruction(whileStmt.Body.Location, Opcode.Jump, whileLabel);
            methodBuilder.MarkLabelPosition(breakLabel);
            breakLabels.Pop();
            continueLabels.Pop();
        }
Exemplo n.º 10
0
        public override void Accept(ListCompExpression list)
        {
            IodineLabel foreachLabel  = methodBuilder.CreateLabel();
            IodineLabel breakLabel    = methodBuilder.CreateLabel();
            IodineLabel predicateSkip = methodBuilder.CreateLabel();
            int         tmp           = methodBuilder.CreateTemporary();
            int         set           = methodBuilder.CreateTemporary();

            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.BuildList, 0);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.StoreLocal, set);
            symbolTable.NextScope();
            list.Iterator.Visit(this);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.Dup);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.StoreLocal, tmp);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.IterReset);
            methodBuilder.MarkLabelPosition(foreachLabel);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, tmp);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.IterMoveNext);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.JumpIfFalse,
                                          breakLabel);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, tmp);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.IterGetNext);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.StoreLocal,
                                          symbolTable.GetSymbol
                                              (list.Identifier).Index);
            if (list.Predicate != null)
            {
                list.Predicate.Visit(this);
                methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.JumpIfFalse, predicateSkip);
            }
            list.Expression.Visit(this);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, set);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadAttribute,
                                          methodBuilder.Module.DefineConstant(new IodineName("add")));
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.Invoke, 1);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.Pop);
            if (list.Predicate != null)
            {
                methodBuilder.MarkLabelPosition(predicateSkip);
            }
            methodBuilder.EmitInstruction(list.Expression.Location, Opcode.Jump, foreachLabel);
            methodBuilder.MarkLabelPosition(breakLabel);
            methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, set);
            symbolTable.LeaveScope();
        }
Exemplo n.º 11
0
        public override void Accept(ForStatement forStmt)
        {
            IodineLabel forLabel         = methodBuilder.CreateLabel();
            IodineLabel breakLabel       = methodBuilder.CreateLabel();
            IodineLabel skipAfterThought = methodBuilder.CreateLabel();

            breakLabels.Push(breakLabel);
            continueLabels.Push(forLabel);
            forStmt.Initializer.Visit(this);
            methodBuilder.EmitInstruction(forStmt.Location, Opcode.Jump, skipAfterThought);
            methodBuilder.MarkLabelPosition(forLabel);
            forStmt.AfterThought.Visit(this);
            methodBuilder.MarkLabelPosition(skipAfterThought);
            forStmt.Condition.Visit(this);
            methodBuilder.EmitInstruction(forStmt.Condition.Location, Opcode.JumpIfFalse, breakLabel);
            forStmt.Body.Visit(this);
            forStmt.AfterThought.Visit(this);
            methodBuilder.EmitInstruction(forStmt.AfterThought.Location, Opcode.Jump, skipAfterThought);
            methodBuilder.MarkLabelPosition(breakLabel);
            breakLabels.Pop();
            continueLabels.Pop();
        }
Exemplo n.º 12
0
        public override void Accept(BinaryExpression pattern)
        {
            IodineLabel shortCircuitTrueLabel  = methodBuilder.CreateLabel();
            IodineLabel shortCircuitFalseLabel = methodBuilder.CreateLabel();
            IodineLabel endLabel = methodBuilder.CreateLabel();

            pattern.Left.Visit(this);

            /*
             * Short circuit evaluation
             */
            switch (pattern.Operation)
            {
            case BinaryOperation.And:
                methodBuilder.EmitInstruction(pattern.Location, Opcode.Dup);
                methodBuilder.EmitInstruction(pattern.Location, Opcode.JumpIfFalse,
                                              shortCircuitFalseLabel);
                break;

            case BinaryOperation.Or:
                methodBuilder.EmitInstruction(pattern.Location, Opcode.Dup);
                methodBuilder.EmitInstruction(pattern.Location, Opcode.JumpIfTrue,
                                              shortCircuitTrueLabel);
                break;
            }
            pattern.Right.Visit(this);

            methodBuilder.EmitInstruction(pattern.Location, Opcode.BinOp, (int)pattern.Operation);
            methodBuilder.EmitInstruction(pattern.Location, Opcode.Jump, endLabel);
            methodBuilder.MarkLabelPosition(shortCircuitTrueLabel);
            methodBuilder.EmitInstruction(pattern.Location, Opcode.Pop);
            methodBuilder.EmitInstruction(pattern.Location, Opcode.LoadTrue);
            methodBuilder.EmitInstruction(pattern.Location, Opcode.Jump, endLabel);
            methodBuilder.MarkLabelPosition(shortCircuitFalseLabel);
            methodBuilder.EmitInstruction(pattern.Location, Opcode.Pop);
            methodBuilder.EmitInstruction(pattern.Location, Opcode.LoadFalse);
            methodBuilder.MarkLabelPosition(endLabel);
        }
Exemplo n.º 13
0
        public override void Accept(BinaryExpression binop)
        {
            if (binop.Operation == BinaryOperation.Assign)
            {
                binop.Right.Visit(this);
                if (binop.Left is NameExpression)
                {
                    NameExpression ident = (NameExpression)binop.Left;
                    Symbol         sym   = symbolTable.GetSymbol(ident.Value);
                    if (sym.Type == SymbolType.Local)
                    {
                        methodBuilder.EmitInstruction(ident.Location, Opcode.StoreLocal, sym.Index);
                        methodBuilder.EmitInstruction(ident.Location, Opcode.LoadLocal, sym.Index);
                    }
                    else
                    {
                        int globalIndex = methodBuilder.Module.DefineConstant(new IodineName(ident.Value));
                        methodBuilder.EmitInstruction(ident.Location, Opcode.StoreGlobal, globalIndex);
                        methodBuilder.EmitInstruction(ident.Location, Opcode.LoadGlobal, globalIndex);
                    }
                }
                else if (binop.Left is GetExpression)
                {
                    GetExpression getattr = binop.Left as GetExpression;
                    getattr.Target.Visit(this);
                    int attrIndex = methodBuilder.Module.DefineConstant(new IodineName(getattr.Field));
                    methodBuilder.EmitInstruction(getattr.Location, Opcode.StoreAttribute, attrIndex);
                    getattr.Target.Visit(this);
                    methodBuilder.EmitInstruction(getattr.Location, Opcode.LoadAttribute, attrIndex);
                }
                else if (binop.Left is IndexerExpression)
                {
                    IndexerExpression indexer = binop.Left as IndexerExpression;
                    indexer.Target.Visit(this);
                    indexer.Index.Visit(this);
                    methodBuilder.EmitInstruction(indexer.Location, Opcode.StoreIndex);
                    binop.Left.Visit(this);
                }
            }
            else if (binop.Operation == BinaryOperation.InstanceOf)
            {
                binop.Right.Visit(this);
                binop.Left.Visit(this);
                methodBuilder.EmitInstruction(binop.Location, Opcode.InstanceOf);
            }
            else if (binop.Operation == BinaryOperation.NotInstanceOf)
            {
                binop.Right.Visit(this);
                binop.Left.Visit(this);
                methodBuilder.EmitInstruction(binop.Location, Opcode.InstanceOf);
                methodBuilder.EmitInstruction(binop.Location, Opcode.UnaryOp, (int)UnaryOperation.BoolNot);
            }
            else if (binop.Operation == BinaryOperation.DynamicCast)
            {
                binop.Right.Visit(this);
                binop.Left.Visit(this);
                methodBuilder.EmitInstruction(binop.Location, Opcode.DynamicCast);
            }
            else if (binop.Operation == BinaryOperation.NullCoalescing)
            {
                binop.Right.Visit(this);
                binop.Left.Visit(this);
                methodBuilder.EmitInstruction(binop.Location, Opcode.NullCoalesce);
            }
            else
            {
                IodineLabel shortCircuitTrueLabel  = methodBuilder.CreateLabel();
                IodineLabel shortCircuitFalseLabel = methodBuilder.CreateLabel();
                IodineLabel endLabel = methodBuilder.CreateLabel();
                binop.Left.Visit(this);

                /*
                 * Short circuit evaluation
                 */
                switch (binop.Operation)
                {
                case BinaryOperation.BoolAnd:
                    methodBuilder.EmitInstruction(binop.Location, Opcode.Dup);
                    methodBuilder.EmitInstruction(binop.Location, Opcode.JumpIfFalse,
                                                  shortCircuitFalseLabel);
                    break;

                case BinaryOperation.BoolOr:
                    methodBuilder.EmitInstruction(binop.Location, Opcode.Dup);
                    methodBuilder.EmitInstruction(binop.Location, Opcode.JumpIfTrue,
                                                  shortCircuitTrueLabel);
                    break;
                }
                binop.Right.Visit(this);
                methodBuilder.EmitInstruction(binop.Location, Opcode.BinOp, (int)binop.Operation);
                methodBuilder.EmitInstruction(binop.Location, Opcode.Jump, endLabel);
                methodBuilder.MarkLabelPosition(shortCircuitTrueLabel);
                methodBuilder.EmitInstruction(binop.Location, Opcode.Pop);
                methodBuilder.EmitInstruction(binop.Location, Opcode.LoadTrue);
                methodBuilder.EmitInstruction(binop.Location, Opcode.Jump, endLabel);
                methodBuilder.MarkLabelPosition(shortCircuitFalseLabel);
                methodBuilder.EmitInstruction(binop.Location, Opcode.Pop);
                methodBuilder.EmitInstruction(binop.Location, Opcode.LoadFalse);
                methodBuilder.MarkLabelPosition(endLabel);
            }
        }