106 lines
3.3 KiB
C++
106 lines
3.3 KiB
C++
|
/*
|
||
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||
|
|
||
|
Author: Leonardo de Moura
|
||
|
*/
|
||
|
#include <unordered_map>
|
||
|
#include <utility>
|
||
|
#include <string>
|
||
|
#include "util/hash.h"
|
||
|
#include "library/module.h"
|
||
|
#include "library/kernel_serializer.h"
|
||
|
|
||
|
namespace lean {
|
||
|
typedef std::pair<std::string, std::function<void(serializer &)>> writer;
|
||
|
typedef std::pair<std::string, unsigned> import_info; // imported module and its hashcode
|
||
|
|
||
|
struct module_ext : public environment_extension {
|
||
|
list<import_info> m_direct_imports;
|
||
|
list<writer> m_writers;
|
||
|
};
|
||
|
|
||
|
struct module_ext_reg {
|
||
|
unsigned m_ext_id;
|
||
|
module_ext_reg() { m_ext_id = environment::register_extension(std::make_shared<module_ext>()); }
|
||
|
};
|
||
|
|
||
|
static module_ext_reg g_ext;
|
||
|
static module_ext const & get_extension(environment const & env) {
|
||
|
return static_cast<module_ext const &>(env.get_extension(g_ext.m_ext_id));
|
||
|
}
|
||
|
static environment update(environment const & env, module_ext const & ext) {
|
||
|
return env.update(g_ext.m_ext_id, std::make_shared<module_ext>(ext));
|
||
|
}
|
||
|
|
||
|
void export_module(std::ostream & out, environment const & env) {
|
||
|
module_ext const & ext = get_extension(env);
|
||
|
buffer<import_info> imports;
|
||
|
buffer<writer const *> writers;
|
||
|
to_buffer(ext.m_direct_imports, imports);
|
||
|
std::reverse(imports.begin(), imports.end());
|
||
|
for (writer const & w : ext.m_writers)
|
||
|
writers.push_back(&w);
|
||
|
std::reverse(writers.begin(), writers.end());
|
||
|
|
||
|
std::string r;
|
||
|
std::ostringstream out1(r);
|
||
|
serializer s1(out1);
|
||
|
|
||
|
// store imported files
|
||
|
s1 << imports.size();
|
||
|
for (auto p : imports)
|
||
|
s1 << p.first << p.second;
|
||
|
|
||
|
// store objects
|
||
|
for (auto p : writers) {
|
||
|
s1 << p->first;
|
||
|
p->second(s1);
|
||
|
}
|
||
|
|
||
|
serializer s2(out);
|
||
|
unsigned h = hash_str(r.size(), r.c_str(), 13);
|
||
|
s2 << h;
|
||
|
for (unsigned i = 0; i < r.size(); i++)
|
||
|
s2.write_char(r[i]);
|
||
|
}
|
||
|
|
||
|
typedef std::unordered_map<std::string, module_object_reader> object_readers;
|
||
|
static std::unique_ptr<object_readers> g_object_readers;
|
||
|
static object_readers & get_object_readers() {
|
||
|
if (!g_object_readers)
|
||
|
g_object_readers.reset(new object_readers());
|
||
|
return *(g_object_readers.get());
|
||
|
}
|
||
|
|
||
|
void register_module_object_reader(std::string const & k, module_object_reader r) {
|
||
|
object_readers & readers = get_object_readers();
|
||
|
lean_assert(readers.find(k) == readers.end());
|
||
|
readers[k] = r;
|
||
|
}
|
||
|
|
||
|
environment add(environment const & env, std::string const & k, std::function<void(serializer &)> const & wr) {
|
||
|
module_ext ext = get_extension(env);
|
||
|
ext.m_writers = list<writer>(writer(k, wr), ext.m_writers);
|
||
|
return update(env, ext);
|
||
|
}
|
||
|
|
||
|
static std::string g_decl("decl");
|
||
|
|
||
|
environment add(environment const & env, certified_declaration const & d) {
|
||
|
environment new_env = env.add(d);
|
||
|
new_env = add(new_env, g_decl, [=](serializer & s) { s << d.get_declaration(); });
|
||
|
return new_env;
|
||
|
}
|
||
|
|
||
|
environment import_modules(environment const & env, unsigned num_modules, std::string const * modules) {
|
||
|
// TODO(Leo)
|
||
|
for (unsigned i = 0; i < num_modules; i++) std::cout << modules[i];
|
||
|
return env;
|
||
|
}
|
||
|
|
||
|
environment import_module(environment const & env, std::string const & module) {
|
||
|
return import_modules(env, 1, &module);
|
||
|
}
|
||
|
}
|