Commit dc51ed6b authored by Kenton Varda's avatar Kenton Varda

Support 'inf' and 'nan' as float/double literals.

parent 9baabb1d
......@@ -103,8 +103,14 @@ void genericInitTestMessage(Builder builder) {
builder.setUInt16List({33333u, 44444u});
builder.setUInt32List({3333333333u});
builder.setUInt64List({11111111111111111111ull});
builder.setFloat32List({5555.5, 2222.25});
builder.setFloat64List({7777.75, 1111.125});
builder.setFloat32List({5555.5,
std::numeric_limits<float>::infinity(),
-std::numeric_limits<float>::infinity(),
std::numeric_limits<float>::quiet_NaN()});
builder.setFloat64List({7777.75,
std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::quiet_NaN()});
builder.setTextList({"plugh", "xyzzy", "thud"});
builder.setDataList({"oops", "exhausted", "rfc3092"});
{
......@@ -140,6 +146,9 @@ void checkList(T reader, std::initializer_list<double> expected) {
}
}
inline bool isNaN(float f) { return f != f; }
inline bool isNaN(double f) { return f != f; }
template <typename Reader>
void genericCheckTestMessage(Reader reader) {
EXPECT_EQ(Void::VOID, reader.getVoidField());
......@@ -215,8 +224,22 @@ void genericCheckTestMessage(Reader reader) {
checkList(reader.getUInt16List(), {33333u, 44444u});
checkList(reader.getUInt32List(), {3333333333u});
checkList(reader.getUInt64List(), {11111111111111111111ull});
checkList(reader.getFloat32List(), {5555.5f, 2222.25f});
checkList(reader.getFloat64List(), {7777.75, 1111.125});
{
auto listReader = reader.getFloat32List();
ASSERT_EQ(4u, listReader.size());
EXPECT_EQ(5555.5f, listReader[0]);
EXPECT_EQ(std::numeric_limits<float>::infinity(), listReader[1]);
EXPECT_EQ(-std::numeric_limits<float>::infinity(), listReader[2]);
EXPECT_TRUE(isNaN(listReader[3]));
}
{
auto listReader = reader.getFloat64List();
ASSERT_EQ(4u, listReader.size());
EXPECT_EQ(7777.75, listReader[0]);
EXPECT_EQ(std::numeric_limits<double>::infinity(), listReader[1]);
EXPECT_EQ(-std::numeric_limits<double>::infinity(), listReader[2]);
EXPECT_TRUE(isNaN(listReader[3]));
}
checkList(reader.getTextList(), {"plugh", "xyzzy", "thud"});
checkList(reader.getDataList(), {"oops", "exhausted", "rfc3092"});
{
......
......@@ -144,8 +144,8 @@ struct TestDefaults {
uInt16List @24 : List(UInt16) = [33333, 44444];
uInt32List @25 : List(UInt32) = [3333333333];
uInt64List @26 : List(UInt64) = [11111111111111111111];
float32List @27 : List(Float32) = [5555.5, 2222.25];
float64List @28 : List(Float64) = [7777.75, 1111.125];
float32List @27 : List(Float32) = [5555.5, inf, -inf, nan];
float64List @28 : List(Float64) = [7777.75, inf, -inf, nan];
textList @29 : List(Text) = ["plugh", "xyzzy", "thud"];
dataList @30 : List(Data) = ["oops", "exhausted", "rfc3092"];
structList @31 : List(TestAllTypes) = [
......
......@@ -196,6 +196,14 @@ compileValue _ (BuiltinType BuiltinFloat32) (FloatFieldValue x) = succeed (Float
compileValue _ (BuiltinType BuiltinFloat64) (FloatFieldValue x) = succeed (Float64Desc x)
compileValue _ (BuiltinType BuiltinFloat32) (IntegerFieldValue x) = succeed (Float32Desc (realToFrac x))
compileValue _ (BuiltinType BuiltinFloat64) (IntegerFieldValue x) = succeed (Float64Desc (realToFrac x))
compileValue _ (BuiltinType BuiltinFloat32) (IdentifierFieldValue "inf") =
succeed $ Float32Desc $ realToFrac $ 1.0 / 0.0
compileValue _ (BuiltinType BuiltinFloat64) (IdentifierFieldValue "inf") =
succeed $ Float64Desc $ 1.0 / 0.0
compileValue _ (BuiltinType BuiltinFloat32) (IdentifierFieldValue "nan") =
succeed $ Float32Desc $ realToFrac $ 0.0 / 0.0
compileValue _ (BuiltinType BuiltinFloat64) (IdentifierFieldValue "nan") =
succeed $ Float64Desc $ 0.0 / 0.0
compileValue _ (BuiltinType BuiltinText) (StringFieldValue x) = succeed (TextDesc x)
compileValue _ (BuiltinType BuiltinData) (StringFieldValue x) =
succeed (DataDesc (map (fromIntegral . fromEnum) x))
......
......@@ -121,6 +121,8 @@ unionKeyword = tokenParser (matchSimpleToken UnionKeyword) <?> "\"union\""
interfaceKeyword = tokenParser (matchSimpleToken InterfaceKeyword) <?> "\"interface\""
annotationKeyword = tokenParser (matchSimpleToken AnnotationKeyword) <?> "\"annotation\""
exactIdentifier s = tokenParser (matchSimpleToken $ Identifier s) <?> "\"" ++ s ++ "\""
parenthesizedList parser = do
items <- tokenParser (matchUnary ParenthesizedList)
parseList parser items
......@@ -250,6 +252,7 @@ fieldDecl = do
negativeFieldValue = liftM (IntegerFieldValue . negate) literalInt
<|> liftM (FloatFieldValue . negate) literalFloat
<|> (exactIdentifier "inf" >> return (FloatFieldValue (-1.0 / 0.0)))
fieldValue = (literalVoid >> return VoidFieldValue)
<|> liftM BoolFieldValue literalBool
......@@ -312,25 +315,17 @@ annotationDecl = do
return (AnnotationDecl name t annotations targets)
allAnnotationTargets = [minBound::AnnotationTarget .. maxBound::AnnotationTarget]
annotationTarget = (constKeyword >> return ConstantAnnotation)
annotationTarget = (exactIdentifier "file" >> return FileAnnotation)
<|> (constKeyword >> return ConstantAnnotation)
<|> (enumKeyword >> return EnumAnnotation)
<|> (exactIdentifier "enumerant" >> return EnumerantAnnotation)
<|> (structKeyword >> return StructAnnotation)
<|> (exactIdentifier "field" >> return FieldAnnotation)
<|> (unionKeyword >> return UnionAnnotation)
<|> (interfaceKeyword >> return InterfaceAnnotation)
<|> (exactIdentifier "method" >> return MethodAnnotation)
<|> (exactIdentifier "parameter" >> return ParamAnnotation)
<|> (annotationKeyword >> return AnnotationAnnotation)
<|> (do
name <- varIdentifier
case name of
"file" -> return FileAnnotation
"enumerant" -> return EnumerantAnnotation
"field" -> return FieldAnnotation
"method" -> return MethodAnnotation
"parameter" -> return ParamAnnotation
_ -> fail "" <?> annotationTargetList)
<?> annotationTargetList
annotationTargetList = "const, enum, enumerant, struct, field, union, interface, method, \
\parameter, or annotation"
extractErrors :: Either ParseError (a, [ParseError]) -> [ParseError]
extractErrors (Left err) = [err]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment