Beispiel #1
0
        public Statement GetStatement()
        {
            var statement = new UnaryStatement
            {
                Operand = statementInterpreterHandler.GetStatement(prefixUnaryExpressionSyntax.Operand)
            };

            switch (prefixUnaryExpressionSyntax.Kind())
            {
            case Microsoft.CodeAnalysis.CSharp.SyntaxKind.PreDecrementExpression:
                statement.Operator = UnaryOperand.PreDecrementAssign;
                break;

            case Microsoft.CodeAnalysis.CSharp.SyntaxKind.PreIncrementExpression:
                statement.Operator = UnaryOperand.PreIncrementAssign;
                break;

            case Microsoft.CodeAnalysis.CSharp.SyntaxKind.LogicalNotExpression:
                statement.Operator = UnaryOperand.Not;
                break;

            case Microsoft.CodeAnalysis.CSharp.SyntaxKind.BitwiseNotExpression:
                statement.Operator = UnaryOperand.OnesComplement;
                break;

            default:
                throw new NotSupportedException(prefixUnaryExpressionSyntax.Kind() + " is not supported unary operation");
            }
            return(statement);
        }
Beispiel #2
0
        public override BoundNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            MethodSymbol unaryMethodSymbol = (MethodSymbol)GetSymbol(node);

            BoundExpression expression = VisitExpression(node.Operand, unaryMethodSymbol.Parameters[0].Type);

            // + operator is a no-op on builtins so ignore it until we allow user operator overloads
            if (node.OperatorToken.Kind() == SyntaxKind.PlusToken)
            {
                return(expression);
            }

            BoundExpression constantResult = ConstantExpressionOptimizer.FoldConstantUnaryPrefixExpression(Context, node, unaryMethodSymbol, expression);

            if (constantResult != null)
            {
                return(constantResult);
            }

            if (node.Kind() == SyntaxKind.PreIncrementExpression ||
                node.Kind() == SyntaxKind.PreDecrementExpression)
            {
                return(new BoundInvocationExpression.BoundPrefixOperatorExpression(Context, node,
                                                                                   (BoundAccessExpression)expression, unaryMethodSymbol));
            }

            return(BoundInvocationExpression.CreateBoundInvocation(Context, node, unaryMethodSymbol, null, new[] { expression }));
        }
        public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            node = (PrefixUnaryExpressionSyntax)base.VisitPrefixUnaryExpression(node);

            if (transformKind == TransformKind.PrefixToPostfix)
            {
                var operatorToken = node.OperatorToken;
                var operand       = node.Operand;

                var newOperatorToken = SyntaxFactory.Token(SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker), operatorToken.Kind(), operand.GetTrailingTrivia());
                var newOperand       = operand.WithTrailingTrivia(operatorToken.TrailingTrivia);
                newOperand = newOperand.WithLeadingTrivia(operatorToken.LeadingTrivia);

                if (node.Kind() == SyntaxKind.PreIncrementExpression)
                {
                    return(SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, newOperand, newOperatorToken));
                }

                if (node.Kind() == SyntaxKind.PreDecrementExpression)
                {
                    return(SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostDecrementExpression, newOperand, newOperatorToken));
                }
            }

            return(node);
        }
Beispiel #4
0
            public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
            {
                base.VisitPrefixUnaryExpression(node);
                bool invalid = false;

                switch (node.Kind())
                {
                case SyntaxKind.UnaryMinusExpression:
                case SyntaxKind.UnaryPlusExpression:
                    if (Values.Count < 1)
                    {
                        invalid = true;
                        Errors.Add(RateRulesErrors.MissingArgument);
                    }
                    break;

                default:
                    invalid = true;
                    Errors.Add(RateRulesErrors.UnsupportedOperator);
                    break;
                }

                if (invalid)
                {
                    return;
                }

                switch (node.Kind())
                {
                case SyntaxKind.UnaryMinusExpression:
                    var v = Values.Pop();
                    if (v.Bid == v.Ask)
                    {
                        Values.Push(-v);
                    }
                    else
                    {
                        Errors.Add(RateRulesErrors.InvalidNegative);
                    }
                    break;

                case SyntaxKind.UnaryPlusExpression:
                    Values.Push(+Values.Pop());
                    break;

                default:
                    throw new NotSupportedException("Should never happen");
                }
            }
Beispiel #5
0
        private ExpressionSyntax DifferentiateExpression(
            PrefixUnaryExpressionSyntax expression, SyntaxToken x)
        {
            var innerDerivative = DifferentiateExpression(expression.Operand, x);

            switch (expression.Kind())
            {
            case SyntaxKind.UnaryPlusExpression:
            case SyntaxKind.UnaryMinusExpression:
                return(expression.WithOperand(innerDerivative));

            default:
                throw new ArgumentException($"Unexpected syntax kind: {expression.Kind()}");
            }
        }
