Пример #1
0
        /// <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);
        }
Пример #3
0
        /// <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);
 }