private IEnumerable<ITypeSymbol> InferTypeInPostfixUnaryExpression(PostfixUnaryExpressionSyntax postfixUnaryExpressionSyntax, SyntaxToken? previousToken = null)
            {
                // If we're after a postfix ++ or -- then we can't infer anything.
                if (previousToken.HasValue)
                {
                    return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
                }

                switch (postfixUnaryExpressionSyntax.CSharpKind())
                {
                    case SyntaxKind.PostDecrementExpression:
                    case SyntaxKind.PostIncrementExpression:
                        return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Int32));
                }

                return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
            }
Exemple #2
0
        public FlatOperand ResolveExpression(PostfixUnaryExpressionSyntax pues, TypeInfo result_type, FlatOperand into_lvalue, List<FlatStatement> instructions)
        {
            if (into_lvalue == null)
            {
                into_lvalue = this.AllocateRegister("");
                into_lvalue = into_lvalue.GetLValue(this, instructions);
            }

            SymbolInfo si = Model.GetSymbolInfo(pues.Operand);
            FlatOperand fop_subject;
            switch (si.Symbol.Kind)
            {
                case SymbolKind.Parameter:
                    {
                        IParameterSymbol ps = (IParameterSymbol)si.Symbol;

                        if (ps.RefKind == RefKind.None)
                        {
                            FlatOperand op = ResolveExpression(pues.Operand, null, instructions);

                            instructions.Add(FlatStatement.DUPLICATE(into_lvalue, op));

                            FlatOperand new_lvalue = op.GetLValue(this,instructions);

                            switch (pues.CSharpKind())
                            {
                                case SyntaxKind.PostIncrementExpression:
                                    instructions.Add(FlatStatement.ADD(new_lvalue, op, FlatOperand.Immediate(FlatValue.Int32(1))));
                                    instructions.Add(FlatStatement.ARRAYSET(FlatOperand.Inputs(), FlatOperand.Immediate(FlatValue.Int32(op.OperandIndex)), new_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType))));
                                    return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                                case SyntaxKind.PostDecrementExpression:
                                    instructions.Add(FlatStatement.SUB(new_lvalue, op, FlatOperand.Immediate(FlatValue.Int32(1))));
                                    instructions.Add(FlatStatement.ARRAYSET(FlatOperand.Inputs(), FlatOperand.Immediate(FlatValue.Int32(op.OperandIndex)), new_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType))));
                                    return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                            }

                        }
                        else
                        {
                            int numParam = 0;
                            FlatOperand fop_duplicate = ResolveParameter(pues.Operand, null, out numParam, instructions);
                            FlatOperand new_lvalue = fop_duplicate.GetLValue(this, instructions);

                            instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_duplicate));
                            switch (pues.CSharpKind())
                            {
                                case SyntaxKind.PostIncrementExpression:
                                    instructions.Add(FlatStatement.ADD(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1))));
                                    instructions.Add(FlatStatement.REREFERENCE(FlatOperand.InputRef(numParam,fop_duplicate.ImmediateValue), fop_duplicate));
                                    return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                                case SyntaxKind.PostDecrementExpression:
                                    instructions.Add(FlatStatement.SUB(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1))));
                                    instructions.Add(FlatStatement.REREFERENCE(FlatOperand.InputRef(numParam, fop_duplicate.ImmediateValue), fop_duplicate));
                                    return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                            }

                            /*
                            FlatOperand fop_duplicate = AllocateRegister("local_" + op.ToString());
                            FlatOperand new_lvalue = fop_duplicate.GetLValue(this, instructions);

                            instructions.Add(FlatStatement.DEREFERENCE(new_lvalue, op));
                            instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_duplicate));

                            switch (pues.CSharpKind())
                            {
                                case SyntaxKind.PostIncrementExpression:
                                    instructions.Add(FlatStatement.ADD(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1))));
                                    instructions.Add(FlatStatement.REREFERENCE(op, fop_duplicate));
                                    return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                                case SyntaxKind.PostDecrementExpression:
                                    instructions.Add(FlatStatement.SUB(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1))));
                                    instructions.Add(FlatStatement.REREFERENCE(op, fop_duplicate));
                                    return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                            }
                             * */
                        }

                        // reference
                        /*
                        if (node.CSharpKind() == SyntaxKind.SimpleAssignmentExpression)
                        {
                            FlatOperand fop_right = ResolveExpression(node.Right, into_lvalue, instructions);

                            instructions.Add(FlatStatement.REREFERENCE(fop_subject, fop_right));
                            return fop_right;
                        }
                        else
                        {
                            FlatOperand fop_right = ResolveExpression(node.Right, into_lvalue, instructions);

                            FlatOperand fop_duplicate = AllocateRegister("local_" + fop_subject.ToString());
                            FlatOperand lvalue_final = fop_duplicate.GetLValue(this, instructions);

                            instructions.Add(FlatStatement.DEREFERENCE(lvalue_final, fop_subject));

                            ResolveBinaryExpression(node.CSharpKind(), fop_duplicate, fop_right, lvalue_final, instructions);

                            instructions.Add(FlatStatement.REREFERENCE(fop_subject, fop_duplicate));
                            return fop_subject;
                        }
                         */
                    }
                    break;
                case SymbolKind.Event:
                    {
                        IEventSymbol fs = (IEventSymbol)si.Symbol;
                        fop_subject = ResolveParentExpression(si, pues.Operand, null, null, instructions);
                        //FlatOperand fop_type = TypeOf(fop_subject, null, null, instructions);
                        FlatOperand fop_type = Resolve(si.Symbol.ContainingType, null, instructions);

                        FlatOperand fop_Field;
                        ITypeSymbol typeSymbol;
                        {

                            typeSymbol = fs.Type;
                            fop_Field = Resolve(fs, fop_type, null, instructions);
                        }

                        FlatOperand fop_currentvalue = this.AllocateRegister("");
                        FlatOperand fop_currentlvalue = fop_currentvalue.GetLValue(this, instructions);

                        if (fs.IsStatic)
                            instructions.Add(FlatStatement.GETSTATICFIELD(fop_currentlvalue, fop_Field));
                        else
                            instructions.Add(FlatStatement.GETFIELD(fop_currentlvalue, fop_Field, fop_subject));
                        instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_currentvalue));

                        switch (pues.CSharpKind())
                        {
                            case SyntaxKind.PostIncrementExpression:
                                instructions.Add(FlatStatement.ADD(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1))));
                                break;
                            case SyntaxKind.PostDecrementExpression:
                                instructions.Add(FlatStatement.SUB(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1))));
                                break;
                        }

                        if (fs.IsStatic)
                            instructions.Add(FlatStatement.SETSTATICFIELD(fop_Field, fop_currentvalue));
                        else
                            instructions.Add(FlatStatement.SETFIELD(fop_Field, fop_subject, fop_currentvalue));
                        return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                    }
                    break;
                case SymbolKind.Field:
                    {
                        IFieldSymbol fs = (IFieldSymbol)si.Symbol;
                        fop_subject = ResolveParentExpression(si, pues.Operand, null, null, instructions);
                        //FlatOperand fop_type = TypeOf(fop_subject, null, null, instructions);
                        FlatOperand fop_type = Resolve(si.Symbol.ContainingType, null, instructions);

                        FlatOperand fop_Field;
                        ITypeSymbol typeSymbol;
                        {

                            typeSymbol = fs.Type;
                            fop_Field = Resolve(fs, fop_type, null, instructions);
                        }

                        FlatOperand fop_currentvalue = this.AllocateRegister("");
                        FlatOperand fop_currentlvalue = fop_currentvalue.GetLValue(this, instructions);

                        if (fs.IsStatic)
                            instructions.Add(FlatStatement.GETSTATICFIELD(fop_currentlvalue, fop_Field));
                        else
                            instructions.Add(FlatStatement.GETFIELD(fop_currentlvalue, fop_Field, fop_subject));
                        instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_currentvalue));

                        switch (pues.CSharpKind())
                        {
                            case SyntaxKind.PostIncrementExpression:
                                instructions.Add(FlatStatement.ADD(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1))));
                                break;
                            case SyntaxKind.PostDecrementExpression:
                                instructions.Add(FlatStatement.SUB(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1))));
                                break;
                        }

                        if (fs.IsStatic)
                            instructions.Add(FlatStatement.SETSTATICFIELD(fop_Field, fop_currentvalue));
                        else
                            instructions.Add(FlatStatement.SETFIELD(fop_Field, fop_subject, fop_currentvalue));
                        return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                    }
                    break;
                case SymbolKind.Property:
                    {
                        IPropertySymbol ps = (IPropertySymbol)si.Symbol;

                        fop_subject = ResolveParentExpression(si, pues.Operand, null, null, instructions);
                        FlatOperand fop_type;

                        if (ps.IsStatic)
                            fop_type = fop_subject;
                        else
                            fop_type = TypeOf(fop_subject, null, null, instructions);

                        FlatOperand fop_property;
                        ITypeSymbol typeSymbol;
                        {

            //                            if (ps.IsStatic)
            //                            {
            //                                throw new NotImplementedException("static property postfix unary assignment");
            //                            }

                            typeSymbol = ps.Type;
                            fop_property = Resolve(ps, fop_type, null, instructions);
                        }

                        FlatOperand fop_currentvalue = this.AllocateRegister("");
                        FlatOperand fop_currentlvalue = fop_currentvalue.GetLValue(this, instructions);

                        if (ps.IsStatic)
                            instructions.Add(FlatStatement.GETSTATICPROPERTY(fop_currentlvalue, fop_property));
                        else
                            instructions.Add(FlatStatement.GETPROPERTY(fop_currentlvalue, fop_property, fop_subject));
                        instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_currentvalue));

                        switch (pues.CSharpKind())
                        {
                            case SyntaxKind.PostIncrementExpression:
                                instructions.Add(FlatStatement.ADD(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1))));
                                break;
                            case SyntaxKind.PostDecrementExpression:
                                instructions.Add(FlatStatement.SUB(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1))));
                                break;
                        }
                        if (ps.IsStatic)
                            instructions.Add(FlatStatement.SETSTATICPROPERTY(fop_property, fop_currentvalue));
                        else
                            instructions.Add(FlatStatement.SETPROPERTY(fop_property, fop_subject, fop_currentvalue));
                        return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                    }
                    break;
                case SymbolKind.Local:
                    {
                        FlatOperand op = ResolveExpression(pues.Operand, null, instructions);

                        instructions.Add(FlatStatement.DUPLICATE(into_lvalue, op));

                        switch (pues.CSharpKind())
                        {
                            case SyntaxKind.PostIncrementExpression:
                                instructions.Add(FlatStatement.ADD(op.GetLValue(this, instructions), op, FlatOperand.Immediate(FlatValue.Int32(1))));
                                return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                            case SyntaxKind.PostDecrementExpression:
                                instructions.Add(FlatStatement.SUB(op.GetLValue(this, instructions), op, FlatOperand.Immediate(FlatValue.Int32(1))));
                                return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType));
                        }
                    }
                    break;

            }

            throw new NotImplementedException("postfix unary " + pues.CSharpKind().ToString() + " - " + si.Symbol.Kind.ToString());
        }