Beispiel #6
0
        private static ITranslationUnit BuildUnaryExpressionTranslationUnit(PrefixUnaryExpressionSyntax expression, SemanticModel semanticModel)
        {
            OperatorToken token = OperatorToken.Undefined;

            switch (expression.Kind())
            {
            case SyntaxKind.PreIncrementExpression:
                token = OperatorToken.Increment;
                break;

            case SyntaxKind.PreDecrementExpression:
                token = OperatorToken.Decrement;
                break;

            case SyntaxKind.LogicalNotExpression:
                token = OperatorToken.LogicalNot;
                break;
            }

            if (token == OperatorToken.Undefined)
            {
                throw new InvalidOperationException("Unary operator could not be detected!");
            }

            UnaryExpression  unaryExpressionHelper = new UnaryExpression(expression, semanticModel);
            ITranslationUnit operand = new ExpressionTranslationUnitBuilder(unaryExpressionHelper.Operand, semanticModel).Build();

            return(UnaryExpressionTranslationUnit.Create(operand, token, UnaryExpressionTranslationUnit.UnaryPosition.Prefix));
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);

            PrefixUnaryExpressionSyntax prefixUnaryExpression = root
                                                                .FindNode(context.Span, getInnermostNodeForTie: true)?
                                                                .FirstAncestorOrSelf <PrefixUnaryExpressionSyntax>();

            if (prefixUnaryExpression == null)
            {
                return;
            }

            switch (prefixUnaryExpression.Kind())
            {
            case SyntaxKind.PreIncrementExpression:
            {
                PreIncrementToPostIncrement(context, prefixUnaryExpression);
                PreIncrementToPreDecrement(context, prefixUnaryExpression);
                break;
            }

            case SyntaxKind.PreDecrementExpression:
            {
                PreDecrementToPostDecrement(context, prefixUnaryExpression);
                PreDecrementToPreIncrement(context, prefixUnaryExpression);
                break;
            }
            }
        }
Beispiel #8
0
        public static void Write(PrefixUnaryExpressionSyntax syntax, IIndentedTextWriterWrapper textWriter, IContext context)
        {
            var kind = syntax.Kind();

            if (kind == SyntaxKind.UnaryMinusExpression)
            {
                textWriter.Write("-");
                syntax.Operand.Write(textWriter, context);
            }
            else if (kind == SyntaxKind.UnaryPlusExpression)// TODO handle LogicalNotExpression as well.
            {
                textWriter.Write("+");
                syntax.Operand.Write(textWriter, context);
            }
            else if (kind == SyntaxKind.LogicalNotExpression)
            {
                textWriter.Write("not(");
                syntax.Operand.Write(textWriter, context);
                textWriter.Write(")");
            }
            else
            {
                throw new Exception($"Unhandled PrefixUnaryExpressionSyntax kind {kind}.");
            }
        }
Beispiel #9
0
        private static T GetNotNullObjectArgumentIdentifyerSyntax <T>(PrefixUnaryExpressionSyntax unaryArgumentExpression)
            where T : ExpressionSyntax
        {
            if (unaryArgumentExpression?.Kind() != SyntaxKind.LogicalNotExpression)
            {
                return(null);
            }

            var invocationExpressionSyntax = unaryArgumentExpression.Operand as InvocationExpressionSyntax;

            if (invocationExpressionSyntax == null)
            {
                return(null);
            }

            var expressionValue = invocationExpressionSyntax.Expression?.ToString();

            if (expressionValue == null)
            {
                return(null);
            }

            var nullStringChecks = new[] { "string.IsNullOrEmpty", "string.IsNullOrWhitespace" };

            if (nullStringChecks.Any(item => string.Equals(expressionValue, item, StringComparison.OrdinalIgnoreCase)))
            {
                var arguments = invocationExpressionSyntax.ArgumentList?.Arguments ?? new SeparatedSyntaxList <ArgumentSyntax>();
                if (arguments.Count != 1)
                {
                    return(null);
                }

                return(arguments.Single()?.Expression as T);
            }

            expressionValue = expressionValue.Split('.').Last();
            var nullObjectChecks = new[] { "Equals", "ReferenceEquals" };

            if (nullObjectChecks.Any(item => string.Equals(expressionValue, item, StringComparison.OrdinalIgnoreCase)))
            {
                var arguments = invocationExpressionSyntax.ArgumentList?.Arguments ?? new SeparatedSyntaxList <ArgumentSyntax>();
                if (arguments.Count != 2)
                {
                    return(null);
                }

                if (arguments[0]?.Expression?.Kind() == SyntaxKind.NullLiteralExpression)
                {
                    return(arguments[1]?.Expression as T);
                }

                if (arguments[1]?.Expression?.Kind() == SyntaxKind.NullLiteralExpression)
                {
                    return(arguments[0]?.Expression as T);
                }
            }

            return(null);
        }
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            if (node.Kind() != SyntaxKind.LogicalNotExpression)
            {
                throw new InvalidPreprocessorExpressionException("Expected logical not expression");
            }

            node.Operand.Accept(this);
        }
        public override Tristate VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            if (node.Kind() != SyntaxKind.LogicalNotExpression)
            {
                throw new InvalidPreprocessorExpressionException("Expected logical not expression");
            }

            return(!node.Operand.Accept(this));
        }
            public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
            {
                base.VisitPrefixUnaryExpression(node);

                if (UnaryOperationsForChecked.Contains(node.Kind()))
                {
                    SetHasIntegralOperation(node);
                }
            }
Beispiel #13
0
 public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
 {
     if (node.Kind().Is(SyntaxKind.AddressOfExpression, SyntaxKind.PointerIndirectionExpression))
     {
         ContainsUnsafe = true;
     }
     else
     {
         base.VisitPrefixUnaryExpression(node);
     }
 }
Beispiel #14
0
        private string ParsePrefixUnary(PrefixUnaryExpressionSyntax syntax)
        {
            switch (syntax.Kind())
            {
            case SyntaxKind.UnaryPlusExpression:
                return($"+{ParseExpression(syntax.Operand)}");

            case SyntaxKind.UnaryMinusExpression:
                return($"-{ParseExpression(syntax.Operand)}");
            }
            return(ParseUnknown(syntax));
        }
