public override object VisitLiteralExpression([NotNull] DoshikParser.LiteralExpressionContext context)
        {
            SetWholeExpression(context);
            VisitChildren(context);
            _compilationContext.SetParsingAntlrContext(context);

            var node = new LiteralExpressionNode(context);

            Sequence.Sequence.Add(node);

            var literalCtx        = context.literal();
            var integerLiteralCtx = literalCtx.integerLiteral();

            if (integerLiteralCtx != null && integerLiteralCtx.INT_LITERAL() != null)
            {
                node.LiteralValue = integerLiteralCtx.INT_LITERAL().GetText();
                node.LiteralType  = LiteralExpressionNode.LiteralTypeOption.Int;
            }
            else if (integerLiteralCtx != null && integerLiteralCtx.INT_HEX_LITERAL() != null)
            {
                node.LiteralValue = integerLiteralCtx.INT_HEX_LITERAL().GetText();
                node.LiteralType  = LiteralExpressionNode.LiteralTypeOption.IntHex;
            }
            else if (literalCtx.FLOAT_LITERAL() != null)
            {
                node.LiteralValue = literalCtx.FLOAT_LITERAL().GetText();
                node.LiteralType  = LiteralExpressionNode.LiteralTypeOption.Float;
            }
            else if (literalCtx.STRING_LITERAL() != null)
            {
                node.LiteralValue = literalCtx.STRING_LITERAL().GetText();
                node.LiteralType  = LiteralExpressionNode.LiteralTypeOption.String;
            }
            else if (literalCtx.BOOL_LITERAL() != null)
            {
                node.LiteralValue = literalCtx.BOOL_LITERAL().GetText();
                node.LiteralType  = LiteralExpressionNode.LiteralTypeOption.Bool;
            }
            else if (literalCtx.NULL_LITERAL() != null)
            {
                node.LiteralValue = literalCtx.NULL_LITERAL().GetText();
                node.LiteralType  = LiteralExpressionNode.LiteralTypeOption.Null;
            }
            else
            {
                throw new System.NotImplementedException();
            }

            return(null);
        }
Beispiel #2
0
        private IExpression HandleLiteralExpressionNode(LiteralExpressionNode node)
        {
            var       result = new ConstantValueExpression();
            KnownType knownType;

            switch (node.LiteralType)
            {
            case LiteralExpressionNode.LiteralTypeOption.Int:
            {
                var literalValue = node.LiteralValue;

                if (int.TryParse(literalValue, NumberStyles.None, CultureInfo.InvariantCulture, out int intResult))
                {
                    knownType          = KnownType.Int32;
                    result.DotnetValue = intResult;
                }
                else if (long.TryParse(literalValue, NumberStyles.None, CultureInfo.InvariantCulture, out long longResult))
                {
                    knownType          = KnownType.Int64;
                    result.DotnetValue = longResult;
                }
                else
                {
                    throw _compilationContext.ThrowCompilationError("integer constant is too large");
                }
            }
            break;

            case LiteralExpressionNode.LiteralTypeOption.IntHex:
            {
                // Удаляем '0x'
                var literalValue = node.LiteralValue.Remove(0, 2);

                if (int.TryParse(literalValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out int intResult))
                {
                    knownType          = KnownType.Int32;
                    result.DotnetValue = intResult;
                }
                else if (long.TryParse(literalValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out long longResult))
                {
                    knownType          = KnownType.Int64;
                    result.DotnetValue = longResult;
                }
                else
                {
                    throw _compilationContext.ThrowCompilationError("integer constant is too large");
                }
            }
            break;

            case LiteralExpressionNode.LiteralTypeOption.Float:
            {
                var  literalValue = node.LiteralValue;
                bool isFloatLiteral;

                if (literalValue.EndsWith("f"))
                {
                    isFloatLiteral = true;
                    literalValue   = literalValue.Remove(literalValue.Length - 1, 1);
                }
                else
                {
                    isFloatLiteral = false;

                    if (literalValue.EndsWith("d"))
                    {
                        literalValue = literalValue.Remove(literalValue.Length - 1, 1);
                    }
                }

                if (isFloatLiteral)
                {
                    if (float.TryParse(literalValue, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out float floatResult))
                    {
                        knownType          = KnownType.Single;
                        result.DotnetValue = floatResult;
                    }
                    else
                    {
                        throw _compilationContext.ThrowCompilationError("cannot parse float literal");
                    }
                }
                else
                {
                    if (double.TryParse(literalValue, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double doubleResult))
                    {
                        knownType          = KnownType.Double;
                        result.DotnetValue = doubleResult;
                    }
                    else
                    {
                        throw _compilationContext.ThrowCompilationError("cannot parse double literal");
                    }
                }
            }
            break;

            case LiteralExpressionNode.LiteralTypeOption.String:
            {
                knownType = KnownType.String;

                var literalValue = node.LiteralValue;

                // Удаляем кавычки по краям

                literalValue = literalValue.Remove(0, 1);
                literalValue = literalValue.Remove(literalValue.Length - 1, 1);

                // unescape

                // ToDo: в этом месте делаем undescape, то есть находим в строке обратный слеш плюс код и заменяем эти места на соответствующие символы (например \n меняем на символ новой строки и тд)
                // В парсере это не определено и не будет определено

                result.DotnetValue = literalValue;
            }
            break;

            case LiteralExpressionNode.LiteralTypeOption.Bool:
            {
                knownType          = KnownType.Boolean;
                result.DotnetValue = bool.Parse(node.LiteralValue);
            }
            break;

            case LiteralExpressionNode.LiteralTypeOption.Null:
            {
                knownType          = KnownType.Object;
                result.DotnetValue = null;
            }
            break;

            default:
                throw new NotImplementedException();
            }

            result.ValueType = _compilationContext.TypeLibrary.FindByKnownType(knownType);

            _compilationContext.CompilationUnit.AddConstant(Constant.CreateAsDotnetValue(result.ValueType, result.DotnetValue));

            // Определяем выходное значение
            result.ReturnOutputSlot = new ExpressionSlot(result.ValueType, result);

            return(result);
        }