/// <summary> /// Reads an unsafe type expression. /// </summary> /// <param name="type"> /// The type expression. /// </param> /// <param name="previousPrecedence"> /// The precedence of the previous expression. /// </param> /// <param name="parentReference"> /// The parent code unit. /// </param> /// <returns> /// Returns the expression. /// </returns> private UnsafeAccessExpression GetUnsafeTypeExpression(Expression type, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference) { Param.Ignore(type); Param.AssertNotNull(previousPrecedence, "previousPrecedence"); Param.AssertNotNull(parentReference, "parentReference"); UnsafeAccessExpression expression = null; if (CheckPrecedence(previousPrecedence, ExpressionPrecedence.Unary)) { // Get the operator symbol. Symbol symbol = this.GetNextSymbol(parentReference); Reference<ICodePart> expressionReference = new Reference<ICodePart>(); OperatorType operatorType; UnsafeAccessExpression.Operator unsafeOperatorType; if (symbol.SymbolType == SymbolType.LogicalAnd) { operatorType = OperatorType.AddressOf; unsafeOperatorType = UnsafeAccessExpression.Operator.AddressOf; } else if (symbol.SymbolType == SymbolType.Multiplication) { operatorType = OperatorType.Dereference; unsafeOperatorType = UnsafeAccessExpression.Operator.Dereference; } else { Debug.Fail("Unexpected operator type."); throw new InvalidOperationException(); } // Create a token for the operator symbol. this.symbols.Advance(); OperatorSymbol token = new OperatorSymbol( symbol.Text, OperatorCategory.Reference, operatorType, symbol.Location, expressionReference, this.symbols.Generated); this.tokens.Add(token); // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, type.Tokens.First, this.tokens.Last); // Create and return the expression. expression = new UnsafeAccessExpression(partialTokens, unsafeOperatorType, type); expressionReference.Target = expression; } return expression; }
/// <summary> /// The save. /// </summary> /// <param name="operator"> /// The operator. /// </param> private void Save(UnsafeAccessExpression.Operator @operator) { var operatorString = string.Empty; switch (@operator) { case UnsafeAccessExpression.Operator.AddressOf: operatorString = "&"; break; case UnsafeAccessExpression.Operator.Dereference: operatorString = "*"; break; default: break; } this.cppWriter.Write(operatorString); }
/// <summary> /// Reads an unsafe access expression. /// </summary> /// <param name="parentReference"> /// The parent code unit. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the expression. /// </returns> private UnsafeAccessExpression GetUnsafeAccessExpression(Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(parentReference, "parentReference"); Param.Assert(unsafeCode, "unsafeCode", "Un unsafe access must reside in an unsafe code block."); // Get the operator symbol. Symbol symbol = this.GetNextSymbol(parentReference); Reference<ICodePart> expressionReference = new Reference<ICodePart>(); OperatorType operatorType; UnsafeAccessExpression.Operator unsafeOperatorType; if (symbol.SymbolType == SymbolType.LogicalAnd) { operatorType = OperatorType.AddressOf; unsafeOperatorType = UnsafeAccessExpression.Operator.AddressOf; } else if (symbol.SymbolType == SymbolType.Multiplication) { operatorType = OperatorType.Dereference; unsafeOperatorType = UnsafeAccessExpression.Operator.Dereference; } else { Debug.Fail("Unexpected operator type."); throw new InvalidOperationException(); } // Create a token for the operator symbol. this.symbols.Advance(); OperatorSymbol token = new OperatorSymbol(symbol.Text, OperatorCategory.Reference, operatorType, symbol.Location, expressionReference, this.symbols.Generated); Node<CsToken> tokenNode = this.tokens.InsertLast(token); // Get the expression being accessed. Expression innerExpression = this.GetNextExpression(ExpressionPrecedence.Unary, expressionReference, unsafeCode); if (innerExpression == null || innerExpression.Tokens.First == null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, tokenNode, this.tokens.Last); // Create and return the expression. UnsafeAccessExpression expression = new UnsafeAccessExpression(partialTokens, unsafeOperatorType, innerExpression); expressionReference.Target = expression; return expression; }
/// <summary> /// The save. /// </summary> /// <param name="unsafeAccessExpression"> /// The unsafe access expression. /// </param> private void Save(UnsafeAccessExpression unsafeAccessExpression) { this.Save(unsafeAccessExpression.OperatorType); @switch(unsafeAccessExpression.Value); }