Beispiel #15
0
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.LogicalNotExpression:
                break;

            default:
                this.HandleAssignedValue(node.Operand, node);
                break;
            }

            base.VisitPrefixUnaryExpression(node);
        }
Beispiel #16
0
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.LogicalNotExpression:
                break;

            default:
                this.mutations.Add(node);
                break;
            }

            base.VisitPrefixUnaryExpression(node);
        }
Beispiel #17
0
 public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
 {
     if (node.Kind() == SyntaxKind.AddressOfExpression &&
         node.Operand is IdentifierNameSyntax identifierName)
     {
         if (Identifiers.Contains(identifierName.Identifier.ValueText))
         {
             IsMatch = true;
         }
     }
     else
     {
         base.VisitPrefixUnaryExpression(node);
     }
 }
        public static void ComputeRefactorings(RefactoringContext context, PrefixUnaryExpressionSyntax prefixUnaryExpression)
        {
            SyntaxKind kind = prefixUnaryExpression.Kind();

            if (kind == SyntaxKind.PreIncrementExpression)
            {
                ReplacePreIncrementWithPostIncrement(context, prefixUnaryExpression);
                ReplacePreIncrementWithPreDecrement(context, prefixUnaryExpression);
            }
            else if (kind == SyntaxKind.PreDecrementExpression)
            {
                ReplacePreDecrementWithPostDecrement(context, prefixUnaryExpression);
                ReplacePreDecrementWithPreIncrement(context, prefixUnaryExpression);
            }
        }
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.LogicalNotExpression:
                TState trueState;
                TState falseState;
                this.VisitCondition(node, out trueState, out falseState);
                this.SetState(node.EndLocation(), (TState)trueState.Join(falseState));
                break;

            default:
                base.VisitPrefixUnaryExpression(node);
                break;
            }
        }
Beispiel #20
0
        public override AccessorOrMutator VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            var operand = Visit(node.Operand);

            switch (node.Kind())
            {
            case SyntaxKind.PreIncrementExpression:
            case SyntaxKind.PreDecrementExpression:
            {
                var accessor = operand as Accessor;
                if (accessor != null)
                {
                    var methodSymbol = Model.GetSymbolInfo(node).Symbol as IMethodSymbol;
                    if (methodSymbol != null)
                    {
                        var result = Lifter.LiftInstanceNonVoidNullaryMethod(methodSymbol)(accessor.GetMutator(this));
                        accessor.AcceptAssignment(this, result.Item1);
                        return(result.Item2);
                    }
                }
                break;
            }

            case SyntaxKind.UnaryPlusExpression:
            case SyntaxKind.UnaryMinusExpression:
            case SyntaxKind.BitwiseNotExpression:
            case SyntaxKind.LogicalNotExpression:
            {
                var methodSymbol = Model.GetSymbolInfo(node).Symbol as IMethodSymbol;
                if (methodSymbol != null)
                {
                    return(Lifter.LiftStaticNonVoidUnaryMethod(methodSymbol)(operand.GetMutator(this)));
                }
                else if (node.Operand is LiteralExpressionSyntax)
                {
                    var literalExpr = operand.GetMutator(this).CreateUpdate();
                    if (literalExpr is BitVecExpr)
                    {
                        return(operand.GetMutator(this).WithValue(Ctx.MkBVNeg((BitVecExpr)literalExpr)));
                    }
                    throw new SyntaxErrorException("Unsupported literal syntax: " + node);
                }
                break;
            }
            }
            throw new SyntaxErrorException("Unsupported syntax: " + node);
        }
Beispiel #21
0
        /// <inheritdoc />
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            if (node is null)
            {
                throw new System.ArgumentNullException(nameof(node));
            }

            switch (node.Kind())
            {
                case SyntaxKind.LogicalNotExpression:
                    break;
                default:
                    this.prefixUnaries.Add(node);
                    break;
            }

            base.VisitPrefixUnaryExpression(node);
        }
            public override Expression VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
            {
                if (_proofSemantics && !node.IsMemberMethodOfPrimitiveType(_semanticModel))
                {
                    throw new UnsupportedSyntaxException($"detected overloaded unary operator '{node}'");
                }

                var operand = node.Operand.Accept(this);

                switch (node.Kind())
                {
                case SyntaxKind.UnaryMinusExpression:
                    return(new UnaryMinusExpression(operand));

                case SyntaxKind.LogicalNotExpression:
                    return(new ComparisonExpression("!=", operand, new GenericLiteralExpression()));

                default:
                    throw new UnsupportedSyntaxException(node);
                }
            }
Beispiel #23
0
        public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            if (node.Kind() != SyntaxKind.LogicalNotExpression)
            {
                throw new InvalidPreprocessorExpressionException("Expected logical not expression");
            }

            var newExpression = (ExpressionSyntax)node.Operand.Accept(this);

            if (newExpression.Kind() == SyntaxKind.LogicalNotExpression)
            {
                return(((PrefixUnaryExpressionSyntax)newExpression).Operand
                       .WithLeadingTrivia(node.GetLeadingTrivia())
                       .WithTrailingTrivia(node.GetTrailingTrivia()));
            }
            else
            {
                return(node.Operand != newExpression?
                       node.WithOperand(newExpression) : node);
            }
        }
