Commit ba5c0d67 authored by Kenton Varda's avatar Kenton Varda

Merge branch 'master' of github.com:kentonv/capnproto

parents 9fa79341 b2d752be
...@@ -41,12 +41,20 @@ ...@@ -41,12 +41,20 @@
namespace capnp { namespace capnp {
namespace benchmark { namespace benchmark {
// Use a 128-bit Xorshift algorithm.
static inline uint32_t nextFastRand() { static inline uint32_t nextFastRand() {
static constexpr uint32_t A = 1664525; // These values are arbitrary. Any seed other than all zeroes is OK.
static constexpr uint32_t C = 1013904223; static uint32_t x = 0x1d2acd47;
static uint32_t state = C; static uint32_t y = 0x58ca3e14;
state = A * state + C; static uint32_t z = 0xf563f232;
return state; static uint32_t w = 0x0bc76199;
uint32_t tmp = x ^ (x << 11);
x = y;
y = z;
z = w;
w = w ^ (w >> 19) ^ tmp ^ (tmp >> 8);
return w;
} }
static inline uint32_t fastRand(uint32_t range) { static inline uint32_t fastRand(uint32_t range) {
......
...@@ -243,7 +243,7 @@ public: ...@@ -243,7 +243,7 @@ public:
"If a file specified for compilation starts with <prefix>, remove " "If a file specified for compilation starts with <prefix>, remove "
"the prefix for the purpose of deciding the names of output files. " "the prefix for the purpose of deciding the names of output files. "
"For example, the following command:\n" "For example, the following command:\n"
" capnp --src-prefix=foo/bar -oc++:corge foo/bar/baz/qux.capnp\n" " capnp compile --src-prefix=foo/bar -oc++:corge foo/bar/baz/qux.capnp\n"
"would generate the files corge/baz/qux.capnp.{h,c++}.") "would generate the files corge/baz/qux.capnp.{h,c++}.")
.expectOneOrMoreArgs("<source>", KJ_BIND_METHOD(*this, addSource)) .expectOneOrMoreArgs("<source>", KJ_BIND_METHOD(*this, addSource))
.callAfterParsing(KJ_BIND_METHOD(*this, generateOutput)); .callAfterParsing(KJ_BIND_METHOD(*this, generateOutput));
......
...@@ -96,6 +96,7 @@ struct ValueExpression { ...@@ -96,6 +96,7 @@ struct ValueExpression {
negativeInt @2 :UInt64; negativeInt @2 :UInt64;
float @3 :Float64; float @3 :Float64;
string @4 :Text; string @4 :Text;
binary @10 :Data;
name @5 :DeclName; name @5 :DeclName;
list @6 :List(ValueExpression); list @6 :List(ValueExpression);
struct @7 :List(FieldAssignment); struct @7 :List(FieldAssignment);
......
This diff is collapsed.
...@@ -83,6 +83,7 @@ struct ValueExpression { ...@@ -83,6 +83,7 @@ struct ValueExpression {
NAME, NAME,
LIST, LIST,
STRUCT, STRUCT,
BINARY,
}; };
struct FieldAssignment; struct FieldAssignment;
}; };
...@@ -1003,6 +1004,10 @@ public: ...@@ -1003,6 +1004,10 @@ public:
inline ::uint32_t getEndByte() const; inline ::uint32_t getEndByte() const;
inline bool isBinary() const;
inline bool hasBinary() const;
inline ::capnp::Data::Reader getBinary() const;
private: private:
::capnp::_::StructReader _reader; ::capnp::_::StructReader _reader;
template <typename T, ::capnp::Kind k> template <typename T, ::capnp::Kind k>
...@@ -1088,6 +1093,14 @@ public: ...@@ -1088,6 +1093,14 @@ public:
inline ::uint32_t getEndByte(); inline ::uint32_t getEndByte();
inline void setEndByte( ::uint32_t value); inline void setEndByte( ::uint32_t value);
inline bool isBinary();
inline bool hasBinary();
inline ::capnp::Data::Builder getBinary();
inline void setBinary( ::capnp::Data::Reader value);
inline ::capnp::Data::Builder initBinary(unsigned int size);
inline void adoptBinary(::capnp::Orphan< ::capnp::Data>&& value);
inline ::capnp::Orphan< ::capnp::Data> disownBinary();
private: private:
::capnp::_::StructBuilder _builder; ::capnp::_::StructBuilder _builder;
template <typename T, ::capnp::Kind k> template <typename T, ::capnp::Kind k>
...@@ -3763,6 +3776,58 @@ inline void ValueExpression::Builder::setEndByte( ::uint32_t value) { ...@@ -3763,6 +3776,58 @@ inline void ValueExpression::Builder::setEndByte( ::uint32_t value) {
4 * ::capnp::ELEMENTS, value); 4 * ::capnp::ELEMENTS, value);
} }
inline bool ValueExpression::Reader::isBinary() const {
return which() == ValueExpression::BINARY;
}
inline bool ValueExpression::Builder::isBinary() {
return which() == ValueExpression::BINARY;
}
inline bool ValueExpression::Reader::hasBinary() const {
if (which() != ValueExpression::BINARY) return false;
return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
}
inline bool ValueExpression::Builder::hasBinary() {
if (which() != ValueExpression::BINARY) return false;
return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull();
}
inline ::capnp::Data::Reader ValueExpression::Reader::getBinary() const {
KJ_IREQUIRE(which() == ValueExpression::BINARY,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::capnp::Data>::get(
_reader.getPointerField(0 * ::capnp::POINTERS));
}
inline ::capnp::Data::Builder ValueExpression::Builder::getBinary() {
KJ_IREQUIRE(which() == ValueExpression::BINARY,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::capnp::Data>::get(
_builder.getPointerField(0 * ::capnp::POINTERS));
}
inline void ValueExpression::Builder::setBinary( ::capnp::Data::Reader value) {
_builder.setDataField<ValueExpression::Which>(
0 * ::capnp::ELEMENTS, ValueExpression::BINARY);
::capnp::_::PointerHelpers< ::capnp::Data>::set(
_builder.getPointerField(0 * ::capnp::POINTERS), value);
}
inline ::capnp::Data::Builder ValueExpression::Builder::initBinary(unsigned int size) {
_builder.setDataField<ValueExpression::Which>(
0 * ::capnp::ELEMENTS, ValueExpression::BINARY);
return ::capnp::_::PointerHelpers< ::capnp::Data>::init(
_builder.getPointerField(0 * ::capnp::POINTERS), size);
}
inline void ValueExpression::Builder::adoptBinary(
::capnp::Orphan< ::capnp::Data>&& value) {
_builder.setDataField<ValueExpression::Which>(
0 * ::capnp::ELEMENTS, ValueExpression::BINARY);
::capnp::_::PointerHelpers< ::capnp::Data>::adopt(
_builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Data> ValueExpression::Builder::disownBinary() {
KJ_IREQUIRE(which() == ValueExpression::BINARY,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::capnp::Data>::disown(
_builder.getPointerField(0 * ::capnp::POINTERS));
}
inline bool ValueExpression::FieldAssignment::Reader::hasFieldName() const { inline bool ValueExpression::FieldAssignment::Reader::hasFieldName() const {
return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
} }
......
...@@ -173,6 +173,13 @@ Lexer::Lexer(Orphanage orphanageParam, ErrorReporter& errorReporterParam) ...@@ -173,6 +173,13 @@ Lexer::Lexer(Orphanage orphanageParam, ErrorReporter& errorReporterParam)
initTok(t, loc).setStringLiteral(text); initTok(t, loc).setStringLiteral(text);
return t; return t;
}), }),
p::transformWithLocation(p::doubleQuotedHexBinary,
[this](Location loc, kj::Array<char> data) -> Orphan<Token> {
auto t = orphanage.newOrphan<Token>();
kj::ArrayPtr<byte> dataPtr(reinterpret_cast<byte*>(data.begin()), reinterpret_cast<byte*>(data.end()));
initTok(t, loc).setBinaryLiteral(dataPtr);
return t;
}),
p::transformWithLocation(p::integer, p::transformWithLocation(p::integer,
[this](Location loc, uint64_t i) -> Orphan<Token> { [this](Location loc, uint64_t i) -> Orphan<Token> {
auto t = orphanage.newOrphan<Token>(); auto t = orphanage.newOrphan<Token>();
......
...@@ -29,6 +29,7 @@ struct Token { ...@@ -29,6 +29,7 @@ struct Token {
union { union {
identifier @0 :Text; identifier @0 :Text;
stringLiteral @1 :Text; stringLiteral @1 :Text;
binaryLiteral @9 :Data;
integerLiteral @2 :UInt64; integerLiteral @2 :UInt64;
floatLiteral @3 :Float64; floatLiteral @3 :Float64;
operator @4 :Text; operator @4 :Text;
......
This diff is collapsed.
...@@ -28,6 +28,7 @@ struct Token { ...@@ -28,6 +28,7 @@ struct Token {
OPERATOR, OPERATOR,
PARENTHESIZED_LIST, PARENTHESIZED_LIST,
BRACKETED_LIST, BRACKETED_LIST,
BINARY_LITERAL,
}; };
}; };
...@@ -138,6 +139,10 @@ public: ...@@ -138,6 +139,10 @@ public:
inline ::uint32_t getEndByte() const; inline ::uint32_t getEndByte() const;
inline bool isBinaryLiteral() const;
inline bool hasBinaryLiteral() const;
inline ::capnp::Data::Reader getBinaryLiteral() const;
private: private:
::capnp::_::StructReader _reader; ::capnp::_::StructReader _reader;
template <typename T, ::capnp::Kind k> template <typename T, ::capnp::Kind k>
...@@ -225,6 +230,14 @@ public: ...@@ -225,6 +230,14 @@ public:
inline ::uint32_t getEndByte(); inline ::uint32_t getEndByte();
inline void setEndByte( ::uint32_t value); inline void setEndByte( ::uint32_t value);
inline bool isBinaryLiteral();
inline bool hasBinaryLiteral();
inline ::capnp::Data::Builder getBinaryLiteral();
inline void setBinaryLiteral( ::capnp::Data::Reader value);
inline ::capnp::Data::Builder initBinaryLiteral(unsigned int size);
inline void adoptBinaryLiteral(::capnp::Orphan< ::capnp::Data>&& value);
inline ::capnp::Orphan< ::capnp::Data> disownBinaryLiteral();
private: private:
::capnp::_::StructBuilder _builder; ::capnp::_::StructBuilder _builder;
template <typename T, ::capnp::Kind k> template <typename T, ::capnp::Kind k>
...@@ -884,6 +897,58 @@ inline void Token::Builder::setEndByte( ::uint32_t value) { ...@@ -884,6 +897,58 @@ inline void Token::Builder::setEndByte( ::uint32_t value) {
4 * ::capnp::ELEMENTS, value); 4 * ::capnp::ELEMENTS, value);
} }
inline bool Token::Reader::isBinaryLiteral() const {
return which() == Token::BINARY_LITERAL;
}
inline bool Token::Builder::isBinaryLiteral() {
return which() == Token::BINARY_LITERAL;
}
inline bool Token::Reader::hasBinaryLiteral() const {
if (which() != Token::BINARY_LITERAL) return false;
return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
}
inline bool Token::Builder::hasBinaryLiteral() {
if (which() != Token::BINARY_LITERAL) return false;
return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull();
}
inline ::capnp::Data::Reader Token::Reader::getBinaryLiteral() const {
KJ_IREQUIRE(which() == Token::BINARY_LITERAL,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::capnp::Data>::get(
_reader.getPointerField(0 * ::capnp::POINTERS));
}
inline ::capnp::Data::Builder Token::Builder::getBinaryLiteral() {
KJ_IREQUIRE(which() == Token::BINARY_LITERAL,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::capnp::Data>::get(
_builder.getPointerField(0 * ::capnp::POINTERS));
}
inline void Token::Builder::setBinaryLiteral( ::capnp::Data::Reader value) {
_builder.setDataField<Token::Which>(
0 * ::capnp::ELEMENTS, Token::BINARY_LITERAL);
::capnp::_::PointerHelpers< ::capnp::Data>::set(
_builder.getPointerField(0 * ::capnp::POINTERS), value);
}
inline ::capnp::Data::Builder Token::Builder::initBinaryLiteral(unsigned int size) {
_builder.setDataField<Token::Which>(
0 * ::capnp::ELEMENTS, Token::BINARY_LITERAL);
return ::capnp::_::PointerHelpers< ::capnp::Data>::init(
_builder.getPointerField(0 * ::capnp::POINTERS), size);
}
inline void Token::Builder::adoptBinaryLiteral(
::capnp::Orphan< ::capnp::Data>&& value) {
_builder.setDataField<Token::Which>(
0 * ::capnp::ELEMENTS, Token::BINARY_LITERAL);
::capnp::_::PointerHelpers< ::capnp::Data>::adopt(
_builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Data> Token::Builder::disownBinaryLiteral() {
KJ_IREQUIRE(which() == Token::BINARY_LITERAL,
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::capnp::Data>::disown(
_builder.getPointerField(0 * ::capnp::POINTERS));
}
inline Statement::Which Statement::Reader::which() const { inline Statement::Which Statement::Reader::which() const {
return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS); return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS);
} }
......
...@@ -1859,6 +1859,13 @@ Orphan<DynamicValue> ValueTranslator::compileValueInner( ...@@ -1859,6 +1859,13 @@ Orphan<DynamicValue> ValueTranslator::compileValueInner(
} }
break; break;
case ValueExpression::BINARY:
if (!type.isData()) {
errorReporter.addErrorOn(src, kj::str("Type mismatch; expected ", makeTypeName(type), "."));
return nullptr;
}
return orphanage.newOrphanCopy(src.getBinary());
case ValueExpression::LIST: { case ValueExpression::LIST: {
if (!type.isList()) { if (!type.isList()) {
errorReporter.addErrorOn(src, kj::str("Type mismatch; expected ", makeTypeName(type), ".")); errorReporter.addErrorOn(src, kj::str("Type mismatch; expected ", makeTypeName(type), "."));
......
...@@ -227,6 +227,7 @@ struct MatchTokenType { ...@@ -227,6 +227,7 @@ struct MatchTokenType {
constexpr auto identifier = TOKEN_TYPE_PARSER(Text::Reader, IDENTIFIER, getIdentifier); constexpr auto identifier = TOKEN_TYPE_PARSER(Text::Reader, IDENTIFIER, getIdentifier);
constexpr auto stringLiteral = TOKEN_TYPE_PARSER(Text::Reader, STRING_LITERAL, getStringLiteral); constexpr auto stringLiteral = TOKEN_TYPE_PARSER(Text::Reader, STRING_LITERAL, getStringLiteral);
constexpr auto binaryLiteral = TOKEN_TYPE_PARSER(Data::Reader, BINARY_LITERAL, getBinaryLiteral);
constexpr auto integerLiteral = TOKEN_TYPE_PARSER(uint64_t, INTEGER_LITERAL, getIntegerLiteral); constexpr auto integerLiteral = TOKEN_TYPE_PARSER(uint64_t, INTEGER_LITERAL, getIntegerLiteral);
constexpr auto floatLiteral = TOKEN_TYPE_PARSER(double, FLOAT_LITERAL, getFloatLiteral); constexpr auto floatLiteral = TOKEN_TYPE_PARSER(double, FLOAT_LITERAL, getFloatLiteral);
constexpr auto operatorToken = TOKEN_TYPE_PARSER(Text::Reader, OPERATOR, getOperator); constexpr auto operatorToken = TOKEN_TYPE_PARSER(Text::Reader, OPERATOR, getOperator);
...@@ -551,6 +552,14 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP ...@@ -551,6 +552,14 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
value.copyLocationTo(builder); value.copyLocationTo(builder);
return result; return result;
}), }),
p::transform(binaryLiteral,
[this](Located<Data::Reader>&& value) -> Orphan<ValueExpression> {
auto result = orphanage.newOrphan<ValueExpression>();
auto builder = result.get();
builder.setBinary(value.value);
value.copyLocationTo(builder);
return result;
}),
p::transformWithLocation(parsers.declName, p::transformWithLocation(parsers.declName,
[this](kj::parse::Span<List<Token>::Reader::Iterator> location, [this](kj::parse::Span<List<Token>::Reader::Iterator> location,
Orphan<DeclName>&& value) -> Orphan<ValueExpression> { Orphan<DeclName>&& value) -> Orphan<ValueExpression> {
......
...@@ -90,7 +90,7 @@ struct TestDefaults { ...@@ -90,7 +90,7 @@ struct TestDefaults {
float32Field @10 : Float32 = 1234.5; float32Field @10 : Float32 = 1234.5;
float64Field @11 : Float64 = -123e45; float64Field @11 : Float64 = -123e45;
textField @12 : Text = "foo"; textField @12 : Text = "foo";
dataField @13 : Data = "bar"; dataField @13 : Data = 0x"62 61 72"; # "bar"
structField @14 : TestAllTypes = ( structField @14 : TestAllTypes = (
voidField = void, voidField = void,
boolField = true, boolField = true,
......
...@@ -238,7 +238,7 @@ struct ParseInteger { ...@@ -238,7 +238,7 @@ struct ParseInteger {
constexpr auto integer = sequence( constexpr auto integer = sequence(
oneOf( oneOf(
transform(sequence(exactChar<'0'>(), exactChar<'x'>(), many(hexDigit)), _::ParseInteger<16>()), transform(sequence(exactChar<'0'>(), exactChar<'x'>(), oneOrMore(hexDigit)), _::ParseInteger<16>()),
transform(sequence(exactChar<'0'>(), many(octDigit)), _::ParseInteger<8>()), transform(sequence(exactChar<'0'>(), many(octDigit)), _::ParseInteger<8>()),
transform(sequence(charRange('1', '9'), many(digit)), _::ParseInteger<10>())), transform(sequence(charRange('1', '9'), many(digit)), _::ParseInteger<10>())),
notLookingAt(alpha.orAny("_."))); notLookingAt(alpha.orAny("_.")));
...@@ -326,6 +326,13 @@ constexpr auto singleQuotedString = charsToString(sequence( ...@@ -326,6 +326,13 @@ constexpr auto singleQuotedString = charsToString(sequence(
exactChar<'\''>())); exactChar<'\''>()));
// Parses a C-style single-quoted string. // Parses a C-style single-quoted string.
constexpr auto doubleQuotedHexBinary = sequence(
exactChar<'0'>(), exactChar<'x'>(), exactChar<'\"'>(),
oneOrMore(transform(sequence(discardWhitespace, hexDigit, hexDigit), _::ParseHexEscape())),
discardWhitespace,
exactChar<'\"'>());
// Parses a double-quoted hex binary literal.
} // namespace parse } // namespace parse
} // namespace kj } // namespace kj
......
...@@ -123,6 +123,7 @@ bar @1 :Text = "blah"; ...@@ -123,6 +123,7 @@ bar @1 :Text = "blah";
baz @2 :List(Bool) = [ true, false, false, true ]; baz @2 :List(Bool) = [ true, false, false, true ];
qux @3 :Person = (name = "Bob", email = "bob@example.com"); qux @3 :Person = (name = "Bob", email = "bob@example.com");
corge @4 :Void = void; corge @4 :Void = void;
grault @5 :Data = 0x"a1 40 33";
{% endhighlight %} {% endhighlight %}
### Unions ### Unions
...@@ -360,6 +361,7 @@ tool](capnp-tool.html#evaluating_constants). ...@@ -360,6 +361,7 @@ tool](capnp-tool.html#evaluating_constants).
{% highlight capnp %} {% highlight capnp %}
const pi :Float32 = 3.14159; const pi :Float32 = 3.14159;
const bob :Person = (name = "Bob", email = "bob@example.com"); const bob :Person = (name = "Bob", email = "bob@example.com");
const secret :Data = 0x"9f98739c2b53835e 6720a00907abd42f";
{% endhighlight %} {% endhighlight %}
Additionally, you may refer to a constant inside another value (e.g. another constant, or a default Additionally, you may refer to a constant inside another value (e.g. another constant, or a default
......
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