Commit b92a28a6 authored by Kenton Varda's avatar Kenton Varda

Compiler nearing completion. Mostly just needs a driver.

parent 34e70d5a
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "lexer.h" #include "lexer.h"
#include "parser.h" #include "parser.h"
#include "compiler.h"
#include <capnp/pretty-print.h> #include <capnp/pretty-print.h>
#include <kj/vector.h> #include <kj/vector.h>
#include <kj/io.h> #include <kj/io.h>
...@@ -31,8 +32,22 @@ ...@@ -31,8 +32,22 @@
#include "../message.h" #include "../message.h"
#include <iostream> #include <iostream>
class CerrErrorReporter: public capnp::compiler::ErrorReporter { class DummyModule: public capnp::compiler::Module {
public: 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 { void addError(uint32_t startByte, uint32_t endByte, kj::StringPtr message) const override {
std::cerr << "input:" << startByte << "-" << endByte << ": " << message.cStr() << std::endl; std::cerr << "input:" << startByte << "-" << endByte << ": " << message.cStr() << std::endl;
} }
...@@ -41,18 +56,23 @@ public: ...@@ -41,18 +56,23 @@ public:
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
// Eventually this will be capnpc. For now it's just a dummy program that tests parsing. // Eventually this will be capnpc. For now it's just a dummy program that tests parsing.
kj::Vector<char> input; // kj::Vector<char> input;
char buffer[4096]; // char buffer[4096];
for (;;) { // for (;;) {
ssize_t n; // ssize_t n;
KJ_SYSCALL(n = read(STDIN_FILENO, buffer, sizeof(buffer))); // KJ_SYSCALL(n = read(STDIN_FILENO, buffer, sizeof(buffer)));
if (n == 0) { // if (n == 0) {
break; // break;
} // }
input.addAll(buffer, buffer + n); // 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" std::cout << "=========================================================================\n"
<< "lex\n" << "lex\n"
...@@ -61,7 +81,7 @@ int main(int argc, char* argv[]) { ...@@ -61,7 +81,7 @@ int main(int argc, char* argv[]) {
capnp::MallocMessageBuilder lexerArena; capnp::MallocMessageBuilder lexerArena;
auto lexedFile = lexerArena.initRoot<capnp::compiler::LexedStatements>(); 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 << capnp::prettyPrint(lexedFile).cStr() << std::endl;
std::cout << "=========================================================================\n" std::cout << "=========================================================================\n"
...@@ -71,8 +91,21 @@ int main(int argc, char* argv[]) { ...@@ -71,8 +91,21 @@ int main(int argc, char* argv[]) {
capnp::MallocMessageBuilder parserArena; capnp::MallocMessageBuilder parserArena;
auto parsedFile = parserArena.initRoot<capnp::compiler::ParsedFile>(); 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 << 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; return 0;
} }
This diff is collapsed.
...@@ -55,7 +55,7 @@ class Compiler { ...@@ -55,7 +55,7 @@ class Compiler {
// Cross-links separate modules (schema files) and translates them into schema nodes. // Cross-links separate modules (schema files) and translates them into schema nodes.
public: public:
explicit Compiler(); Compiler();
~Compiler(); ~Compiler();
KJ_DISALLOW_COPY(Compiler); KJ_DISALLOW_COPY(Compiler);
...@@ -76,8 +76,11 @@ public: ...@@ -76,8 +76,11 @@ public:
// use EAGER mode. // use EAGER mode.
}; };
Schema add(Module& module, Mode mode) const; uint64_t add(Module& module, Mode mode) const;
// Add a module to the Compiler, returning its root Schema object. // 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; const SchemaLoader& getLoader() const;
// Get a SchemaLoader backed by this compiler. Schema nodes will be lazily constructed as you // Get a SchemaLoader backed by this compiler. Schema nodes will be lazily constructed as you
......
This diff is collapsed.
...@@ -54,15 +54,17 @@ public: ...@@ -54,15 +54,17 @@ 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 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 // 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() // 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 // 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 // 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, NodeTranslator(const Resolver& resolver, const ErrorReporter& errorReporter,
...@@ -162,10 +164,12 @@ private: ...@@ -162,10 +164,12 @@ private:
kj::Maybe<DynamicValue::Reader> readConstant(DeclName::Reader name, bool isBootstrap, kj::Maybe<DynamicValue::Reader> readConstant(DeclName::Reader name, bool isBootstrap,
ValueExpression::Reader errorLocation); 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); kj::Maybe<ListSchema> makeListSchemaOf(schema::Type::Reader elementType);
// Construct a list schema representing a list of elements of the given type. // 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( Orphan<List<schema::Annotation>> compileAnnotationApplications(
List<Declaration::AnnotationApplication>::Reader annotations, List<Declaration::AnnotationApplication>::Reader annotations,
......
...@@ -1585,7 +1585,7 @@ struct WireHelpers { ...@@ -1585,7 +1585,7 @@ struct WireHelpers {
} }
static void adopt(SegmentBuilder* segment, WirePointer* ref, OrphanBuilder&& value) { 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."); "Adopted object must live in the same message.");
if (!ref->isNull()) { if (!ref->isNull()) {
......
...@@ -733,7 +733,7 @@ public: ...@@ -733,7 +733,7 @@ public:
KJ_DISALLOW_COPY(Deferred); KJ_DISALLOW_COPY(Deferred);
// This move constructor is usually optimized away by the compiler. // 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; other.canceled = true;
} }
private: 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