Beispiel #24
0
        public static void ComputeRefactorings(RefactoringContext context, PrefixUnaryExpressionSyntax prefixUnaryExpression)
        {
            if (!context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(prefixUnaryExpression.OperatorToken))
            {
                return;
            }

            switch (prefixUnaryExpression.Kind())
            {
            case SyntaxKind.PreIncrementExpression:
            {
                InvertPreIncrement(context, prefixUnaryExpression);
                ReplacePreIncrementWithPostIncrement(context, prefixUnaryExpression);
                break;
            }

            case SyntaxKind.PreDecrementExpression:
            {
                InvertPreDecrement(context, prefixUnaryExpression);
                ReplacePreDecrementWithPostDecrement(context, prefixUnaryExpression);
                break;
            }
            }
        }
Beispiel #25
0
        private BoundLiteral BindIntegralMinValConstants(PrefixUnaryExpressionSyntax node, BoundExpression operand, DiagnosticBag diagnostics)
        {
            // SPEC: To permit the smallest possible int and long values to be written as decimal integer 
            // SPEC: literals, the following two rules exist:

            // SPEC: When a decimal-integer-literal with the value 2147483648 and no integer-type-suffix 
            // SPEC: appears as the token immediately following a unary minus operator token, the result is a 
            // SPEC: constant of type int with the value −2147483648. 

            // SPEC: When a decimal-integer-literal with the value 9223372036854775808 and no integer-type-suffix 
            // SPEC: or the integer-type-suffix L or l appears as the token immediately following a unary minus 
            // SPEC: operator token, the result is a constant of type long with the value −9223372036854775808. 

            if (node.Kind() != SyntaxKind.UnaryMinusExpression)
            {
                return null;
            }

            if (node.Operand != operand.Syntax || operand.Syntax.Kind() != SyntaxKind.NumericLiteralExpression)
            {
                return null;
            }

            var literal = (LiteralExpressionSyntax)operand.Syntax;
            var token = literal.Token;
            if (token.Value is uint)
            {
                uint value = (uint)token.Value;
                if (value != 2147483648U)
                {
                    return null;
                }

                if (token.Text.Contains("u") || token.Text.Contains("U") || token.Text.Contains("l") || token.Text.Contains("L"))
                {
                    return null;
                }

                return new BoundLiteral(node, ConstantValue.Create((int)-2147483648), GetSpecialType(SpecialType.System_Int32, diagnostics, node));
            }
            else if (token.Value is ulong)
            {
                var value = (ulong)token.Value;
                if (value != 9223372036854775808UL)
                {
                    return null;
                }

                if (token.Text.Contains("u") || token.Text.Contains("U"))
                {
                    return null;
                }

                return new BoundLiteral(node, ConstantValue.Create(-9223372036854775808), GetSpecialType(SpecialType.System_Int64, diagnostics, node));
            }

            return null;
        }
Beispiel #26
0
 private BoundExpression BindUnaryOperator(PrefixUnaryExpressionSyntax node, DiagnosticBag diagnostics)
 {
     BoundExpression operand = BindValue(node.Operand, diagnostics, GetUnaryAssignmentKind(node.Kind()));
     BoundLiteral constant = BindIntegralMinValConstants(node, operand, diagnostics);
     return constant ?? BindUnaryOperatorCore(node, node.OperatorToken.Text, operand, diagnostics);
 }
Beispiel #27
0
        // Based on ExpressionBinder::bindPtrIndirection.
        private BoundExpression BindPointerIndirectionExpression(PrefixUnaryExpressionSyntax node, DiagnosticBag diagnostics)
        {
            BoundExpression operand = BindValue(node.Operand, diagnostics, GetUnaryAssignmentKind(node.Kind()));

            TypeSymbol pointedAtType;
            bool hasErrors;
            BindPointerIndirectionExpressionInternal(node, operand, diagnostics, out pointedAtType, out hasErrors);

            return new BoundPointerIndirectionOperator(node, operand, pointedAtType ?? CreateErrorType(), hasErrors);
        }
        public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            if (node.Kind() != SyntaxKind.UnaryMinusExpression)
            {
                return(base.VisitPrefixUnaryExpression(node));
            }
            var expression = node.Operand;

            if (expression.Kind() != SyntaxKind.NumericLiteralExpression)
            {
                return(base.VisitPrefixUnaryExpression(node));
            }

            CheckCastContex(node);

            string      value    = node.ToString();
            bool        found    = false;
            VirtualData constant = null;

            foreach (var data in _virtualizationContext.data)
            {
                if (value.Equals(data.Name))
                {
                    found    = true;
                    constant = data;
                    break;
                }
            }
            if (!found)
            {
                int              index          = _virtualizationContext.DataIndex;
                string           name           = value;
                SyntaxAnnotation indexMarker    = new SyntaxAnnotation("index", index + "");
                SyntaxAnnotation nameMarker     = new SyntaxAnnotation("name", name);
                SyntaxAnnotation constantMarker = new SyntaxAnnotation("type", "constant");
                SyntaxAnnotation codeMarker     = new SyntaxAnnotation("code", "undefined");
                SyntaxAnnotation uniqueMarker   = new SyntaxAnnotation("unique", "" + VirtualizationContext.UniqueId);

                constant       = new VirtualData();
                constant.Index = index;
                constant.Name  = name;
                var typeInfo = _virtualizationContext.semanticModel.GetTypeInfo(node);
                var info     = typeInfo.Type.ToString();
                constant.Type         = info;
                constant.Node         = node;
                constant.DefaultValue = node;
                constant.Annotations.Add(indexMarker);
                constant.Annotations.Add(nameMarker);
                constant.Annotations.Add(constantMarker);
                constant.Annotations.Add(codeMarker);
                constant.Annotations.Add(uniqueMarker);
                _virtualizationContext.data.Add(constant);
            }

            //            constants.Add(node);



            ExpressionSyntax newNode = SyntaxFactoryExtensions.DataCodeVirtualAccess();

            newNode = newNode.WithAdditionalAnnotations(constant.Annotations);
            ExpressionSyntax newExpression;

            if (CastEnabled)
            {
                newExpression = SyntaxFactory.CastExpression(SyntaxFactory.IdentifierName
                                                             (
                                                                 @"" + constant.Type
                                                             ),
                                                             newNode
                                                             );
            }
            else
            {
                newExpression = newNode;
            }

            //TODO: add annotations + comments
            newExpression = newExpression.WithLeadingTrivia(node.GetLeadingTrivia())
                            .WithTrailingTrivia(node.GetTrailingTrivia())
            ;

            return(newExpression);
        }
