Commit a6aa9d6a authored by Kenton Varda's avatar Kenton Varda

Make enum syntax match docs, make enum lists work correctly, add enum tests,…

Make enum syntax match docs, make enum lists work correctly, add enum tests, enforce maximum ordinals on enum values and interface methods, change the maximum field ordinal to 16-bit to match docs (now all ordinal limits match).
parent 9ebc3020
...@@ -51,15 +51,15 @@ struct Car { ...@@ -51,15 +51,15 @@ struct Car {
} }
enum Color { enum Color {
black = 0; black @0;
white = 1; white @1;
red = 2; red @2;
green = 3; green @3;
blue = 4; blue @4;
cyan = 5; cyan @5;
magenta = 6; magenta @6;
yellow = 7; yellow @7;
silver = 8; silver @8;
} }
struct Wheel { struct Wheel {
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum Operation { enum Operation {
add = 0; add @0;
subtract = 1; subtract @1;
multiply = 2; multiply @2;
divide = 3; divide @3;
modulus = 4; modulus @4;
} }
struct Expression { struct Expression {
......
...@@ -30,7 +30,19 @@ ...@@ -30,7 +30,19 @@
namespace capnproto { namespace capnproto {
namespace internal { namespace internal {
template <typename T> struct IsPrimitive;
template <typename T>
class IsPrimitive {
typedef char no;
typedef long yes;
template <typename U> static no test(typename U::Reader*);
template <typename U> static yes test(...);
public:
static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};
} // namespace internal } // namespace internal
template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value> template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value>
...@@ -38,41 +50,35 @@ struct List; ...@@ -38,41 +50,35 @@ struct List;
namespace internal { namespace internal {
template <typename T> struct IsPrimitive { static constexpr bool value = false; }; template <size_t size> struct FieldSizeForByteSize;
template <> struct FieldSizeForByteSize<1> { static constexpr FieldSize value = FieldSize::BYTE; };
template <> struct IsPrimitive<Void> { static constexpr bool value = true; }; template <> struct FieldSizeForByteSize<2> { static constexpr FieldSize value = FieldSize::TWO_BYTES; };
template <> struct IsPrimitive<bool> { static constexpr bool value = true; }; template <> struct FieldSizeForByteSize<4> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct IsPrimitive<int8_t> { static constexpr bool value = true; }; template <> struct FieldSizeForByteSize<8> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <> struct IsPrimitive<int16_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<int32_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<int64_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<uint8_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<uint16_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<uint32_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<uint64_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<float> { static constexpr bool value = true; };
template <> struct IsPrimitive<double> { static constexpr bool value = true; };
template <typename T, bool b> struct IsPrimitive<List<T, b>> {
static constexpr bool value = IsPrimitive<T>::value;
};
template <typename T> struct FieldSizeForType { static constexpr FieldSize value = FieldSize::INLINE_COMPOSITE; }; template <typename T> struct FieldSizeForType {
static constexpr FieldSize value = IsPrimitive<T>::value ?
// Primitive types that aren't special-cased below can be determined from sizeof().
FieldSizeForByteSize<sizeof(T)>::value :
// Non-primitive types that aren't special-cased below are presumed to be structs.
FieldSize::INLINE_COMPOSITE;
};
// Void and bool are special.
template <> struct FieldSizeForType<Void> { static constexpr FieldSize value = FieldSize::VOID; }; template <> struct FieldSizeForType<Void> { static constexpr FieldSize value = FieldSize::VOID; };
template <> struct FieldSizeForType<bool> { static constexpr FieldSize value = FieldSize::BIT; }; template <> struct FieldSizeForType<bool> { static constexpr FieldSize value = FieldSize::BIT; };
template <> struct FieldSizeForType<int8_t> { static constexpr FieldSize value = FieldSize::BYTE; };
template <> struct FieldSizeForType<int16_t> { static constexpr FieldSize value = FieldSize::TWO_BYTES; }; // Lists and blobs are references, not structs.
template <> struct FieldSizeForType<int32_t> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct FieldSizeForType<int64_t> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <> struct FieldSizeForType<uint8_t> { static constexpr FieldSize value = FieldSize::BYTE; };
template <> struct FieldSizeForType<uint16_t> { static constexpr FieldSize value = FieldSize::TWO_BYTES; };
template <> struct FieldSizeForType<uint32_t> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct FieldSizeForType<uint64_t> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <> struct FieldSizeForType<float> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct FieldSizeForType<double> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <typename T, bool b> struct FieldSizeForType<List<T, b>> { template <typename T, bool b> struct FieldSizeForType<List<T, b>> {
static constexpr FieldSize value = FieldSize::REFERENCE; static constexpr FieldSize value = FieldSize::REFERENCE;
}; };
template <> struct FieldSizeForType<Text> {
static constexpr FieldSize value = FieldSize::REFERENCE;
};
template <> struct FieldSizeForType<Data> {
static constexpr FieldSize value = FieldSize::REFERENCE;
};
template <typename T> template <typename T>
class TemporaryPointer { class TemporaryPointer {
......
...@@ -65,6 +65,7 @@ void genericInitTestMessage(Builder builder) { ...@@ -65,6 +65,7 @@ void genericInitTestMessage(Builder builder) {
subSubBuilder.setTextField("nested"); subSubBuilder.setTextField("nested");
subSubBuilder.initStructField().setTextField("really nested"); subSubBuilder.initStructField().setTextField("really nested");
} }
subBuilder.setEnumField(TestEnum::BAZ);
subBuilder.setVoidList({Void::VOID, Void::VOID, Void::VOID}); subBuilder.setVoidList({Void::VOID, Void::VOID, Void::VOID});
subBuilder.setBoolList({false, true, false, true, true}); subBuilder.setBoolList({false, true, false, true, true});
...@@ -81,14 +82,15 @@ void genericInitTestMessage(Builder builder) { ...@@ -81,14 +82,15 @@ void genericInitTestMessage(Builder builder) {
subBuilder.setFloat64List({0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306}); subBuilder.setFloat64List({0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306});
subBuilder.setTextList({"quux", "corge", "grault"}); subBuilder.setTextList({"quux", "corge", "grault"});
subBuilder.setDataList({"garply", "waldo", "fred"}); subBuilder.setDataList({"garply", "waldo", "fred"});
{ {
auto listBuilder = subBuilder.initStructList(3); auto listBuilder = subBuilder.initStructList(3);
listBuilder[0].setTextField("x structlist 1"); listBuilder[0].setTextField("x structlist 1");
listBuilder[1].setTextField("x structlist 2"); listBuilder[1].setTextField("x structlist 2");
listBuilder[2].setTextField("x structlist 3"); listBuilder[2].setTextField("x structlist 3");
} }
subBuilder.setEnumList({TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT});
} }
builder.setEnumField(TestEnum::CORGE);
builder.initVoidList(6); builder.initVoidList(6);
builder.setBoolList({true, false, false, true}); builder.setBoolList({true, false, false, true});
...@@ -104,13 +106,13 @@ void genericInitTestMessage(Builder builder) { ...@@ -104,13 +106,13 @@ void genericInitTestMessage(Builder builder) {
builder.setFloat64List({7777.75, 1111.125}); builder.setFloat64List({7777.75, 1111.125});
builder.setTextList({"plugh", "xyzzy", "thud"}); builder.setTextList({"plugh", "xyzzy", "thud"});
builder.setDataList({"oops", "exhausted", "rfc3092"}); builder.setDataList({"oops", "exhausted", "rfc3092"});
{ {
auto listBuilder = builder.initStructList(3); auto listBuilder = builder.initStructList(3);
listBuilder[0].setTextField("structlist 1"); listBuilder[0].setTextField("structlist 1");
listBuilder[1].setTextField("structlist 2"); listBuilder[1].setTextField("structlist 2");
listBuilder[2].setTextField("structlist 3"); listBuilder[2].setTextField("structlist 3");
} }
builder.setEnumList({TestEnum::FOO, TestEnum::GARPLY});
} }
template <typename T, typename U> template <typename T, typename U>
...@@ -174,6 +176,7 @@ void genericCheckTestMessage(Reader reader) { ...@@ -174,6 +176,7 @@ void genericCheckTestMessage(Reader reader) {
EXPECT_EQ("nested", subSubReader.getTextField()); EXPECT_EQ("nested", subSubReader.getTextField());
EXPECT_EQ("really nested", subSubReader.getStructField().getTextField()); EXPECT_EQ("really nested", subSubReader.getStructField().getTextField());
} }
EXPECT_EQ(TestEnum::BAZ, subReader.getEnumField());
checkList(subReader.getVoidList(), {Void::VOID, Void::VOID, Void::VOID}); checkList(subReader.getVoidList(), {Void::VOID, Void::VOID, Void::VOID});
checkList(subReader.getBoolList(), {false, true, false, true, true}); checkList(subReader.getBoolList(), {false, true, false, true, true});
...@@ -190,7 +193,6 @@ void genericCheckTestMessage(Reader reader) { ...@@ -190,7 +193,6 @@ void genericCheckTestMessage(Reader reader) {
checkList(subReader.getFloat64List(), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306}); checkList(subReader.getFloat64List(), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306});
checkList(subReader.getTextList(), {"quux", "corge", "grault"}); checkList(subReader.getTextList(), {"quux", "corge", "grault"});
checkList(subReader.getDataList(), {"garply", "waldo", "fred"}); checkList(subReader.getDataList(), {"garply", "waldo", "fred"});
{ {
auto listReader = subReader.getStructList(); auto listReader = subReader.getStructList();
ASSERT_EQ(3u, listReader.size()); ASSERT_EQ(3u, listReader.size());
...@@ -198,7 +200,9 @@ void genericCheckTestMessage(Reader reader) { ...@@ -198,7 +200,9 @@ void genericCheckTestMessage(Reader reader) {
EXPECT_EQ("x structlist 2", listReader[1].getTextField()); EXPECT_EQ("x structlist 2", listReader[1].getTextField());
EXPECT_EQ("x structlist 3", listReader[2].getTextField()); EXPECT_EQ("x structlist 3", listReader[2].getTextField());
} }
checkList(subReader.getEnumList(), {TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT});
} }
EXPECT_EQ(TestEnum::CORGE, reader.getEnumField());
EXPECT_EQ(6u, reader.getVoidList().size()); EXPECT_EQ(6u, reader.getVoidList().size());
checkList(reader.getBoolList(), {true, false, false, true}); checkList(reader.getBoolList(), {true, false, false, true});
...@@ -214,7 +218,6 @@ void genericCheckTestMessage(Reader reader) { ...@@ -214,7 +218,6 @@ void genericCheckTestMessage(Reader reader) {
checkList(reader.getFloat64List(), {7777.75, 1111.125}); checkList(reader.getFloat64List(), {7777.75, 1111.125});
checkList(reader.getTextList(), {"plugh", "xyzzy", "thud"}); checkList(reader.getTextList(), {"plugh", "xyzzy", "thud"});
checkList(reader.getDataList(), {"oops", "exhausted", "rfc3092"}); checkList(reader.getDataList(), {"oops", "exhausted", "rfc3092"});
{ {
auto listReader = reader.getStructList(); auto listReader = reader.getStructList();
ASSERT_EQ(3u, listReader.size()); ASSERT_EQ(3u, listReader.size());
...@@ -222,6 +225,7 @@ void genericCheckTestMessage(Reader reader) { ...@@ -222,6 +225,7 @@ void genericCheckTestMessage(Reader reader) {
EXPECT_EQ("structlist 2", listReader[1].getTextField()); EXPECT_EQ("structlist 2", listReader[1].getTextField());
EXPECT_EQ("structlist 3", listReader[2].getTextField()); EXPECT_EQ("structlist 3", listReader[2].getTextField());
} }
checkList(reader.getEnumList(), {TestEnum::FOO, TestEnum::GARPLY});
} }
template <typename Reader> template <typename Reader>
......
...@@ -21,6 +21,17 @@ ...@@ -21,6 +21,17 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum TestEnum {
foo @0;
bar @1;
baz @2;
qux @3;
quux @4;
corge @5;
grault @6;
garply @7;
}
struct TestAllTypes { struct TestAllTypes {
voidField @0 : Void; voidField @0 : Void;
boolField @1 : Bool; boolField @1 : Bool;
...@@ -37,7 +48,7 @@ struct TestAllTypes { ...@@ -37,7 +48,7 @@ struct TestAllTypes {
textField @12 : Text; textField @12 : Text;
dataField @13 : Data; dataField @13 : Data;
structField @14 : TestAllTypes; structField @14 : TestAllTypes;
enumField @15 : Void; # TODO enumField @15 : TestEnum;
interfaceField @16 : Void; # TODO interfaceField @16 : Void; # TODO
voidList @17 : List(Void); voidList @17 : List(Void);
...@@ -55,7 +66,7 @@ struct TestAllTypes { ...@@ -55,7 +66,7 @@ struct TestAllTypes {
textList @29 : List(Text); textList @29 : List(Text);
dataList @30 : List(Data); dataList @30 : List(Data);
structList @31 : List(TestAllTypes); structList @31 : List(TestAllTypes);
enumList @32 : Void; # TODO enumList @32 : List(TestEnum);
interfaceList @33 : Void; # TODO interfaceList @33 : Void; # TODO
} }
...@@ -92,7 +103,7 @@ struct TestDefaults { ...@@ -92,7 +103,7 @@ struct TestDefaults {
structField = ( structField = (
textField = "nested", textField = "nested",
structField = (textField = "really nested")), structField = (textField = "really nested")),
# enumField = TODO enumField = baz,
# interfaceField can't have a default # interfaceField can't have a default
voidList = [void, void, void], voidList = [void, void, void],
...@@ -112,11 +123,11 @@ struct TestDefaults { ...@@ -112,11 +123,11 @@ struct TestDefaults {
structList = [ structList = [
(textField = "x structlist 1"), (textField = "x structlist 1"),
(textField = "x structlist 2"), (textField = "x structlist 2"),
(textField = "x structlist 3")] (textField = "x structlist 3")],
# enumList = TODO enumList = [qux, bar, grault]
# interfaceList can't have a default # interfaceList can't have a default
); );
enumField @15 : Void; # TODO enumField @15 : TestEnum = corge;
interfaceField @16 : Void; # TODO interfaceField @16 : Void; # TODO
voidList @17 : List(Void) = [void, void, void, void, void, void]; voidList @17 : List(Void) = [void, void, void, void, void, void];
...@@ -137,6 +148,6 @@ struct TestDefaults { ...@@ -137,6 +148,6 @@ struct TestDefaults {
(textField = "structlist 1"), (textField = "structlist 1"),
(textField = "structlist 2"), (textField = "structlist 2"),
(textField = "structlist 3")]; (textField = "structlist 3")];
enumList @32 : List(Void); # TODO enumList @32 : List(TestEnum) = [foo, garply];
interfaceList @33 : List(Void); # TODO interfaceList @33 : List(Void); # TODO
} }
...@@ -298,10 +298,10 @@ requireSequentialNumbering kind items = Active () (loop undefined (-1) sortedIte ...@@ -298,10 +298,10 @@ requireSequentialNumbering kind items = Active () (loop undefined (-1) sortedIte
message = printf "Skipped number %d. %s must be numbered sequentially starting \ message = printf "Skipped number %d. %s must be numbered sequentially starting \
\from zero." (prev + 1) kind \from zero." (prev + 1) kind
requireFieldNumbersInRange fieldNums = requireOrdinalsInRange ordinals =
Active () [ fieldNumError num pos | Located pos num <- fieldNums, num > maxFieldNumber ] where Active () [ ordinalError num pos | Located pos num <- ordinals, num > maxOrdinal ] where
fieldNumError num = newErrorMessage (Message ordinalError num = newErrorMessage (Message
(printf "Field number %d too large; maximum is %d." num maxFieldNumber)) (printf "Ordinal %d too large; maximum is %d." num maxOrdinal))
requireNoDuplicateNames :: [Declaration] -> Status() requireNoDuplicateNames :: [Declaration] -> Status()
requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where
...@@ -497,7 +497,9 @@ compileDecl scope (EnumDecl (Located _ name) decls) = ...@@ -497,7 +497,9 @@ compileDecl scope (EnumDecl (Located _ name) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(members, memberMap, options, statements) <- compileChildDecls desc decls (members, memberMap, options, statements) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
requireSequentialNumbering "Enum values" [ num | EnumValueDecl _ num _ <- decls ] let numbers = [ num | EnumValueDecl _ num _ <- decls ]
requireSequentialNumbering "Enum values" numbers
requireOrdinalsInRange numbers
return (DescEnum EnumDesc return (DescEnum EnumDesc
{ enumName = name { enumName = name
, enumParent = scope , enumParent = scope
...@@ -527,7 +529,7 @@ compileDecl scope (StructDecl (Located _ name) decls) = ...@@ -527,7 +529,7 @@ compileDecl scope (StructDecl (Located _ name) decls) =
let fieldNums = [ num | FieldDecl _ num _ _ _ _ <- decls ] ++ let fieldNums = [ num | FieldDecl _ num _ _ _ _ <- decls ] ++
[ num | UnionDecl _ num _ <- decls ] [ num | UnionDecl _ num _ <- decls ]
requireSequentialNumbering "Fields" fieldNums requireSequentialNumbering "Fields" fieldNums
requireFieldNumbersInRange fieldNums requireOrdinalsInRange fieldNums
return (let return (let
fields = [d | DescField d <- members] fields = [d | DescField d <- members]
unions = [d | DescUnion d <- members] unions = [d | DescUnion d <- members]
...@@ -611,7 +613,9 @@ compileDecl scope (InterfaceDecl (Located _ name) decls) = ...@@ -611,7 +613,9 @@ compileDecl scope (InterfaceDecl (Located _ name) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(members, memberMap, options, statements) <- compileChildDecls desc decls (members, memberMap, options, statements) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
requireSequentialNumbering "Methods" [ num | MethodDecl _ num _ _ _ <- decls ] let numbers = [ num | MethodDecl _ num _ _ _ <- decls ]
requireSequentialNumbering "Methods" numbers
requireOrdinalsInRange numbers
return (DescInterface InterfaceDesc return (DescInterface InterfaceDesc
{ interfaceName = name { interfaceName = name
, interfaceParent = scope , interfaceParent = scope
......
...@@ -25,11 +25,8 @@ module Parser (parseFile) where ...@@ -25,11 +25,8 @@ module Parser (parseFile) where
import Text.Parsec hiding (tokens) import Text.Parsec hiding (tokens)
import Text.Parsec.Error(newErrorMessage, Message(Message)) import Text.Parsec.Error(newErrorMessage, Message(Message))
import Text.Parsec.Pos(newPos)
import Text.Printf(printf)
import Token import Token
import Grammar import Grammar
import Semantics(maxFieldNumber, maxMethodNumber)
import Lexer (lexer) import Lexer (lexer)
import Control.Monad.Identity import Control.Monad.Identity
...@@ -147,21 +144,11 @@ typeExpression = do ...@@ -147,21 +144,11 @@ typeExpression = do
suffixes <- option [] (parenthesizedList typeExpression) suffixes <- option [] (parenthesizedList typeExpression)
return (TypeExpression name suffixes) return (TypeExpression name suffixes)
nameWithOrdinal :: Integer -> TokenParser (Located String, Located Integer) nameWithOrdinal :: TokenParser (Located String, Located Integer)
nameWithOrdinal maxNumber = do nameWithOrdinal = do
name <- located varIdentifier name <- located varIdentifier
atSign atSign
ordinal <- located literalInt ordinal <- located literalInt
if locatedValue ordinal > maxNumber - 32 && locatedValue ordinal <= maxNumber
then exclamationPoint
<|> failNonFatal (locatedPos ordinal)
(printf "%d is nearing maximum of %d. Be sure to plan for future extensibility \
\before you run out of numbers, e.g. by declaring a new nested type which \
\can hold future declarations. To acknowledge this warning, add an \
\exclamation point after the number, i.e.: %s@%d!"
(locatedValue ordinal) maxNumber (locatedValue name)
(locatedValue ordinal))
else optional exclamationPoint
return (name, ordinal) return (name, ordinal)
topLine :: Maybe [Located Statement] -> TokenParser Declaration topLine :: Maybe [Located Statement] -> TokenParser Declaration
...@@ -199,9 +186,7 @@ enumLine Nothing = optionDecl <|> enumValueDecl [] ...@@ -199,9 +186,7 @@ enumLine Nothing = optionDecl <|> enumValueDecl []
enumLine (Just statements) = enumValueDecl statements enumLine (Just statements) = enumValueDecl statements
enumValueDecl statements = do enumValueDecl statements = do
name <- located varIdentifier (name, value) <- nameWithOrdinal
equalsSign
value <- located literalInt
children <- parseBlock enumValueLine statements children <- parseBlock enumValueLine statements
return (EnumValueDecl name value children) return (EnumValueDecl name value children)
...@@ -221,7 +206,7 @@ structLine (Just statements) = typeDecl statements <|> unionDecl statements <|> ...@@ -221,7 +206,7 @@ structLine (Just statements) = typeDecl statements <|> unionDecl statements <|>
unionDecl statements = do unionDecl statements = do
unionKeyword unionKeyword
(name, ordinal) <- nameWithOrdinal maxFieldNumber (name, ordinal) <- nameWithOrdinal
children <- parseBlock unionLine statements children <- parseBlock unionLine statements
return (UnionDecl name ordinal children) return (UnionDecl name ordinal children)
...@@ -230,7 +215,7 @@ unionLine Nothing = optionDecl <|> fieldDecl [] ...@@ -230,7 +215,7 @@ unionLine Nothing = optionDecl <|> fieldDecl []
unionLine (Just statements) = fieldDecl statements unionLine (Just statements) = fieldDecl statements
fieldDecl statements = do fieldDecl statements = do
(name, ordinal) <- nameWithOrdinal maxFieldNumber (name, ordinal) <- nameWithOrdinal
union <- optionMaybe (inKeyword >> located varIdentifier) union <- optionMaybe (inKeyword >> located varIdentifier)
colon colon
t <- typeExpression t <- typeExpression
...@@ -273,7 +258,7 @@ interfaceLine Nothing = optionDecl <|> constantDecl <|> methodDecl [] ...@@ -273,7 +258,7 @@ interfaceLine Nothing = optionDecl <|> constantDecl <|> methodDecl []
interfaceLine (Just statements) = typeDecl statements <|> methodDecl statements interfaceLine (Just statements) = typeDecl statements <|> methodDecl statements
methodDecl statements = do methodDecl statements = do
(name, ordinal) <- nameWithOrdinal maxMethodNumber (name, ordinal) <- nameWithOrdinal
params <- parenthesizedList paramDecl params <- parenthesizedList paramDecl
colon colon
t <- typeExpression t <- typeExpression
......
...@@ -33,13 +33,9 @@ import Text.Printf(printf) ...@@ -33,13 +33,9 @@ import Text.Printf(printf)
import Control.Monad(join) import Control.Monad(join)
import Util(delimit) import Util(delimit)
-- Field counts are 8-bit, therefore there cannot be more than 255 fields, therefore the max field -- Field counts are 16-bit, therefore there cannot be more than 65535 fields, therefore the max
-- number is 254. -- ordinal is 65534.
maxFieldNumber = 254 :: Integer maxOrdinal = 65534 :: Integer
-- Limiting method counts is not as important technically, but obviously it would be insane to have
-- anywhere near 2^16 methods.
maxMethodNumber = 65534 :: Integer
type ByteString = [Word8] type ByteString = [Word8]
...@@ -404,7 +400,7 @@ descToCode indent (DescConstant desc) = printf "%sconst %s: %s = %s;\n" indent ...@@ -404,7 +400,7 @@ descToCode indent (DescConstant desc) = printf "%sconst %s: %s = %s;\n" indent
descToCode indent (DescEnum desc) = printf "%senum %s%s" indent descToCode indent (DescEnum desc) = printf "%senum %s%s" indent
(enumName desc) (enumName desc)
(blockCode indent (enumStatements desc)) (blockCode indent (enumStatements desc))
descToCode indent (DescEnumValue desc) = printf "%s%s = %d%s" indent descToCode indent (DescEnumValue desc) = printf "%s%s @%d%s" indent
(enumValueName desc) (enumValueNumber desc) (maybeBlockCode indent $ enumValueStatements desc) (enumValueName desc) (enumValueNumber desc) (maybeBlockCode indent $ enumValueStatements desc)
descToCode indent (DescStruct desc) = printf "%sstruct %s%s" indent descToCode indent (DescStruct desc) = printf "%sstruct %s%s" indent
(structName desc) (structName desc)
......
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