Ejemplo n.º 1
0
        public override void ExitUnaryExpr(GoParser.UnaryExprContext context)
        {
            // unaryExpr
            //     : primaryExpr
            //     | ('+' | '-' | '!' | '^' | '*' | '&' | '<-') expression

            if (PrimaryExpressions.TryGetValue(context.primaryExpr(), out string primaryExpression))
            {
                UnaryExpressions[context] = primaryExpression;
            }
            else if (context.expression() != null)
            {
                string unaryOP = context.children[0].GetText();

                if (unaryOP.Equals("^", StringComparison.Ordinal))
                {
                    unaryOP = "~";
                }
                else if (unaryOP.Equals("<-", StringComparison.Ordinal))
                {
                    // TODO: Handle channel value access (update when channel class is created):
                    unaryOP = null;
                    UnaryExpressions[context] = $"{Expressions[context.expression()]}.Receive()";
                }
                else if (unaryOP.Equals("&", StringComparison.Ordinal))
                {
                    // TODO: Handle pointer acquisition context - may need to augment pre-scan metadata for heap allocation notation
                    unaryOP = null;
                    UnaryExpressions[context] = $"ref {Expressions[context.expression()]}";
                }
                else if (unaryOP.Equals("*", StringComparison.Ordinal))
                {
                    // TODO: Handle pointer dereference context - if this is a ref variable, Deref call is unnecessary
                    unaryOP = null;
                    UnaryExpressions[context] = $"{Expressions[context.expression()]}.Deref";
                }

                if ((object)unaryOP != null)
                {
                    UnaryExpressions[context] = $"{unaryOP}{Expressions[context.expression()]}";
                }
            }
            else if (!UnaryExpressions.ContainsKey(context))
            {
                AddWarning(context, $"Unexpected unary expression \"{context.GetText()}\"");
            }
        }
Ejemplo n.º 2
0
        public override void ExitUnaryExpr(GoParser.UnaryExprContext context)
        {
            base.ExitUnaryExpr(context);

            if (!InFunction || !(context.primaryExpr() is null) && PrimaryExpressions.ContainsKey(context.primaryExpr()) ||
                context.expression() is null || !Expressions.TryGetValue(context.expression(), out ExpressionInfo expression))
            {
                return;
            }

            ParameterInfo[] parameters = CurrentFunction.Signature.Signature.Parameters;
            string          unaryOP    = context.children[0].GetText();

            if (!unaryOP.Equals("*", StringComparison.Ordinal))
            {
                return;
            }

            ParameterInfo pointerParam = parameters.FirstOrDefault(parameter => parameter.Name.Equals(expression.Text));

            if (!(pointerParam is null) && pointerParam.Type is PointerTypeInfo pointer)
            {
                TypeInfo targetType = pointer.TargetTypeInfo.Clone();
                targetType.IsByRefPointer = true;

                string derefPointerExpression = expression.Text;

                // Handle pointer-to-pointer dereferencing
                int derefs = pointer.Name.Count(chr => chr == '*');

                if (derefs > 1)
                {
                    for (int i = 1; i < derefs; i++)
                    {
                        derefPointerExpression += ".val";
                    }
                }

                // Implicitly dereference pointer parameter when dereference operator (*) is used
                UnaryExpressions[context] = new ExpressionInfo
                {
                    Text = derefPointerExpression,
                    Type = targetType
                };
            }
        }
Ejemplo n.º 3
0
        public override void ExitUnaryExpr(GoParser.UnaryExprContext context)
        {
            base.ExitUnaryExpr(context);

            ExpressionInfo expression = null;

            if (!(context.primaryExpr() is null) && !PrimaryExpressions.ContainsKey(context.primaryExpr()) ||
                !(context.expression() is null) && !Expressions.TryGetValue(context.expression(), out expression) ||
                expression is null)
            {
                return;
            }

            // Taking the address of a variable means making a stack variable heap allocated
            if (context.children[0].GetText().Equals("&", StringComparison.Ordinal) && m_variables.TryGetValue(expression.Text, out VariableInfo variable))
            {
                variable.HeapAllocated = true;
            }
        }