Beispiel #29
0
 public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
 {
     if (node.IsKind(SK.PreIncrementExpression) ||
         node.IsKind(SK.PreDecrementExpression))
     {
         var identifier = ((IdentifierNameSyntax)node.Operand).Identifier.Text;
         SMS.Update(identifier, node);
     }
     else if (node.IsKind(SK.UnaryMinusExpression))
     {
         return(base.VisitPrefixUnaryExpression(node));
     }
     else
     {
         throw new NotImplementedException("Unsupported PrefixUnaryExpression: " + node.Kind());
     }
     return(base.VisitPrefixUnaryExpression(node));
 }
Beispiel #30
0
        public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            node = (PrefixUnaryExpressionSyntax)base.VisitPrefixUnaryExpression(node);

            if (transformKind == TransformKind.PrefixToPostfix)
            {
                var operatorToken = node.OperatorToken;
                var operand = node.Operand;

                var newOperatorToken = SyntaxFactory.Token(SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker), operatorToken.Kind(), operand.GetTrailingTrivia());
                var newOperand = operand.WithTrailingTrivia(operatorToken.TrailingTrivia);
                newOperand = newOperand.WithLeadingTrivia(operatorToken.LeadingTrivia);

                if (node.Kind() == SyntaxKind.PreIncrementExpression)
                {
                    return SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, newOperand, newOperatorToken);
                }

                if (node.Kind() == SyntaxKind.PreDecrementExpression)
                {
                    return SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostDecrementExpression, newOperand, newOperatorToken);
                }
            }

            return node;
        }
        public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            if (node.Kind() != SyntaxKind.LogicalNotExpression)
            {
                throw new InvalidPreprocessorExpressionException("Expected logical not expression");
            }

            var newExpression = (ExpressionSyntax)node.Operand.Accept(this);
            if (newExpression.Kind() == SyntaxKind.LogicalNotExpression)
            {
                return ((PrefixUnaryExpressionSyntax)newExpression).Operand
                    .WithLeadingTrivia(node.GetLeadingTrivia())
                    .WithTrailingTrivia(node.GetTrailingTrivia());
            }
            else
            {
                return node.Operand != newExpression ?
                    node.WithOperand(newExpression) : node;
            }
        }
            private IEnumerable<ITypeSymbol> InferTypeInPrefixUnaryExpression(PrefixUnaryExpressionSyntax prefixUnaryExpression, SyntaxToken? previousToken = null)
            {
                // If we have a position, then we must be after the prefix token.
                Contract.ThrowIfTrue(previousToken.HasValue && previousToken.Value != prefixUnaryExpression.OperatorToken);

                switch (prefixUnaryExpression.Kind())
                {
                    case SyntaxKind.PreDecrementExpression:
                    case SyntaxKind.PreIncrementExpression:
                    case SyntaxKind.UnaryPlusExpression:
                    case SyntaxKind.UnaryMinusExpression:
                    case SyntaxKind.BitwiseNotExpression:
                        // ++, --, +Foo(), -Foo(), ~Foo();
                        return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Int32));

                    case SyntaxKind.LogicalNotExpression:
                        // !Foo()
                        return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Boolean));
                }

                return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
            }
