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); }
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); }