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 @@
namespace capnp {
namespace benchmark {
// Use a 128-bit Xorshift algorithm.
static inline uint32_t nextFastRand() {
static constexpr uint32_t A = 1664525;
static constexpr uint32_t C = 1013904223;
static uint32_t state = C;
state = A * state + C;
return state;
// These values are arbitrary. Any seed other than all zeroes is OK.
static uint32_t x = 0x1d2acd47;
static uint32_t y = 0x58ca3e14;
static uint32_t z = 0xf563f232;
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) {
......
......@@ -243,7 +243,7 @@ public:
"If a file specified for compilation starts with <prefix>, remove "
"the prefix for the purpose of deciding the names of output files. "
"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++}.")
.expectOneOrMoreArgs("<source>", KJ_BIND_METHOD(*this, addSource))
.callAfterParsing(KJ_BIND_METHOD(*this, generateOutput));
......
......@@ -96,6 +96,7 @@ struct ValueExpression {
negativeInt @2 :UInt64;
float @3 :Float64;
string @4 :Text;
binary @10 :Data;
name @5 :DeclName;
list @6 :List(ValueExpression);
struct @7 :List(FieldAssignment);
......
This diff is collapsed.
......@@ -83,6 +83,7 @@ struct ValueExpression {
NAME,
LIST,
STRUCT,
BINARY,
};
struct FieldAssignment;
};
......@@ -1003,6 +1004,10 @@ public:
inline ::uint32_t getEndByte() const;
inline bool isBinary() const;
inline bool hasBinary() const;
inline ::capnp::Data::Reader getBinary() const;
private:
::capnp::_::StructReader _reader;
template <typename T, ::capnp::Kind k>
......@@ -1088,6 +1093,14 @@ public:
inline ::uint32_t getEndByte();
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:
::capnp::_::StructBuilder _builder;
template <typename T, ::capnp::Kind k>
......@@ -3763,6 +3776,58 @@ inline void ValueExpression::Builder::setEndByte( ::uint32_t 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 {
return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
}
......
......@@ -173,6 +173,13 @@ Lexer::Lexer(Orphanage orphanageParam, ErrorReporter& errorReporterParam)
initTok(t, loc).setStringLiteral(text);
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,
[this](Location loc, uint64_t i) -> Orphan<Token> {
auto t = orphanage.newOrphan<Token>();
......
......@@ -29,6 +29,7 @@ struct Token {
union {
identifier @0 :Text;
stringLiteral @1 :Text;
binaryLiteral @9 :Data;
integerLiteral @2 :UInt64;
floatLiteral @3 :Float64;
operator @4 :Text;
......
This diff is collapsed.
......@@ -28,6 +28,7 @@ struct Token {
OPERATOR,
PARENTHESIZED_LIST,
BRACKETED_LIST,
BINARY_LITERAL,
};
};
......@@ -138,6 +139,10 @@ public:
inline ::uint32_t getEndByte() const;
inline bool isBinaryLiteral() const;
inline bool hasBinaryLiteral() const;
inline ::capnp::Data::Reader getBinaryLiteral() const;
private:
::capnp::_::StructReader _reader;
template <typename T, ::capnp::Kind k>
......@@ -225,6 +230,14 @@ public:
inline ::uint32_t getEndByte();
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:
::capnp::_::StructBuilder _builder;
template <typename T, ::capnp::Kind k>
......@@ -884,6 +897,58 @@ inline void Token::Builder::setEndByte( ::uint32_t 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 {
return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS);
}
......
......@@ -1859,6 +1859,13 @@ Orphan<DynamicValue> ValueTranslator::compileValueInner(
}
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: {
if (!type.isList()) {
errorReporter.addErrorOn(src, kj::str("Type mismatch; expected ", makeTypeName(type), "."));
......
......@@ -227,6 +227,7 @@ struct MatchTokenType {
constexpr auto identifier = TOKEN_TYPE_PARSER(Text::Reader, IDENTIFIER, getIdentifier);
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 floatLiteral = TOKEN_TYPE_PARSER(double, FLOAT_LITERAL, getFloatLiteral);
constexpr auto operatorToken = TOKEN_TYPE_PARSER(Text::Reader, OPERATOR, getOperator);
......@@ -551,6 +552,14 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
value.copyLocationTo(builder);
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,
[this](kj::parse::Span<List<Token>::Reader::Iterator> location,
Orphan<DeclName>&& value) -> Orphan<ValueExpression> {
......
......@@ -90,7 +90,7 @@ struct TestDefaults {
float32Field @10 : Float32 = 1234.5;
float64Field @11 : Float64 = -123e45;
textField @12 : Text = "foo";
dataField @13 : Data = "bar";
dataField @13 : Data = 0x"62 61 72"; # "bar"
structField @14 : TestAllTypes = (
voidField = void,
boolField = true,
......
......@@ -238,7 +238,7 @@ struct ParseInteger {
constexpr auto integer = sequence(
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(charRange('1', '9'), many(digit)), _::ParseInteger<10>())),
notLookingAt(alpha.orAny("_.")));
......@@ -326,6 +326,13 @@ constexpr auto singleQuotedString = charsToString(sequence(
exactChar<'\''>()));
// 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 kj
......
......@@ -123,6 +123,7 @@ bar @1 :Text = "blah";
baz @2 :List(Bool) = [ true, false, false, true ];
qux @3 :Person = (name = "Bob", email = "bob@example.com");
corge @4 :Void = void;
grault @5 :Data = 0x"a1 40 33";
{% endhighlight %}
### Unions
......@@ -360,6 +361,7 @@ tool](capnp-tool.html#evaluating_constants).
{% highlight capnp %}
const pi :Float32 = 3.14159;
const bob :Person = (name = "Bob", email = "bob@example.com");
const secret :Data = 0x"9f98739c2b53835e 6720a00907abd42f";
{% endhighlight %}
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