Beispiel #33
0
        /// <summary>
        /// 7.7
        /// </summary>
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            SyntaxKind   kind     = node.Kind();
            TypeInfo     typeInfo = this.semanticModel.GetTypeInfo(node.Operand);
            LLVMValueRef operand;

            switch (kind)
            {
            // 7.7.1
            case SyntaxKind.UnaryPlusExpression:     // var a = +10;
                switch (typeInfo.ConvertedType.SpecialType)
                {
                case SpecialType.System_Int32:
                case SpecialType.System_UInt32:
                case SpecialType.System_Int64:
                case SpecialType.System_UInt64:
                case SpecialType.System_Single:
                case SpecialType.System_Double:
                case SpecialType.System_Decimal:
                    operand = this.Pop(node.Operand);
                    break;

                default:
                    throw new NotImplementedException("UnaryPlusExpression operator overloading is not yet implemented");
                }
                break;

            // 7.7.2
            case SyntaxKind.UnaryMinusExpression:     // var a = -10;
                switch (typeInfo.ConvertedType.SpecialType)
                {
                case SpecialType.System_Int32:
                case SpecialType.System_Int64:
                    operand = LLVM.BuildNeg(this.builder, this.Pop(node.Operand), "neg");
                    break;

                case SpecialType.System_Single:
                case SpecialType.System_Double:
                case SpecialType.System_Decimal:
                    operand = LLVM.BuildFNeg(this.builder, this.Pop(node.Operand), "fneg");
                    break;

                case SpecialType.System_UInt32:
                case SpecialType.System_UInt64:
                    if (node.Operand.IsKind(SyntaxKind.NumericLiteralExpression))
                    {
                        operand = LLVM.BuildNeg(this.builder, this.Pop(node.Operand), "neg");
                        break;
                    }
                    // TODO: UnaryMinusExpression rules from 7.7.2 should hard code int/long.MinValue here
                    throw new Exception("UnaryMinusExpression for uint32 and uint64 is only applicable for numerical literals");

                default:
                    throw new NotImplementedException("UnaryMinusExpression operator overloading not yet implemented");
                }
                break;

            // 7.7.3
            case SyntaxKind.LogicalNotExpression:     // var a = !true;
                switch (typeInfo.ConvertedType.SpecialType)
                {
                case SpecialType.System_Boolean:
                    operand = LLVM.BuildNot(this.builder, this.Pop(node.Operand), "lnot");
                    break;

                default:
                    throw new NotImplementedException("LogicalNotExpression operator overloading not yet implemented");
                }
                break;

            // 7.7.4
            case SyntaxKind.BitwiseNotExpression:     // var a = ~10;
                switch (typeInfo.ConvertedType.SpecialType)
                {
                case SpecialType.System_Int32:
                case SpecialType.System_UInt32:
                case SpecialType.System_Int64:
                case SpecialType.System_UInt64:
                    operand = LLVM.BuildNot(this.builder, this.Pop(node.Operand), "not");
                    break;

                default:
                    throw new NotImplementedException("BitwiseNotExpression operator overloading is not implemented");
                }
                break;

            case SyntaxKind.PreIncrementExpression:
            case SyntaxKind.PreDecrementExpression:
            {
                LLVMOpcode   opcode;
                LLVMValueRef opValue;
                LLVMValueRef operand2;

                switch (typeInfo.ConvertedType.SpecialType)
                {
                case SpecialType.System_SByte:
                case SpecialType.System_Byte:
                case SpecialType.System_Int16:
                case SpecialType.System_UInt16:
                case SpecialType.System_Int32:
                case SpecialType.System_UInt32:
                case SpecialType.System_Int64:
                case SpecialType.System_UInt64:
                case SpecialType.System_Char:
                    opcode  = kind == SyntaxKind.PreIncrementExpression ? LLVMOpcode.LLVMAdd : LLVMOpcode.LLVMSub;
                    opValue = LLVM.ConstInt(typeInfo.LLVMTypeRef(), 1, typeInfo.IsSignExtended());
                    break;

                case SpecialType.System_Single:
                case SpecialType.System_Double:
                case SpecialType.System_Decimal:
                    opcode  = kind == SyntaxKind.PreIncrementExpression ? LLVMOpcode.LLVMFAdd : LLVMOpcode.LLVMFSub;
                    opValue = LLVM.ConstReal(typeInfo.LLVMTypeRef(), 1);
                    break;

                default:
                    throw new NotImplementedException("PreIncrementExpression/PreDecrementExpression operator overloading is not yet implemented");
                }

                switch (node.Operand.Kind())
                {
                case SyntaxKind.IdentifierName:
                    SyntaxNode syntaxNode = node.Operand.DeclaringSyntaxNode(this.semanticModel);
                    operand2 = this.symbolTable[syntaxNode];
                    break;

                case SyntaxKind.SimpleMemberAccessExpression:
                    throw new NotImplementedException("PreIncrementExpression/PreDecrementExpression for SimpleMemberAccessExpression is not implemented");

                case SyntaxKind.ElementAccessExpression:
                    throw new NotImplementedException("PreIncrementExpression/PreDecrementExpression for ElementAccessExpression is not implemented");

                default:
                    throw new Exception("Unreachable");
                }

                var inc = LLVM.BuildBinOp(this.builder, opcode, this.Pop(node.Operand), opValue, "preop");
                LLVM.BuildStore(this.builder, inc, operand2);
                operand = inc;
                break;
            }

            default:
                throw new Exception("Unreachable");
            }

            this.Push(node, operand);
        }
