Exemplo n.º 1
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.º 2
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);
            }
        }