Commit b92a28a6 authored by Kenton Varda's avatar Kenton Varda

Compiler nearing completion. Mostly just needs a driver.

parent 34e70d5a
......@@ -23,6 +23,7 @@
#include "lexer.h"
#include "parser.h"
#include "compiler.h"
#include <capnp/pretty-print.h>
#include <kj/vector.h>
#include <kj/io.h>
......@@ -31,8 +32,22 @@
#include "../message.h"
#include <iostream>
class CerrErrorReporter: public capnp::compiler::ErrorReporter {
class DummyModule: public capnp::compiler::Module {
public:
capnp::compiler::ParsedFile::Reader content;
kj::StringPtr getLocalName() const {
return "(stdin)";
}
kj::StringPtr getSourceName() const {
return "(stdin)";
}
capnp::Orphan<capnp::compiler::ParsedFile> loadContent(capnp::Orphanage orphanage) const {
return orphanage.newOrphanCopy(content);
}
kj::Maybe<const Module&> importRelative(kj::StringPtr importPath) const {
return nullptr;
}
void addError(uint32_t startByte, uint32_t endByte, kj::StringPtr message) const override {
std::cerr << "input:" << startByte << "-" << endByte << ": " << message.cStr() << std::endl;
}
......@@ -41,18 +56,23 @@ public:
int main(int argc, char* argv[]) {
// Eventually this will be capnpc. For now it's just a dummy program that tests parsing.
kj::Vector<char> input;
char buffer[4096];
for (;;) {
ssize_t n;
KJ_SYSCALL(n = read(STDIN_FILENO, buffer, sizeof(buffer)));
if (n == 0) {
break;
}
input.addAll(buffer, buffer + n);
}
// kj::Vector<char> input;
// char buffer[4096];
// for (;;) {
// ssize_t n;
// KJ_SYSCALL(n = read(STDIN_FILENO, buffer, sizeof(buffer)));
// if (n == 0) {
// break;
// }
// input.addAll(buffer, buffer + n);
// }
kj::StringPtr input =
"@0x8e001c75f6ff54c8;\n"
"struct Foo { bar @0 :Int32 = 123; baz @1 :Text; }\n"
"struct Qux { foo @0 :List(Int32) = [12, 34]; }";
CerrErrorReporter errorReporter;
DummyModule module;
std::cout << "=========================================================================\n"
<< "lex\n"
......@@ -61,7 +81,7 @@ int main(int argc, char* argv[]) {
capnp::MallocMessageBuilder lexerArena;
auto lexedFile = lexerArena.initRoot<capnp::compiler::LexedStatements>();
capnp::compiler::lex(input, lexedFile, errorReporter);
capnp::compiler::lex(input, lexedFile, module);
std::cout << capnp::prettyPrint(lexedFile).cStr() << std::endl;
std::cout << "=========================================================================\n"
......@@ -71,8 +91,21 @@ int main(int argc, char* argv[]) {
capnp::MallocMessageBuilder parserArena;
auto parsedFile = parserArena.initRoot<capnp::compiler::ParsedFile>();
capnp::compiler::parseFile(lexedFile.getStatements(), parsedFile, errorReporter);
capnp::compiler::parseFile(lexedFile.getStatements(), parsedFile, module);
std::cout << capnp::prettyPrint(parsedFile).cStr() << std::endl;
std::cout << "=========================================================================\n"
<< "compile\n"
<< "========================================================================="
<< std::endl;
module.content = parsedFile.asReader();
capnp::compiler::Compiler compiler;
compiler.add(module, capnp::compiler::Compiler::EAGER);
for (auto schema: compiler.getLoader().getAllLoaded()) {
std::cout << capnp::prettyPrint(schema.getProto()).cStr() << std::endl;
}
return 0;
}
This diff is collapsed.
......@@ -55,7 +55,7 @@ class Compiler {
// Cross-links separate modules (schema files) and translates them into schema nodes.
public:
explicit Compiler();
Compiler();
~Compiler();
KJ_DISALLOW_COPY(Compiler);
......@@ -76,8 +76,11 @@ public:
// use EAGER mode.
};
Schema add(Module& module, Mode mode) const;
// Add a module to the Compiler, returning its root Schema object.
uint64_t add(Module& module, Mode mode) const;
// Add a module to the Compiler, returning the module's file ID. The ID can then be used to
// look up the schema in the SchemaLoader returned by `getLoader()`. However, if there were any
// errors while compiling (reported via `module.addError()`), then the SchemaLoader may behave as
// if the node doesn't exist, or may return an invalid partial Schema.
const SchemaLoader& getLoader() const;
// Get a SchemaLoader backed by this compiler. Schema nodes will be lazily constructed as you
......
This diff is collapsed.
......@@ -54,15 +54,17 @@ public:
// Look up the given name, relative to this node, and return basic information about the
// target.
virtual Schema resolveMaybeBootstrapSchema(uint64_t id) const = 0;
virtual kj::Maybe<Schema> resolveMaybeBootstrapSchema(uint64_t id) const = 0;
// Get the schema for the given ID. Returning either a bootstrap schema or a final schema
// is acceptable. Throws an exception if the id is not one that was found by calling resolve()
// or by traversing other schemas.
// or by traversing other schemas. Returns null if the ID is recognized, but the corresponding
// schema node failed to be built for reasons that were already reported.
virtual Schema resolveFinalSchema(uint64_t id) const = 0;
virtual kj::Maybe<Schema> resolveFinalSchema(uint64_t id) const = 0;
// 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.
// schemas. Returns null if the ID is recognized, but the corresponding schema node failed to
// be built for reasons that were already reported.
};
NodeTranslator(const Resolver& resolver, const ErrorReporter& errorReporter,
......@@ -162,10 +164,12 @@ private:
kj::Maybe<DynamicValue::Reader> readConstant(DeclName::Reader name, bool isBootstrap,
ValueExpression::Reader errorLocation);
// Get the value of the given constant.
// Get the value of the given constant. May return null if some error occurs, which will already
// have been reported.
ListSchema makeListSchemaOf(schema::Type::Reader elementType);
// Construct a list schema representing a list of elements of the given type.
kj::Maybe<ListSchema> makeListSchemaOf(schema::Type::Reader elementType);
// Construct a list schema representing a list of elements of the given type. May return null if
// some error occurs, which will already have been reported.
Orphan<List<schema::Annotation>> compileAnnotationApplications(
List<Declaration::AnnotationApplication>::Reader annotations,
......
......@@ -1585,7 +1585,7 @@ struct WireHelpers {
}
static void adopt(SegmentBuilder* segment, WirePointer* ref, OrphanBuilder&& value) {
KJ_REQUIRE(value.segment->getArena() == segment->getArena(),
KJ_REQUIRE(value.segment == nullptr || value.segment->getArena() == segment->getArena(),
"Adopted object must live in the same message.");
if (!ref->isNull()) {
......
......@@ -733,7 +733,7 @@ public:
KJ_DISALLOW_COPY(Deferred);
// This move constructor is usually optimized away by the compiler.
inline Deferred(Deferred&& other): func(kj::mv(other.func)) {
inline Deferred(Deferred&& other): func(kj::mv(other.func)), canceled(false) {
other.canceled = true;
}
private:
......
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