Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
b0730966
Commit
b0730966
authored
Jul 26, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More compiler WIP
parent
0da57538
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
515 additions
and
57 deletions
+515
-57
compiler.c++
c++/src/capnp/compiler/compiler.c++
+15
-21
grammar.capnp
c++/src/capnp/compiler/grammar.capnp
+2
-6
node-translator.c++
c++/src/capnp/compiler/node-translator.c++
+444
-9
node-translator.h
c++/src/capnp/compiler/node-translator.h
+13
-4
parser.c++
c++/src/capnp/compiler/parser.c++
+30
-9
dynamic.c++
c++/src/capnp/dynamic.c++
+6
-8
schema.capnp
c++/src/capnp/schema.capnp
+5
-0
No files found.
c++/src/capnp/compiler/compiler.c++
View file @
b0730966
...
@@ -89,8 +89,8 @@ public:
...
@@ -89,8 +89,8 @@ public:
// implements NodeTranslator::Resolver -----------------------------
// implements NodeTranslator::Resolver -----------------------------
kj
::
Maybe
<
ResolvedName
>
resolve
(
const
DeclName
::
Reader
&
name
)
const
override
;
kj
::
Maybe
<
ResolvedName
>
resolve
(
const
DeclName
::
Reader
&
name
)
const
override
;
kj
::
Maybe
<
Schema
>
resolveMaybeBootstrapSchema
(
uint64_t
id
)
const
override
;
Schema
resolveMaybeBootstrapSchema
(
uint64_t
id
)
const
override
;
kj
::
Maybe
<
Schema
>
resolveFinalSchema
(
uint64_t
id
)
const
override
;
Schema
resolveFinalSchema
(
uint64_t
id
)
const
override
;
private
:
private
:
const
CompiledModule
*
module
;
// null iff isBuiltin is true
const
CompiledModule
*
module
;
// null iff isBuiltin is true
...
@@ -608,14 +608,20 @@ kj::Maybe<NodeTranslator::Resolver::ResolvedName> Compiler::Node::resolve(
...
@@ -608,14 +608,20 @@ kj::Maybe<NodeTranslator::Resolver::ResolvedName> Compiler::Node::resolve(
});
});
}
}
kj
::
Maybe
<
Schema
>
Compiler
::
Node
::
resolveMaybeBootstrapSchema
(
uint64_t
id
)
const
{
Schema
Compiler
::
Node
::
resolveMaybeBootstrapSchema
(
uint64_t
id
)
const
{
return
module
->
getCompiler
().
findNode
(
id
).
map
(
KJ_IF_MAYBE
(
node
,
module
->
getCompiler
().
findNode
(
id
))
{
[](
const
Node
&
node
)
{
return
node
.
getBootstrapOrFinalSchema
();
});
return
node
->
getBootstrapOrFinalSchema
();
}
else
{
KJ_FAIL_REQUIRE
(
"Tried to get schema for ID we haven't seen before."
);
}
}
}
kj
::
Maybe
<
Schema
>
Compiler
::
Node
::
resolveFinalSchema
(
uint64_t
id
)
const
{
Schema
Compiler
::
Node
::
resolveFinalSchema
(
uint64_t
id
)
const
{
return
module
->
getCompiler
().
findNode
(
id
).
map
(
KJ_IF_MAYBE
(
node
,
module
->
getCompiler
().
findNode
(
id
))
{
[](
const
Node
&
node
)
{
return
node
.
getFinalSchema
();
});
return
node
->
getFinalSchema
();
}
else
{
KJ_FAIL_REQUIRE
(
"Tried to get schema for ID we haven't seen before."
);
}
}
}
// =======================================================================================
// =======================================================================================
...
@@ -644,19 +650,7 @@ Compiler::Impl::Impl(): finalLoader(*this), workspace(nullptr) {
...
@@ -644,19 +650,7 @@ Compiler::Impl::Impl(): finalLoader(*this), workspace(nullptr) {
for
(
auto
member
:
declBodySchema
.
getMembers
())
{
for
(
auto
member
:
declBodySchema
.
getMembers
())
{
auto
name
=
member
.
getProto
().
getName
();
auto
name
=
member
.
getProto
().
getName
();
if
(
name
.
startsWith
(
"builtin"
))
{
if
(
name
.
startsWith
(
"builtin"
))
{
kj
::
StringPtr
symbolName
;
kj
::
StringPtr
symbolName
=
name
.
slice
(
strlen
(
"builtin"
));
if
(
name
.
endsWith
(
"Value"
))
{
// e.g. "builtinTrueValue" -- transform this to "true".
auto
substr
=
name
.
slice
(
strlen
(
"builtin"
),
name
.
size
()
-
strlen
(
"Value"
));
kj
::
ArrayPtr
<
char
>
array
=
nodeArena
.
allocateArray
<
char
>
(
substr
.
size
()
+
1
);
memcpy
(
array
.
begin
(),
substr
.
begin
(),
substr
.
size
());
array
[
substr
.
size
()]
=
'\0'
;
array
[
0
]
+=
'a'
-
'A'
;
symbolName
=
kj
::
StringPtr
(
array
.
begin
(),
array
.
size
()
-
1
);
}
else
{
// e.g. "builtinVoid" -- transform this to "Void".
symbolName
=
name
.
slice
(
strlen
(
"builtin"
));
}
builtinDecls
[
symbolName
]
=
nodeArena
.
allocateOwn
<
Node
>
(
builtinDecls
[
symbolName
]
=
nodeArena
.
allocateOwn
<
Node
>
(
symbolName
,
static_cast
<
Declaration
::
Body
::
Which
>
(
member
.
getIndex
()));
symbolName
,
static_cast
<
Declaration
::
Body
::
Which
>
(
member
.
getIndex
()));
}
}
...
...
c++/src/capnp/compiler/grammar.capnp
View file @
b0730966
...
@@ -95,7 +95,7 @@ struct ValueExpression {
...
@@ -95,7 +95,7 @@ struct ValueExpression {
negativeInt @3 :UInt64;
negativeInt @3 :UInt64;
float @4 :Float64;
float @4 :Float64;
string @5 :Text;
string @5 :Text;
identifier @6 :Text
;
name @6 :DeclName
;
list @7 :List(ValueExpression);
list @7 :List(ValueExpression);
structValue @8 :List(FieldAssignment);
structValue @8 :List(FieldAssignment);
unionValue @9 :FieldAssignment;
unionValue @9 :FieldAssignment;
...
@@ -160,7 +160,7 @@ struct Declaration {
...
@@ -160,7 +160,7 @@ struct Declaration {
# so that the compiler can handle symbol name lookups more uniformly.
# so that the compiler can handle symbol name lookups more uniformly.
#
#
# New union members added here will magically become visible in the global scope.
# New union members added here will magically become visible in the global scope.
#
"builtinFoo" becomes visible as "Foo", while "builtinFooValue" becomes visible as "f
oo".
#
E.g. "builtinFoo" becomes visible as "F
oo".
builtinVoid @25 :Void;
builtinVoid @25 :Void;
builtinBool @26 :Void;
builtinBool @26 :Void;
builtinInt8 @27 :Void;
builtinInt8 @27 :Void;
...
@@ -177,10 +177,6 @@ struct Declaration {
...
@@ -177,10 +177,6 @@ struct Declaration {
builtinData @38 :Void;
builtinData @38 :Void;
builtinList @39 :Void;
builtinList @39 :Void;
builtinObject @40 :Void;
builtinObject @40 :Void;
builtinTrueValue @41 :Void;
builtinFalseValue @42 :Void;
builtinVoidValue @43 :Void;
}
}
struct File {}
struct File {}
...
...
c++/src/capnp/compiler/node-translator.c++
View file @
b0730966
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
#include <kj/arena.h>
#include <kj/arena.h>
#include <set>
#include <set>
#include <map>
#include <map>
#include <limits
.h
>
#include <limits>
namespace
capnp
{
namespace
capnp
{
namespace
compiler
{
namespace
compiler
{
...
@@ -38,7 +38,7 @@ class NodeTranslator::StructLayout {
...
@@ -38,7 +38,7 @@ class NodeTranslator::StructLayout {
public
:
public
:
template
<
typename
UIntType
>
template
<
typename
UIntType
>
struct
HoleSet
{
struct
HoleSet
{
inline
HoleSet
()
{}
inline
HoleSet
()
:
holes
{
0
,
0
,
0
,
0
,
0
,
0
}
{}
// Represents a set of "holes" within a segment of allocated space, up to one hole of each
// Represents a set of "holes" within a segment of allocated space, up to one hole of each
// power-of-two size between 1 bit and 32 bits.
// power-of-two size between 1 bit and 32 bits.
...
@@ -62,7 +62,7 @@ public:
...
@@ -62,7 +62,7 @@ public:
// a series of holes between N and 64 bits, as described in point (1). Thus, again, there
// a series of holes between N and 64 bits, as described in point (1). Thus, again, there
// is still at most one hole of each size, and the largest hole is 32 bits.
// is still at most one hole of each size, and the largest hole is 32 bits.
UIntType
holes
[
6
]
=
{
0
,
0
,
0
,
0
,
0
,
0
}
;
UIntType
holes
[
6
];
// The offset of each hole as a multiple of its size. A value of zero indicates that no hole
// The offset of each hole as a multiple of its size. A value of zero indicates that no hole
// exists. Notice that it is impossible for any actual hole to have an offset of zero, because
// exists. Notice that it is impossible for any actual hole to have an offset of zero, because
// the first field allocated is always placed at the very beginning of the section. So either
// the first field allocated is always placed at the very beginning of the section. So either
...
@@ -138,7 +138,7 @@ public:
...
@@ -138,7 +138,7 @@ public:
}
}
}
}
kj
::
Maybe
<
int
>
smallestAtLeast
(
uint
size
)
{
kj
::
Maybe
<
u
int
>
smallestAtLeast
(
uint
size
)
{
// Return the size of the smallest hole that is equal to or larger than the given size.
// Return the size of the smallest hole that is equal to or larger than the given size.
for
(
uint
i
=
size
;
i
<
KJ_ARRAY_SIZE
(
holes
);
i
++
)
{
for
(
uint
i
=
size
;
i
<
KJ_ARRAY_SIZE
(
holes
);
i
++
)
{
...
@@ -148,6 +148,20 @@ public:
...
@@ -148,6 +148,20 @@ public:
}
}
return
nullptr
;
return
nullptr
;
}
}
uint
getFirstWordUsed
()
{
// Computes the lg of the amount of space used in the first word of the section.
// If there is a 32-bit hole with a 32-bit offset, no more than the first 32 bits are used.
// If no more than the first 32 bits are used, and there is a 16-bit hole with a 16-bit
// offset, then no more than the first 16 bits are used. And so on.
for
(
uint
i
=
KJ_ARRAY_SIZE
(
holes
);
i
>
0
;
i
--
)
{
if
(
holes
[
i
-
1
]
!=
1
)
{
return
i
;
}
}
return
0
;
}
};
};
struct
StructOrGroup
{
struct
StructOrGroup
{
...
@@ -461,7 +475,7 @@ public:
...
@@ -461,7 +475,7 @@ public:
KJ_DISALLOW_COPY
(
Group
);
KJ_DISALLOW_COPY
(
Group
);
uint
addData
(
uint
lgSize
)
override
{
uint
addData
(
uint
lgSize
)
override
{
uint
bestSize
=
UINT_MAX
;
uint
bestSize
=
std
::
numeric_limits
<
uint
>::
max
()
;
kj
::
Maybe
<
uint
>
bestLocation
=
nullptr
;
kj
::
Maybe
<
uint
>
bestLocation
=
nullptr
;
for
(
uint
i
=
0
;
i
<
parent
.
dataLocations
.
size
();
i
++
)
{
for
(
uint
i
=
0
;
i
<
parent
.
dataLocations
.
size
();
i
++
)
{
...
@@ -565,27 +579,35 @@ schema::Node::Reader NodeTranslator::finish() {
...
@@ -565,27 +579,35 @@ schema::Node::Reader NodeTranslator::finish() {
void
NodeTranslator
::
compileNode
(
Declaration
::
Reader
decl
,
schema
::
Node
::
Builder
builder
)
{
void
NodeTranslator
::
compileNode
(
Declaration
::
Reader
decl
,
schema
::
Node
::
Builder
builder
)
{
checkMembers
(
decl
.
getNestedDecls
(),
decl
.
getBody
().
which
());
checkMembers
(
decl
.
getNestedDecls
(),
decl
.
getBody
().
which
());
kj
::
StringPtr
targetsFlagName
;
switch
(
decl
.
getBody
().
which
())
{
switch
(
decl
.
getBody
().
which
())
{
case
Declaration
:
:
Body
::
FILE_DECL
:
case
Declaration
:
:
Body
::
FILE_DECL
:
compileFile
(
decl
,
builder
.
getBody
().
initFileNode
());
compileFile
(
decl
,
builder
.
getBody
().
initFileNode
());
targetsFlagName
=
"targetsFile"
;
break
;
break
;
case
Declaration
:
:
Body
::
CONST_DECL
:
case
Declaration
:
:
Body
::
CONST_DECL
:
compileConst
(
decl
.
getBody
().
getConstDecl
(),
builder
.
getBody
().
initConstNode
());
compileConst
(
decl
.
getBody
().
getConstDecl
(),
builder
.
getBody
().
initConstNode
());
targetsFlagName
=
"targetsConst"
;
break
;
break
;
case
Declaration
:
:
Body
::
ANNOTATION_DECL
:
case
Declaration
:
:
Body
::
ANNOTATION_DECL
:
compileAnnotation
(
decl
.
getBody
().
getAnnotationDecl
(),
builder
.
getBody
().
initAnnotationNode
());
compileAnnotation
(
decl
.
getBody
().
getAnnotationDecl
(),
builder
.
getBody
().
initAnnotationNode
());
targetsFlagName
=
"targetsAnnotation"
;
break
;
break
;
case
Declaration
:
:
Body
::
ENUM_DECL
:
case
Declaration
:
:
Body
::
ENUM_DECL
:
compileEnum
(
decl
.
getBody
().
getEnumDecl
(),
decl
.
getNestedDecls
(),
compileEnum
(
decl
.
getBody
().
getEnumDecl
(),
decl
.
getNestedDecls
(),
builder
.
getBody
().
initEnumNode
());
builder
.
getBody
().
initEnumNode
());
targetsFlagName
=
"targetsEnum"
;
break
;
break
;
case
Declaration
:
:
Body
::
STRUCT_DECL
:
case
Declaration
:
:
Body
::
STRUCT_DECL
:
compileStruct
(
decl
.
getBody
().
getStructDecl
(),
decl
.
getNestedDecls
(),
compileStruct
(
decl
.
getBody
().
getStructDecl
(),
decl
.
getNestedDecls
(),
builder
.
getBody
().
initStructNode
());
builder
.
getBody
().
initStructNode
());
targetsFlagName
=
"targetsStruct"
;
break
;
break
;
case
Declaration
:
:
Body
::
INTERFACE_DECL
:
case
Declaration
:
:
Body
::
INTERFACE_DECL
:
compileInterface
(
decl
.
getBody
().
getInterfaceDecl
(),
decl
.
getNestedDecls
(),
compileInterface
(
decl
.
getBody
().
getInterfaceDecl
(),
decl
.
getNestedDecls
(),
builder
.
getBody
().
initInterfaceNode
());
builder
.
getBody
().
initInterfaceNode
());
targetsFlagName
=
"targetsInterface"
;
break
;
break
;
default
:
default
:
...
@@ -593,7 +615,7 @@ void NodeTranslator::compileNode(Declaration::Reader decl, schema::Node::Builder
...
@@ -593,7 +615,7 @@ void NodeTranslator::compileNode(Declaration::Reader decl, schema::Node::Builder
break
;
break
;
}
}
// TODO(now): annotations
builder
.
adoptAnnotations
(
compileAnnotationApplications
(
decl
.
getAnnotations
(),
targetsFlagName
));
}
}
void
NodeTranslator
::
checkMembers
(
void
NodeTranslator
::
checkMembers
(
...
@@ -927,6 +949,34 @@ public:
...
@@ -927,6 +949,34 @@ public:
KJ_FAIL_ASSERT
(
"addDiscriminant() didn't set the offset?"
);
KJ_FAIL_ASSERT
(
"addDiscriminant() didn't set the offset?"
);
}
}
}
}
// And fill in the sizes.
builder
.
setDataSectionWordSize
(
layout
.
getTop
().
dataWordCount
);
builder
.
setPointerSectionSize
(
layout
.
getTop
().
pointerCount
);
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
INLINE_COMPOSITE
);
if
(
layout
.
getTop
().
pointerCount
==
0
)
{
if
(
layout
.
getTop
().
dataWordCount
==
0
)
{
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
EMPTY
);
}
else
if
(
layout
.
getTop
().
dataWordCount
==
1
)
{
KJ_IF_MAYBE
(
smallestHole
,
layout
.
getTop
().
holes
.
smallestAtLeast
(
0
))
{
}
switch
(
layout
.
getTop
().
holes
.
getFirstWordUsed
())
{
case
0
:
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
BIT
);
break
;
case
1
:
case
2
:
case
3
:
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
BYTE
);
break
;
case
4
:
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
TWO_BYTES
);
break
;
case
5
:
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
FOUR_BYTES
);
break
;
case
6
:
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
EIGHT_BYTES
);
break
;
default:
KJ_FAIL_ASSERT
(
"Expected 0, 1, 2, 3, 4, 5, or 6."
);
break
;
}
}
}
else
if
(
layout
.
getTop
().
pointerCount
==
1
&&
layout
.
getTop
().
dataWordCount
==
0
)
{
builder
.
setPreferredListEncoding
(
schema
::
ElementSize
::
POINTER
);
}
}
}
private
:
private
:
...
@@ -1009,7 +1059,7 @@ private:
...
@@ -1009,7 +1059,7 @@ private:
// Unions that need to have their discriminant offsets filled in after layout is complete.
// Unions that need to have their discriminant offsets filled in after layout is complete.
uint
traverseUnion
(
List
<
Declaration
>::
Reader
members
,
MemberInfo
&
parent
)
{
uint
traverseUnion
(
List
<
Declaration
>::
Reader
members
,
MemberInfo
&
parent
)
{
uint
minOrdinal
=
UINT_MAX
;
uint
minOrdinal
=
std
::
numeric_limits
<
uint
>::
max
()
;
uint
codeOrder
=
0
;
uint
codeOrder
=
0
;
if
(
members
.
size
()
<
2
)
{
if
(
members
.
size
()
<
2
)
{
...
@@ -1057,7 +1107,7 @@ private:
...
@@ -1057,7 +1107,7 @@ private:
}
}
uint
traverseGroup
(
List
<
Declaration
>::
Reader
members
,
MemberInfo
&
parent
)
{
uint
traverseGroup
(
List
<
Declaration
>::
Reader
members
,
MemberInfo
&
parent
)
{
uint
minOrdinal
=
UINT_MAX
;
uint
minOrdinal
=
std
::
numeric_limits
<
uint
>::
max
()
;
uint
codeOrder
=
0
;
uint
codeOrder
=
0
;
if
(
members
.
size
()
<
2
)
{
if
(
members
.
size
()
<
2
)
{
...
@@ -1110,7 +1160,7 @@ private:
...
@@ -1110,7 +1160,7 @@ private:
void
NodeTranslator
::
compileStruct
(
Declaration
::
Struct
::
Reader
decl
,
void
NodeTranslator
::
compileStruct
(
Declaration
::
Struct
::
Reader
decl
,
List
<
Declaration
>::
Reader
members
,
List
<
Declaration
>::
Reader
members
,
schema
::
StructNode
::
Builder
builder
)
{
schema
::
StructNode
::
Builder
builder
)
{
StructTranslator
(
*
this
).
translate
(
decl
,
members
,
builder
);
}
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
...
@@ -1118,13 +1168,354 @@ void NodeTranslator::compileStruct(Declaration::Struct::Reader decl,
...
@@ -1118,13 +1168,354 @@ void NodeTranslator::compileStruct(Declaration::Struct::Reader decl,
void
NodeTranslator
::
compileInterface
(
Declaration
::
Interface
::
Reader
decl
,
void
NodeTranslator
::
compileInterface
(
Declaration
::
Interface
::
Reader
decl
,
List
<
Declaration
>::
Reader
members
,
List
<
Declaration
>::
Reader
members
,
schema
::
InterfaceNode
::
Builder
builder
)
{
schema
::
InterfaceNode
::
Builder
builder
)
{
KJ_FAIL_ASSERT
(
"TODO: compile interfaces"
);
}
// -------------------------------------------------------------------
static
kj
::
String
declNameString
(
DeclName
::
Reader
name
)
{
kj
::
String
prefix
;
switch
(
name
.
getBase
().
which
())
{
case
DeclName
:
:
Base
::
RELATIVE_NAME
:
prefix
=
kj
::
str
(
name
.
getBase
().
getRelativeName
());
break
;
case
DeclName
:
:
Base
::
ABSOLUTE_NAME
:
prefix
=
kj
::
str
(
"."
,
name
.
getBase
().
getAbsoluteName
());
break
;
case
DeclName
:
:
Base
::
IMPORT_NAME
:
prefix
=
kj
::
str
(
"import
\"
"
,
name
.
getBase
().
getImportName
(),
"
\"
"
);
break
;
}
if
(
name
.
getMemberPath
().
size
()
==
0
)
{
return
prefix
;
}
else
{
auto
path
=
name
.
getMemberPath
();
KJ_STACK_ARRAY
(
kj
::
StringPtr
,
parts
,
path
.
size
(),
16
,
16
);
for
(
size_t
i
=
0
;
i
<
parts
.
size
();
i
++
)
{
parts
[
i
]
=
path
[
i
].
getValue
();
}
return
kj
::
str
(
prefix
,
"."
,
kj
::
strArray
(
parts
,
"."
));
}
}
bool
NodeTranslator
::
compileType
(
TypeExpression
::
Reader
source
,
schema
::
Type
::
Builder
target
)
{
auto
name
=
source
.
getName
();
KJ_IF_MAYBE
(
base
,
resolver
.
resolve
(
name
))
{
bool
handledParams
=
false
;
switch
(
base
->
kind
)
{
case
Declaration
:
:
Body
::
ENUM_DECL
:
target
.
getBody
().
setEnumType
(
base
->
id
);
break
;
case
Declaration
:
:
Body
::
STRUCT_DECL
:
target
.
getBody
().
setStructType
(
base
->
id
);
break
;
case
Declaration
:
:
Body
::
INTERFACE_DECL
:
target
.
getBody
().
setInterfaceType
(
base
->
id
);
break
;
case
Declaration
:
:
Body
::
BUILTIN_LIST
:
{
auto
params
=
source
.
getParams
();
if
(
params
.
size
()
!=
1
)
{
errorReporter
.
addErrorOn
(
source
,
"'List' requires exactly one parameter."
);
return
false
;
}
if
(
!
compileType
(
params
[
0
],
target
.
getBody
().
initListType
()))
{
return
false
;
}
handledParams
=
true
;
break
;
}
case
Declaration
:
:
Body
::
BUILTIN_VOID
:
target
.
getBody
().
setVoidType
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_BOOL
:
target
.
getBody
().
setBoolType
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_INT8
:
target
.
getBody
().
setInt8Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_INT16
:
target
.
getBody
().
setInt16Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_INT32
:
target
.
getBody
().
setInt32Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_INT64
:
target
.
getBody
().
setInt64Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_U_INT8
:
target
.
getBody
().
setUint8Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_U_INT16
:
target
.
getBody
().
setUint16Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_U_INT32
:
target
.
getBody
().
setUint32Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_U_INT64
:
target
.
getBody
().
setUint64Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_FLOAT32
:
target
.
getBody
().
setFloat32Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_FLOAT64
:
target
.
getBody
().
setFloat64Type
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_TEXT
:
target
.
getBody
().
setTextType
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_DATA
:
target
.
getBody
().
setDataType
();
break
;
case
Declaration
:
:
Body
::
BUILTIN_OBJECT
:
target
.
getBody
().
setObjectType
();
break
;
default
:
errorReporter
.
addErrorOn
(
source
,
kj
::
str
(
"'"
,
declNameString
(
name
),
"' is not a type."
));
return
false
;
}
if
(
!
handledParams
)
{
if
(
source
.
getParams
().
size
()
!=
0
)
{
errorReporter
.
addErrorOn
(
source
,
kj
::
str
(
"'"
,
declNameString
(
name
),
"' does not accept parameters."
));
}
return
false
;
}
return
true
;
}
else
{
return
false
;
}
}
// -------------------------------------------------------------------
void
NodeTranslator
::
compileDefaultDefaultValue
(
schema
::
Type
::
Reader
type
,
schema
::
Value
::
Builder
target
)
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
target
.
getBody
().
setVoidValue
();
break
;
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
target
.
getBody
().
setBoolValue
(
false
);
break
;
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
target
.
getBody
().
setInt8Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
target
.
getBody
().
setInt16Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
target
.
getBody
().
setInt32Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
target
.
getBody
().
setInt64Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
target
.
getBody
().
setUint8Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
target
.
getBody
().
setUint16Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
target
.
getBody
().
setUint32Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
target
.
getBody
().
setUint64Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
target
.
getBody
().
setFloat32Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
target
.
getBody
().
setFloat64Value
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
target
.
getBody
().
initTextValue
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
target
.
getBody
().
initDataValue
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
target
.
getBody
().
setEnumValue
(
0
);
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
target
.
getBody
().
setInterfaceValue
();
break
;
// Bit of a hack: For "Object" types, we adopt a null orphan, which sets the field to null.
// TODO(cleanup): Create a cleaner way to do this.
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
target
.
getBody
().
adoptStructValue
(
Orphan
<
Data
>
());
break
;
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
target
.
getBody
().
adoptListValue
(
Orphan
<
Data
>
());
break
;
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
target
.
getBody
().
adoptObjectValue
(
Orphan
<
Data
>
());
break
;
}
}
}
void
NodeTranslator
::
compileBootstrapValue
(
ValueExpression
::
Reader
source
,
void
NodeTranslator
::
compileBootstrapValue
(
ValueExpression
::
Reader
source
,
schema
::
Type
::
Reader
type
,
schema
::
Type
::
Reader
type
,
schema
::
Value
::
Builder
target
)
{
schema
::
Value
::
Builder
target
)
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
// Handle later.
unfinishedValues
.
add
(
UnfinishedValue
{
source
,
type
,
target
});
return
;
default
:
break
;
}
switch
(
source
.
getBody
().
which
())
{
case
ValueExpression
:
:
Body
::
NAME
:
{
auto
name
=
source
.
getBody
().
getName
();
bool
isBare
=
name
.
getBase
().
which
()
==
DeclName
::
Base
::
RELATIVE_NAME
&&
name
.
getMemberPath
().
size
()
==
0
;
if
(
isBare
)
{
// The name is just a bare identifier. It may be a literal value or an enumerant.
kj
::
StringPtr
id
=
name
.
getBase
().
getRelativeName
().
getValue
();
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
if
(
id
==
"void"
)
{
target
.
getBody
().
setVoidValue
();
return
;
}
break
;
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
if
(
id
==
"true"
)
{
target
.
getBody
().
setBoolValue
(
true
);
return
;
}
else
if
(
id
==
"false"
)
{
target
.
getBody
().
setBoolValue
(
false
);
return
;
}
break
;
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
if
(
id
==
"nan"
)
{
target
.
getBody
().
setFloat32Value
(
std
::
numeric_limits
<
float
>::
quiet_NaN
());
return
;
}
else
if
(
id
==
"inf"
)
{
target
.
getBody
().
setFloat32Value
(
std
::
numeric_limits
<
float
>::
infinity
());
return
;
}
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
if
(
id
==
"nan"
)
{
target
.
getBody
().
setFloat64Value
(
std
::
numeric_limits
<
double
>::
quiet_NaN
());
return
;
}
else
if
(
id
==
"inf"
)
{
target
.
getBody
().
setFloat64Value
(
std
::
numeric_limits
<
double
>::
infinity
());
return
;
}
break
;
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
KJ_IF_MAYBE
(
enumerant
,
resolver
.
resolveMaybeBootstrapSchema
(
type
.
getBody
().
getEnumType
()).
asEnum
().
findEnumerantByName
(
id
))
{
target
.
getBody
().
setEnumValue
(
enumerant
->
getOrdinal
());
return
;
}
break
;
default
:
break
;
}
}
// Haven't resolved the name yet. Try looking it up.
KJ_IF_MAYBE
(
resolved
,
resolver
.
resolve
(
source
.
getBody
().
getName
()))
{
if
(
resolved
->
kind
!=
Declaration
::
Body
::
CONST_DECL
)
{
errorReporter
.
addErrorOn
(
source
,
kj
::
str
(
"'"
,
declNameString
(
name
),
"' does not refer to a constant."
));
compileDefaultDefaultValue
(
type
,
target
);
break
;
}
// We can get the bootstrap version of the constant here because if it has a
// non-bootstrap-time value then it's an error anyway.
Schema
constSchema
=
resolver
.
resolveMaybeBootstrapSchema
(
resolved
->
id
);
auto
constReader
=
constSchema
.
getProto
().
getBody
().
getConstNode
();
copyValue
(
constReader
.
getValue
(),
constReader
.
getType
(),
target
,
type
,
source
);
if
(
isBare
)
{
// A fully unqualified identifier looks like it might refer to a constant visible in the
// current scope, but if that's really what the user wanted, we want them to use a
// qualified name to make it more obvious. Report an error.
Schema
scope
=
resolver
.
resolveMaybeBootstrapSchema
(
constSchema
.
getProto
().
getScopeId
());
auto
scopeReader
=
scope
.
getProto
();
kj
::
StringPtr
parent
;
if
(
scopeReader
.
getBody
().
which
()
==
schema
::
Node
::
Body
::
FILE_NODE
)
{
parent
=
""
;
}
else
{
parent
=
scopeReader
.
getDisplayName
().
slice
(
scopeReader
.
getDisplayNamePrefixLength
());
}
kj
::
StringPtr
id
=
name
.
getBase
().
getRelativeName
().
getValue
();
errorReporter
.
addErrorOn
(
source
,
kj
::
str
(
"Constant names must be qualified to avoid confusion. Please replace '"
,
declNameString
(
name
),
"' with '"
,
parent
,
"."
,
id
,
"', if that's what you intended."
));
}
}
break
;
}
case
ValueExpression
:
:
Body
::
POSITIVE_INT
:
{
uint64_t
value
=
source
.
getBody
().
getPositiveInt
();
uint64_t
limit
=
std
::
numeric_limits
<
uint64_t
>::
max
();
switch
(
type
.
getBody
().
which
())
{
#define HANDLE_TYPE(discrim, name, type) \
case schema::Type::Body::discrim##_TYPE: \
limit = std::numeric_limits<type>::max(); \
target.getBody().set##name##Value(value); \
break;
HANDLE_TYPE
(
INT8
,
Int8
,
int8_t
);
HANDLE_TYPE
(
INT16
,
Int16
,
int16_t
);
HANDLE_TYPE
(
INT32
,
Int32
,
int32_t
);
HANDLE_TYPE
(
INT64
,
Int64
,
int64_t
);
HANDLE_TYPE
(
UINT8
,
Uint8
,
uint8_t
);
HANDLE_TYPE
(
UINT16
,
Uint16
,
uint16_t
);
HANDLE_TYPE
(
UINT32
,
Uint32
,
uint32_t
);
HANDLE_TYPE
(
UINT64
,
Uint64
,
uint64_t
);
#undef HANDLE_TYPE
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
target
.
getBody
().
setFloat32Value
(
value
);
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
target
.
getBody
().
setFloat64Value
(
value
);
break
;
default
:
errorReporter
.
addErrorOn
(
source
,
"Type/value mismatch."
);
compileDefaultDefaultValue
(
type
,
target
);
break
;
}
if
(
value
>
limit
)
{
errorReporter
.
addErrorOn
(
source
,
"Value out-of-range for type."
);
}
break
;
}
case
ValueExpression
:
:
Body
::
NEGATIVE_INT
:
{
uint64_t
value
=
source
.
getBody
().
getNegativeInt
();
uint64_t
limit
=
std
::
numeric_limits
<
uint64_t
>::
max
();
switch
(
type
.
getBody
().
which
())
{
#define HANDLE_TYPE(discrim, name, type) \
case schema::Type::Body::discrim##_TYPE: \
limit = kj::implicitCast<uint64_t>(std::numeric_limits<type>::max()) + 1; \
target.getBody().set##name##Value(-value); \
break;
HANDLE_TYPE
(
INT8
,
Int8
,
int8_t
);
HANDLE_TYPE
(
INT16
,
Int16
,
int16_t
);
HANDLE_TYPE
(
INT32
,
Int32
,
int32_t
);
HANDLE_TYPE
(
INT64
,
Int64
,
int64_t
);
#undef HANDLE_TYPE
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
target
.
getBody
().
setFloat32Value
(
-
kj
::
implicitCast
<
float
>
(
value
));
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
target
.
getBody
().
setFloat64Value
(
-
kj
::
implicitCast
<
double
>
(
value
));
break
;
default
:
errorReporter
.
addErrorOn
(
source
,
"Type/value mismatch."
);
compileDefaultDefaultValue
(
type
,
target
);
break
;
}
if
(
value
>
limit
)
{
errorReporter
.
addErrorOn
(
source
,
"Value out-of-range for type."
);
}
break
;
}
case
ValueExpression
:
:
Body
::
FLOAT
:
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
target
.
getBody
().
setFloat32Value
(
source
.
getBody
().
getFloat
());
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
target
.
getBody
().
setFloat64Value
(
source
.
getBody
().
getFloat
());
break
;
default
:
errorReporter
.
addErrorOn
(
source
,
"Type/value mismatch."
);
compileDefaultDefaultValue
(
type
,
target
);
break
;
}
break
;
}
case
ValueExpression
:
:
Body
::
STRING
:
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
target
.
getBody
().
setTextValue
(
source
.
getBody
().
getString
());
break
;
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
{
auto
str
=
source
.
getBody
().
getString
();
target
.
getBody
().
setDataValue
(
kj
::
arrayPtr
(
reinterpret_cast
<
const
byte
*>
(
str
.
begin
()),
str
.
size
()));
break
;
}
default
:
errorReporter
.
addErrorOn
(
source
,
"Type/value mismatch."
);
compileDefaultDefaultValue
(
type
,
target
);
break
;
}
}
case
ValueExpression
:
:
Body
::
LIST
:
case
ValueExpression
:
:
Body
::
STRUCT_VALUE
:
case
ValueExpression
:
:
Body
::
UNION_VALUE
:
// If the type matched, these cases should have been handled earlier.
errorReporter
.
addErrorOn
(
source
,
"Type/value mismatch."
);
compileDefaultDefaultValue
(
type
,
target
);
break
;
case
ValueExpression
:
:
Body
::
UNKNOWN
:
// Ignore earlier error.
compileDefaultDefaultValue
(
type
,
target
);
break
;
}
}
}
void
NodeTranslator
::
compileFinalValue
(
ValueExpression
::
Reader
source
,
void
NodeTranslator
::
compileFinalValue
(
ValueExpression
::
Reader
source
,
...
@@ -1132,6 +1523,50 @@ void NodeTranslator::compileFinalValue(ValueExpression::Reader source,
...
@@ -1132,6 +1523,50 @@ void NodeTranslator::compileFinalValue(ValueExpression::Reader source,
}
}
void
NodeTranslator
::
copyValue
(
schema
::
Value
::
Reader
src
,
schema
::
Type
::
Reader
srcType
,
schema
::
Value
::
Builder
dst
,
schema
::
Type
::
Reader
dstType
,
ValueExpression
::
Reader
errorLocation
)
{
DynamicUnion
::
Reader
srcBody
=
DynamicStruct
::
Reader
(
src
).
get
(
"body"
).
as
<
DynamicUnion
>
();
DynamicUnion
::
Builder
dstBody
=
DynamicStruct
::
Builder
(
dst
).
get
(
"body"
).
as
<
DynamicUnion
>
();
kj
::
StringPtr
dstFieldName
;
switch
(
dstType
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
dstFieldName
=
"voidValue"
;
break
;
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
dstFieldName
=
"boolValue"
;
break
;
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
dstFieldName
=
"int8Value"
;
break
;
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
dstFieldName
=
"int16Value"
;
break
;
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
dstFieldName
=
"int32Value"
;
break
;
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
dstFieldName
=
"int64Value"
;
break
;
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
dstFieldName
=
"uint8Value"
;
break
;
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
dstFieldName
=
"uint16Value"
;
break
;
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
dstFieldName
=
"uint32Value"
;
break
;
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
dstFieldName
=
"uint64Value"
;
break
;
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
dstFieldName
=
"float32Value"
;
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
dstFieldName
=
"float64Value"
;
break
;
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
dstFieldName
=
"textValue"
;
break
;
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
dstFieldName
=
"dataValue"
;
break
;
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
dstFieldName
=
"listValue"
;
break
;
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
dstFieldName
=
"enumValue"
;
break
;
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
dstFieldName
=
"structValue"
;
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
dstFieldName
=
"interfaceValue"
;
break
;
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
dstFieldName
=
"objectValue"
;
break
;
}
KJ_IF_MAYBE
(
which
,
srcBody
.
which
())
{
// Setting a value via the dynamic API implements the implicit conversions that we want, with
// bounds checking that we want. It throws an exception on failure, but that exception is a
// recoverable one, so even if exceptions are disabled, we should be able to catch it. So,
// let's do that rather than try to re-implement all that logic here.
KJ_IF_MAYBE
(
exception
,
kj
::
runCatchingExceptions
(
[
&
]()
{
dstBody
.
set
(
dstFieldName
,
srcBody
.
get
());
}))
{
// Exception caught, therefore the types are not compatible.
errorReporter
.
addErrorOn
(
errorLocation
,
exception
->
getDescription
());
}
}
else
{
KJ_FAIL_ASSERT
(
"Didn't recognize schema::Value::Body type?"
);
}
}
Orphan
<
List
<
schema
::
Annotation
>>
NodeTranslator
::
compileAnnotationApplications
(
Orphan
<
List
<
schema
::
Annotation
>>
NodeTranslator
::
compileAnnotationApplications
(
List
<
Declaration
::
AnnotationApplication
>::
Reader
annotations
,
List
<
Declaration
::
AnnotationApplication
>::
Reader
annotations
,
kj
::
StringPtr
targetsFlagName
)
{
kj
::
StringPtr
targetsFlagName
)
{
...
...
c++/src/capnp/compiler/node-translator.h
View file @
b0730966
...
@@ -54,12 +54,15 @@ public:
...
@@ -54,12 +54,15 @@ public:
// Look up the given name, relative to this node, and return basic information about the
// Look up the given name, relative to this node, and return basic information about the
// target.
// target.
virtual
kj
::
Maybe
<
Schema
>
resolveMaybeBootstrapSchema
(
uint64_t
id
)
const
=
0
;
virtual
Schema
resolveMaybeBootstrapSchema
(
uint64_t
id
)
const
=
0
;
// Get the schema for the given ID. Returning either a bootstrap schema or a final schema
// Get the schema for the given ID. Returning either a bootstrap schema or a final schema
// is acceptable.
// is acceptable. Throws an exception if the id is not one that was found by calling resolve()
// or by traversing other schemas.
virtual
kj
::
Maybe
<
Schema
>
resolveFinalSchema
(
uint64_t
id
)
const
=
0
;
virtual
Schema
resolveFinalSchema
(
uint64_t
id
)
const
=
0
;
// Get the final schema for the given ID. A bootstrap schema is not acceptable.
// Get the final schema for the given ID. A bootstrap schema is not acceptable. Throws an
// exception if the id is not one that was found by calling resolve() or by traversing other
// schemas.
};
};
NodeTranslator
(
const
Resolver
&
resolver
,
const
ErrorReporter
&
errorReporter
,
NodeTranslator
(
const
Resolver
&
resolver
,
const
ErrorReporter
&
errorReporter
,
...
@@ -143,6 +146,12 @@ private:
...
@@ -143,6 +146,12 @@ private:
schema
::
Type
::
Reader
type
,
schema
::
Value
::
Builder
target
);
schema
::
Type
::
Reader
type
,
schema
::
Value
::
Builder
target
);
// Compile a previously-unfinished value. See `unfinishedValues`.
// Compile a previously-unfinished value. See `unfinishedValues`.
void
copyValue
(
schema
::
Value
::
Reader
src
,
schema
::
Type
::
Reader
srcType
,
schema
::
Value
::
Builder
dst
,
schema
::
Type
::
Reader
dstType
,
ValueExpression
::
Reader
errorLocation
);
// Copy a value from one schema to another, possibly coercing the type if compatible, or
// reporting an error otherwise.
Orphan
<
List
<
schema
::
Annotation
>>
compileAnnotationApplications
(
Orphan
<
List
<
schema
::
Annotation
>>
compileAnnotationApplications
(
List
<
Declaration
::
AnnotationApplication
>::
Reader
annotations
,
List
<
Declaration
::
AnnotationApplication
>::
Reader
annotations
,
kj
::
StringPtr
targetsFlagName
);
kj
::
StringPtr
targetsFlagName
);
...
...
c++/src/capnp/compiler/parser.c++
View file @
b0730966
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fcntl.h>
#include <limits>
namespace
capnp
{
namespace
capnp
{
namespace
compiler
{
namespace
compiler
{
...
@@ -299,6 +300,15 @@ inline Declaration::Builder initMemberDecl(
...
@@ -299,6 +300,15 @@ inline Declaration::Builder initMemberDecl(
return
builder
;
return
builder
;
}
}
template
<
typename
BuilderType
>
void
initLocation
(
kj
::
parse
::
Span
<
List
<
Token
>::
Reader
::
Iterator
>
location
,
BuilderType
builder
)
{
if
(
location
.
begin
()
<
location
.
end
())
{
builder
.
setStartByte
(
location
.
begin
()
->
getStartByte
());
builder
.
setEndByte
((
location
.
end
()
-
1
)
->
getEndByte
());
}
}
}
// namespace
}
// namespace
// =======================================================================================
// =======================================================================================
...
@@ -336,10 +346,11 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
...
@@ -336,10 +346,11 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
return
kj
::
mv
(
result
);
return
kj
::
mv
(
result
);
}));
}));
parsers
.
typeExpression
=
arena
.
copy
(
p
::
transform
(
parsers
.
typeExpression
=
arena
.
copy
(
p
::
transform
WithLocation
(
p
::
sequence
(
parsers
.
declName
,
p
::
optional
(
p
::
sequence
(
parsers
.
declName
,
p
::
optional
(
parenthesizedList
(
parsers
.
typeExpression
,
errorReporter
))),
parenthesizedList
(
parsers
.
typeExpression
,
errorReporter
))),
[
this
](
Orphan
<
DeclName
>&&
name
,
[
this
](
kj
::
parse
::
Span
<
List
<
Token
>::
Reader
::
Iterator
>
location
,
Orphan
<
DeclName
>&&
name
,
kj
::
Maybe
<
Located
<
kj
::
Array
<
kj
::
Maybe
<
Orphan
<
TypeExpression
>>>>>&&
params
)
kj
::
Maybe
<
Located
<
kj
::
Array
<
kj
::
Maybe
<
Orphan
<
TypeExpression
>>>>>&&
params
)
->
Orphan
<
TypeExpression
>
{
->
Orphan
<
TypeExpression
>
{
auto
result
=
orphanage
.
newOrphan
<
TypeExpression
>
();
auto
result
=
orphanage
.
newOrphan
<
TypeExpression
>
();
...
@@ -356,6 +367,7 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
...
@@ -356,6 +367,7 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
}
}
}
}
}
}
initLocation
(
location
,
builder
);
return
result
;
return
result
;
}));
}));
...
@@ -451,6 +463,15 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
...
@@ -451,6 +463,15 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
value
.
copyLocationTo
(
builder
);
value
.
copyLocationTo
(
builder
);
return
result
;
return
result
;
}),
}),
p
::
transformWithLocation
(
p
::
sequence
(
op
(
"-"
),
keyword
(
"inf"
)),
[
this
](
kj
::
parse
::
Span
<
List
<
Token
>::
Reader
::
Iterator
>
location
)
->
Orphan
<
ValueExpression
>
{
auto
result
=
orphanage
.
newOrphan
<
ValueExpression
>
();
auto
builder
=
result
.
get
();
builder
.
getBody
().
setFloat
(
-
std
::
numeric_limits
<
double
>::
infinity
());
initLocation
(
location
,
builder
);
return
result
;
}),
p
::
transform
(
stringLiteral
,
p
::
transform
(
stringLiteral
,
[
this
](
Located
<
Text
::
Reader
>&&
value
)
->
Orphan
<
ValueExpression
>
{
[
this
](
Located
<
Text
::
Reader
>&&
value
)
->
Orphan
<
ValueExpression
>
{
auto
result
=
orphanage
.
newOrphan
<
ValueExpression
>
();
auto
result
=
orphanage
.
newOrphan
<
ValueExpression
>
();
...
@@ -474,12 +495,13 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
...
@@ -474,12 +495,13 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
return
result
;
return
result
;
}),
}),
p
::
transform
(
identifier
,
p
::
transformWithLocation
(
parsers
.
declName
,
[
this
](
Located
<
Text
::
Reader
>&&
value
)
->
Orphan
<
ValueExpression
>
{
[
this
](
kj
::
parse
::
Span
<
List
<
Token
>::
Reader
::
Iterator
>
location
,
Orphan
<
DeclName
>&&
value
)
->
Orphan
<
ValueExpression
>
{
auto
result
=
orphanage
.
newOrphan
<
ValueExpression
>
();
auto
result
=
orphanage
.
newOrphan
<
ValueExpression
>
();
auto
builder
=
result
.
get
();
auto
builder
=
result
.
get
();
builder
.
getBody
().
setIdentifier
(
value
.
value
);
builder
.
getBody
().
adoptName
(
kj
::
mv
(
value
)
);
value
.
copyLocationTo
(
builder
);
initLocation
(
location
,
builder
);
return
result
;
return
result
;
}),
}),
p
::
transform
(
bracketedList
(
parsers
.
valueExpression
,
errorReporter
),
p
::
transform
(
bracketedList
(
parsers
.
valueExpression
,
errorReporter
),
...
@@ -518,10 +540,9 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
...
@@ -518,10 +540,9 @@ CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterP
})
})
));
));
parsers
.
annotation
=
arena
.
copy
(
p
::
transform
WithLocation
(
parsers
.
annotation
=
arena
.
copy
(
p
::
transform
(
p
::
sequence
(
op
(
"$"
),
parsers
.
declName
,
p
::
optional
(
parsers
.
parenthesizedValueExpression
)),
p
::
sequence
(
op
(
"$"
),
parsers
.
declName
,
p
::
optional
(
parsers
.
parenthesizedValueExpression
)),
[
this
](
kj
::
parse
::
Span
<
List
<
Token
>::
Reader
::
Iterator
>
location
,
[
this
](
Orphan
<
DeclName
>&&
name
,
kj
::
Maybe
<
Orphan
<
ValueExpression
>>&&
value
)
Orphan
<
DeclName
>&&
name
,
kj
::
Maybe
<
Orphan
<
ValueExpression
>>&&
value
)
->
Orphan
<
Declaration
::
AnnotationApplication
>
{
->
Orphan
<
Declaration
::
AnnotationApplication
>
{
auto
result
=
orphanage
.
newOrphan
<
Declaration
::
AnnotationApplication
>
();
auto
result
=
orphanage
.
newOrphan
<
Declaration
::
AnnotationApplication
>
();
auto
builder
=
result
.
get
();
auto
builder
=
result
.
get
();
...
...
c++/src/capnp/dynamic.c++
View file @
b0730966
...
@@ -1408,7 +1408,7 @@ typeName DynamicValue::Reader::AsImpl<typeName>::apply(const Reader& reader) { \
...
@@ -1408,7 +1408,7 @@ typeName DynamicValue::Reader::AsImpl<typeName>::apply(const Reader& reader) { \
case FLOAT: \
case FLOAT: \
return ifFloat<typeName>(reader.floatValue); \
return ifFloat<typeName>(reader.floatValue); \
default: \
default: \
KJ_FAIL_REQUIRE("
Type mismatch when using DynamicValue::Reader::as()
.") { \
KJ_FAIL_REQUIRE("
Value type mismatch
.") { \
return 0; \
return 0; \
} \
} \
} \
} \
...
@@ -1422,7 +1422,7 @@ typeName DynamicValue::Builder::AsImpl<typeName>::apply(Builder& builder) { \
...
@@ -1422,7 +1422,7 @@ typeName DynamicValue::Builder::AsImpl<typeName>::apply(Builder& builder) { \
case FLOAT: \
case FLOAT: \
return ifFloat<typeName>(builder.floatValue); \
return ifFloat<typeName>(builder.floatValue); \
default: \
default: \
KJ_FAIL_REQUIRE("
Type mismatch when using DynamicValue::Builder::as()
.") { \
KJ_FAIL_REQUIRE("
Value type mismatch
.") { \
return 0; \
return 0; \
} \
} \
} \
} \
...
@@ -1443,15 +1443,13 @@ HANDLE_NUMERIC_TYPE(double, kj::implicitCast, kj::implicitCast, kj::implicitCast
...
@@ -1443,15 +1443,13 @@ HANDLE_NUMERIC_TYPE(double, kj::implicitCast, kj::implicitCast, kj::implicitCast
#define HANDLE_TYPE(name, discrim, typeName) \
#define HANDLE_TYPE(name, discrim, typeName) \
ReaderFor<typeName> DynamicValue::Reader::AsImpl<typeName>::apply(const Reader& reader) { \
ReaderFor<typeName> DynamicValue::Reader::AsImpl<typeName>::apply(const Reader& reader) { \
KJ_REQUIRE(reader.type == discrim, \
KJ_REQUIRE(reader.type == discrim, "Value type mismatch.") { \
"Type mismatch when using DynamicValue::Reader::as().") { \
return ReaderFor<typeName>(); \
return ReaderFor<typeName>(); \
} \
} \
return reader.name##Value; \
return reader.name##Value; \
} \
} \
BuilderFor<typeName> DynamicValue::Builder::AsImpl<typeName>::apply(Builder& builder) { \
BuilderFor<typeName> DynamicValue::Builder::AsImpl<typeName>::apply(Builder& builder) { \
KJ_REQUIRE(builder.type == discrim, \
KJ_REQUIRE(builder.type == discrim, "Value type mismatch.") { \
"Type mismatch when using DynamicValue::Builder::as().") { \
return BuilderFor<typeName>(); \
return BuilderFor<typeName>(); \
} \
} \
return builder.name##Value; \
return builder.name##Value; \
...
@@ -1472,13 +1470,13 @@ HANDLE_TYPE(union, UNION, DynamicUnion)
...
@@ -1472,13 +1470,13 @@ HANDLE_TYPE(union, UNION, DynamicUnion)
// As in the header, HANDLE_TYPE(void, VOID, Void) crashes GCC 4.7.
// As in the header, HANDLE_TYPE(void, VOID, Void) crashes GCC 4.7.
Void
DynamicValue
::
Reader
::
AsImpl
<
Void
>::
apply
(
const
Reader
&
reader
)
{
Void
DynamicValue
::
Reader
::
AsImpl
<
Void
>::
apply
(
const
Reader
&
reader
)
{
KJ_REQUIRE
(
reader
.
type
==
VOID
,
"
Type mismatch when using DynamicValue::Reader::as()
."
)
{
KJ_REQUIRE
(
reader
.
type
==
VOID
,
"
Value type mismatch
."
)
{
return
Void
();
return
Void
();
}
}
return
reader
.
voidValue
;
return
reader
.
voidValue
;
}
}
Void
DynamicValue
::
Builder
::
AsImpl
<
Void
>::
apply
(
Builder
&
builder
)
{
Void
DynamicValue
::
Builder
::
AsImpl
<
Void
>::
apply
(
Builder
&
builder
)
{
KJ_REQUIRE
(
builder
.
type
==
VOID
,
"
Type mismatch when using DynamicValue::Builder::as()
."
)
{
KJ_REQUIRE
(
builder
.
type
==
VOID
,
"
Value type mismatch
."
)
{
return
Void
();
return
Void
();
}
}
return
builder
.
voidValue
;
return
builder
.
voidValue
;
...
...
c++/src/capnp/schema.capnp
View file @
b0730966
...
@@ -40,6 +40,10 @@ struct Node {
...
@@ -40,6 +40,10 @@ struct Node {
#
#
# (On Zooko's triangle, this is the node's nickname.)
# (On Zooko's triangle, this is the node's nickname.)
displayNamePrefixLength @12 :UInt32;
# If you want a shorter version of `displayName` (just naming this node, without its surrounding
# scope), chop off this many characters from the beginning of `displayName`.
scopeId @2 :Id = 0;
scopeId @2 :Id = 0;
# ID of the lexical parent node. Typically, the scope node will have a NestedNode pointing back
# ID of the lexical parent node. Typically, the scope node will have a NestedNode pointing back
# at this node, but robust code should avoid relying on this. `scopeId` is zero if the node has
# at this node, but robust code should avoid relying on this. `scopeId` is zero if the node has
...
@@ -109,6 +113,7 @@ struct Value {
...
@@ -109,6 +113,7 @@ struct Value {
body @0 union {
body @0 union {
# Note ordinals 1 and 10 are intentionally swapped to improve union layout.
# Note ordinals 1 and 10 are intentionally swapped to improve union layout.
# TODO: Make it 2 and 10 that are swapped instead so that voidValue is still default?
voidValue @10 :Void;
voidValue @10 :Void;
boolValue @2 :Bool;
boolValue @2 :Bool;
int8Value @3 :Int8;
int8Value @3 :Int8;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment