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); }
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); }
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"); } }
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()}"); } }
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; } } }
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}."); } }
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); } }
public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { if (node.Kind().Is(SyntaxKind.AddressOfExpression, SyntaxKind.PointerIndirectionExpression)) { ContainsUnsafe = true; } else { base.VisitPrefixUnaryExpression(node); } }
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)); }
public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { switch (node.Kind()) { case SyntaxKind.LogicalNotExpression: break; default: this.HandleAssignedValue(node.Operand, node); break; } base.VisitPrefixUnaryExpression(node); }
public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { switch (node.Kind()) { case SyntaxKind.LogicalNotExpression: break; default: this.mutations.Add(node); break; } base.VisitPrefixUnaryExpression(node); }
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; } }
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); }
/// <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); } }
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); } }
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; } } }
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; }
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); }
// 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); }
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)); }
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>(); }
/// <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); }
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); // } //} }