Beispiel #34
0
        private void CompileNode(SyntaxNode node)
        {
            //if (node is GlobalStatementSyntax)
            //{
            //GlobalStatementSyntax globalStatement = node as GlobalStatementSyntax;

            if (node is GlobalStatementSyntax)
            {
                node = ((GlobalStatementSyntax)node).Statement;
            }

            if (node is BlockSyntax)
            {
                BlockSyntax block = node as BlockSyntax;
                foreach (StatementSyntax statement in block.Statements)
                {
                    CompileNode(statement);
                }
            }
            else if (node is ParenthesizedExpressionSyntax)
            {
                ParenthesizedExpressionSyntax parenthesizedExpression = node as ParenthesizedExpressionSyntax;

                CompileNode(parenthesizedExpression.Expression);

                if (node.Parent.Kind() == SyntaxKind.LogicalNotExpression || // TODO - check this still works
                    node.Parent.Kind() == SyntaxKind.BitwiseNotExpression ||
                    node.Parent.Kind() == SyntaxKind.UnaryMinusExpression)
                {
                    OP_NEG opNeg = new OP_NEG();
                    OpCodes.Add(opNeg);
                }
            }
            else if (node is ExpressionStatementSyntax)
            {
                ExpressionStatementSyntax expressionStatement = node as ExpressionStatementSyntax;

                CompileNode(expressionStatement.Expression);
            }
            else if (node is LiteralExpressionSyntax)
            {
                LiteralExpressionSyntax literalExpression = node as LiteralExpressionSyntax;

                OP_PUSH opPush = new OP_PUSH();
                opPush.DataIndex = Literals[literalExpression].Address;
                OpCodes.Add(opPush);

                if (Literals[literalExpression].IsNegative)
                {
                    //push a negative on top
                    OP_NEG opNeg = new OP_NEG();
                    OpCodes.Add(opNeg);
                }
            }
            //else if (node is null)
            //{

            //}
            else if (node is PrefixUnaryExpressionSyntax)
            {
                PrefixUnaryExpressionSyntax prefixUnaryExpression = node as PrefixUnaryExpressionSyntax;
                //a not? negatives are handled later
                if (prefixUnaryExpression.Kind() == SyntaxKind.LogicalNotExpression)
                {
                    CompileNode(prefixUnaryExpression.Operand);

                    //add a not
                    OP_NOT opNot = new OP_NOT();
                    OpCodes.Add(opNot);
                }
                else
                {
                    CompileNode(prefixUnaryExpression.Operand);
                }
            }
            else if (node is IdentifierNameSyntax)
            {
                IdentifierNameSyntax identifierName = node as IdentifierNameSyntax;

                OP_PUSH opPush = new OP_PUSH();
                if (identifierName != null)
                {
                    opPush.DataIndex = Variables[identifierName.ToString()].Address; // TODO check this  .PlainName
                }
                OpCodes.Add(opPush);

                if (node.Parent.Kind() == SyntaxKind.UnaryMinusExpression) // TODO - check this
                {
                    //add a not
                    OP_NEG opNeg = new OP_NEG();
                    OpCodes.Add(opNeg);
                }
            }
            else if (node is ArgumentSyntax)
            {
                ArgumentSyntax argument = node as ArgumentSyntax;

                if (argument.Expression is PrefixUnaryExpressionSyntax)
                {
                    //for a negative parse the operand
                    PrefixUnaryExpressionSyntax prefixUnaryExpression = argument.Expression as PrefixUnaryExpressionSyntax;
                    CompileNode(prefixUnaryExpression.Operand);
                }
                //if (argument.Expression is LiteralExpressionSyntax
                //    || argument.Expression is IdentifierNameSyntax)
                else
                {
                    CompileNode(argument.Expression);
                }
            }
            //a function invocation
            else if (node is InvocationExpressionSyntax)
            {
                InvocationExpressionSyntax invocationExpressionSyntax = node as InvocationExpressionSyntax;

                //first we have an identifier expression
                IdentifierNameSyntax identifierNameSyntax = invocationExpressionSyntax.Expression as IdentifierNameSyntax;

                //then arguments
                foreach (ArgumentSyntax argumentSyntax in invocationExpressionSyntax.ArgumentList.Arguments) //TODO .Reverse()?
                {
                    //Console.WriteLine("    [Literal]");
                    //Console.WriteLine("    " + (LiteralExpressionSyntax)(argumentSyntax.Expression));
                    CompileNode(argumentSyntax);
                }

                if (identifierNameSyntax.ToString() == "Print")
                {
                    OP_PRINT opPrint = new OP_PRINT();
                    OpCodes.Add(opPrint);
                }
                else
                {
                    //push the function code
                    OP_PUSH opPush = new OP_PUSH();

                    if (!FunctionTable.Functions.ContainsKey(identifierNameSyntax.ToString()))
                    {
                        if (!this.AddFunctions && !this.justPatchFunctions)
                        {
                            hasMissingFunctions = true;

                            //if (!this.DirectoryBased)
                            if (true)
                            {
                                Console.WriteLine(string.Format("Missing function {0}", identifierNameSyntax.ToString()));
                            }
                            opPush.DataIndex = 0x0FF0;
                        }
                        else
                        {
                            Console.WriteLine(string.Format("Fetching function {0}", identifierNameSyntax.ToString()));

                            short functionPointer = FunctionTable.FindFunction(this.ScriptFilename.Replace(".hfs", ".bin"), identifierNameSyntax.ToString(), opPush.Address + 1);

                            opPush.DataIndex = functionPointer;
                        }
                    }
                    else
                    {
                        opPush.DataIndex = FunctionTable.Functions[identifierNameSyntax.ToString()];
                    }
                    OpCodes.Add(opPush);

                    //add function call
                    OP_FUNCTION opFunction = new OP_FUNCTION();
                    OpCodes.Add(opFunction);

                    //do a discard
                    if (node.Parent is BinaryExpressionSyntax ||
                        node.Parent is AssignmentExpressionSyntax)
                    {
                    }
                    else
                    {
                        OP_DISCARD opDiscard = new OP_DISCARD();
                        OpCodes.Add(opDiscard);
                    }
                }
            }
            else if (node is AssignmentExpressionSyntax)
            {
                AssignmentExpressionSyntax assignmentExpression = node as AssignmentExpressionSyntax;
                CompileNode(assignmentExpression.Right);

                IdentifierNameSyntax identifierName = assignmentExpression.Left as IdentifierNameSyntax;

                //gettop the left
                OP_GETTOP opGettop = new OP_GETTOP();
                opGettop.DataIndex = Variables[identifierName.ToString()].Address;
                OpCodes.Add(opGettop);

                //for an if we need to keep the value
                //or for a double assign
                if (assignmentExpression.Parent.Kind() != SyntaxKind.IfStatement &&
                    assignmentExpression.Parent.Kind() != SyntaxKind.SimpleAssignmentExpression)
                {
                    //do a discard
                    OP_DISCARD opDiscard = new OP_DISCARD();
                    OpCodes.Add(opDiscard);
                }
            }
            else if (node is BinaryExpressionSyntax)
            {
                BinaryExpressionSyntax binaryExpression = node as BinaryExpressionSyntax;
                if (binaryExpression.OperatorToken.Kind() == SyntaxKind.EqualsToken)
                {
                    CompileNode(binaryExpression.Right);

                    IdentifierNameSyntax identifierName = binaryExpression.Left as IdentifierNameSyntax;

                    //gettop the left
                    OP_GETTOP opGettop = new OP_GETTOP();
                    opGettop.DataIndex = Variables[identifierName.ToString()].Address;
                    OpCodes.Add(opGettop);

                    //for an if we need to keep the value
                    if (binaryExpression.Parent.Kind() != SyntaxKind.IfStatement)
                    {
                        //do a discard
                        OP_DISCARD opDiscard = new OP_DISCARD();
                        OpCodes.Add(opDiscard);
                    }
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.EqualsEqualsToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_EQUAL opEqual = new OP_EQUAL();
                    OpCodes.Add(opEqual);

                    if (node.Parent.Kind() == SyntaxKind.ExpressionStatement)
                    {
                        //just discard the result
                        OP_DISCARD opDiscard = new OP_DISCARD();
                        OpCodes.Add(opDiscard);
                    }
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.ExclamationEqualsToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_NOT_EQUAL opNotEqual = new OP_NOT_EQUAL();
                    OpCodes.Add(opNotEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.MinusToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_MINUS opEqual = new OP_MINUS();
                    OpCodes.Add(opEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.PlusToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_CONCAT opEqual = new OP_CONCAT();
                    OpCodes.Add(opEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.GreaterThanToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_MORE_THAN opEqual = new OP_MORE_THAN();
                    OpCodes.Add(opEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.LessThanToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_LESS_THAN opEqual = new OP_LESS_THAN();
                    OpCodes.Add(opEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.LessThanEqualsToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_LESS_THAN_OR_EQUAL opLessOrEqual = new OP_LESS_THAN_OR_EQUAL();
                    OpCodes.Add(opLessOrEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.GreaterThanEqualsToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_MORE_THAN_OR_EQUAL opGreatOrEqual = new OP_MORE_THAN_OR_EQUAL();
                    OpCodes.Add(opGreatOrEqual);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.BarBarToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_OR opOr = new OP_OR();
                    OpCodes.Add(opOr);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.AmpersandAmpersandToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_AND opAnd = new OP_AND();
                    OpCodes.Add(opAnd);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.AsteriskToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_MULTIPLY opMultiply = new OP_MULTIPLY();
                    OpCodes.Add(opMultiply);
                }
                else if (binaryExpression.OperatorToken.Kind() == SyntaxKind.SlashToken)
                {
                    CompileNode(binaryExpression.Left);

                    CompileNode(binaryExpression.Right);

                    OP_DIVIDE opDivide = new OP_DIVIDE();
                    OpCodes.Add(opDivide);
                }
            }
            else if (node is WhileStatementSyntax)
            {
                WhileStatementSyntax whileStatement = node as WhileStatementSyntax;

                short whileAddress = OpCode.NextAddress;

                CompileNode(whileStatement.Condition);

                //look at the condition here
                OP_JMPF opJmpF = new OP_JMPF();
                OpCodes.Add(opJmpF);

                CompileNode(whileStatement.Statement);

                //jmp back to the condition
                OP_JMP opJmp = new OP_JMP();
                opJmp.DataIndex = whileAddress;
                OpCodes.Add(opJmp);

                //jump over the jmp back
                opJmpF.DataIndex = (short)(opJmp.Address + 3);
            }
            else if (node is IfStatementSyntax)
            {
                IfStatementSyntax ifStatement = node as IfStatementSyntax;

                //look at the condition here
                CompileNode(ifStatement.Condition);

                short ifAddress = OpCode.NextAddress;
                //do a jump to end if condition is false
                OP_JMPF opJmpF = new OP_JMPF();
                OpCodes.Add(opJmpF);

                CompileNode(ifStatement.Statement);

                //has an else option?
                if (ifStatement.Else != null) //TODO - check this works
                {
                    OP_JMP opJmp = new OP_JMP();
                    OpCodes.Add(opJmp);

                    //save this as the else jump so we can hook it up later
                    this.ElseJmps.Push(opJmp);
                }

                //add in the jump target
                JUMPTARGET jumpTarget = new JUMPTARGET();
                jumpTarget.DataIndex = ifAddress;
                OpCodes.Add(jumpTarget);

                //jump is to here
                opJmpF.DataIndex = jumpTarget.Address;

                CompileNode(ifStatement.Else);
            }
            else if (node is ElseClauseSyntax)
            {
                ElseClauseSyntax elseClause = node as ElseClauseSyntax;

                CompileNode(elseClause.Statement);

                //pop off last one
                OP_JMP opJmp = this.ElseJmps.Pop();

                //add in the jump target
                JUMPTARGET jumpTarget = new JUMPTARGET();
                jumpTarget.DataIndex = opJmp.Address;
                OpCodes.Add(jumpTarget);

                //jump is to here
                opJmp.DataIndex = jumpTarget.Address;
            }

            //}
            //else if (node is BlockSyntax)
            //{
            //    BlockSyntax block = node as BlockSyntax;
            //    foreach (StatementSyntax statement in block.Statements)
            //    {
            //        CompileNode(statement);
            //    }
            //}
        }