if(!io)
return 0;
- Parser parser;
- Module *module = new Module(parser.parse(*io, "<builtin>", BUILTIN_SOURCE));
+ RefPtr<Module> module = new Module;
+ Parser parser(0);
+ parser.parse(*module, *io, "<builtin>", BUILTIN_SOURCE);
NodeList<Statement> &shared_body = module->shared.content.body;
NodeList<Statement>::iterator insert_point = shared_body.begin();
for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
populate_types(*i);
- builtins_module = module;
+ builtins_module = module.release();
}
return builtins_module.get();
}
#include "finalize.h"
#include "generate.h"
#include "glsl_error.h"
+#include "modulecache.h"
#include "optimize.h"
#include "output.h"
#include "resolve.h"
-#include "resources.h"
#include "spirv.h"
#include "validate.h"
void Compiler::set_source(const string &source, const string &src_name)
{
clear();
- Parser parser;
imported_names.push_back(src_name);
- append_module(parser.parse(source, src_name, 1), 0);
+ ModuleCache mod_cache(0);
+ append_module(mod_cache.add_module(source, src_name), mod_cache);
}
void Compiler::load_source(IO::Base &io, DataFile::Collection *res, const string &src_name)
{
clear();
- Parser parser;
imported_names.push_back(src_name);
- append_module(parser.parse(io, src_name, 1), res);
+ ModuleCache mod_cache(res);
+ append_module(mod_cache.add_module(io, src_name), mod_cache);
}
void Compiler::load_source(IO::Base &io, const string &src_name)
return combined;
}
-void Compiler::append_module(Module &mod, DataFile::Collection *res)
+void Compiler::append_module(const Module &mod, ModuleCache &mod_cache)
{
module->source_map.merge_from(mod.source_map);
if(Import *imp = dynamic_cast<Import *>(i->get()))
imports.push_back(imp);
for(vector<Import *>::iterator i=imports.begin(); i!=imports.end(); ++i)
- import(res, (*i)->module);
- NodeRemover().apply(mod.shared, set<Node *>(imports.begin(), imports.end()));
+ import(mod_cache, (*i)->module);
append_stage(mod.shared);
- for(list<Stage>::iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i)
+ for(list<Stage>::const_iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i)
append_stage(*i);
}
-void Compiler::append_stage(Stage &stage)
+void Compiler::append_stage(const Stage &stage)
{
Stage *target = 0;
if(stage.type==Stage::SHARED)
if(stage.required_features.glsl_version>target->required_features.glsl_version)
target->required_features.glsl_version = stage.required_features.glsl_version;
- for(NodeList<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
- target->content.body.push_back(*i);
+ for(NodeList<Statement>::const_iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
+ if(!dynamic_cast<Import *>(i->get()))
+ target->content.body.push_back(*i);
}
-void Compiler::import(DataFile::Collection *resources, const string &name)
+void Compiler::import(ModuleCache &mod_cache, const string &name)
{
- string fn = name+".glsl";
- if(find(imported_names, fn)!=imported_names.end())
+ if(find(imported_names, name)!=imported_names.end())
return;
- imported_names.push_back(fn);
+ imported_names.push_back(name);
- RefPtr<IO::Seekable> io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn));
- if(!io)
- throw runtime_error(format("module %s not found", name));
- Parser import_parser;
- append_module(import_parser.parse(*io, fn, module->source_map.get_count()), resources);
+ append_module(mod_cache.get_module(name), mod_cache);
}
void Compiler::generate(Stage &stage)
private:
/** Appends a module to the target, processing any imports found in it. */
- void append_module(Module &, DataFile::Collection *);
+ void append_module(const Module &, ModuleCache &);
/** Appends a single stage to the matching stage of the target. */
- void append_stage(Stage &);
+ void append_stage(const Stage &);
/// Imports a module by name and appends it to the target. */
- void import(DataFile::Collection *, const std::string &);
+ void import(ModuleCache &, const std::string &);
/** Generates any implicitly defines syntactic structures and resolves
variables. */
--- /dev/null
+#include <msp/io/seekable.h>
+#include "modulecache.h"
+#include "parser.h"
+#include "resources.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+ModuleCache::ModuleCache(DataFile::Collection *r):
+ resources(r),
+ next_source(1)
+{ }
+
+ModuleCache::ModuleCache(const ModuleCache &other)
+{
+ for(map<string, Module *>::const_iterator i=other.modules.begin(); i!=other.modules.end(); ++i)
+ modules[i->first] = new Module(*i->second);
+}
+
+ModuleCache &ModuleCache::operator=(const ModuleCache &other)
+{
+ for(map<string, Module *>::iterator i=modules.begin(); i!=modules.end(); ++i)
+ delete i->second;
+ modules.clear();
+ for(map<string, Module *>::const_iterator i=other.modules.begin(); i!=other.modules.end(); ++i)
+ modules[i->first] = new Module(*i->second);
+ return *this;
+}
+
+ModuleCache::~ModuleCache()
+{
+ for(map<string, Module *>::iterator i=modules.begin(); i!=modules.end(); ++i)
+ delete i->second;
+}
+
+const Module &ModuleCache::add_module(const string &source, const string &src_name)
+{
+ RefPtr<Module> module = new Module;
+ Parser parser(this);
+ unsigned src_index = next_source++;
+ parser.parse(*module, source, src_name, src_index);
+ return *(modules[src_name] = module.release());
+}
+
+const Module &ModuleCache::add_module(IO::Base &io, const string &src_name)
+{
+ RefPtr<Module> module = new Module;
+ Parser parser(this);
+ unsigned src_index = next_source++;
+ parser.parse(*module, io, src_name, src_index);
+ return *(modules[src_name] = module.release());
+}
+
+const Module &ModuleCache::get_module(const string &name)
+{
+ string fn = name+".glsl";
+ map<string, Module *>::const_iterator i = modules.find(fn);
+ if(i!=modules.end())
+ return *i->second;
+
+ RefPtr<IO::Seekable> io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn));
+ if(!io)
+ throw runtime_error(format("module %s not found", name));
+
+ return add_module(*io, fn);
+}
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
--- /dev/null
+#ifndef MSP_GL_SL_MODULECACHE_H_
+#define MSP_GL_SL_MODULECACHE_H_
+
+#include <msp/datafile/collection.h>
+#include "syntax.h"
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+class ModuleCache
+{
+private:
+ DataFile::Collection *resources;
+ std::map<std::string, Module *> modules;
+ unsigned next_source;
+
+public:
+ ModuleCache(DataFile::Collection *);
+ ModuleCache(const ModuleCache &);
+ ModuleCache &operator=(const ModuleCache &);
+ ~ModuleCache();
+
+ const Module &add_module(const std::string &, const std::string &);
+ const Module &add_module(IO::Base &, const std::string &);
+ const Module &get_module(const std::string &);
+};
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
+
+#endif
#include <msp/strings/utils.h>
#include "builtin.h"
#include "glsl_error.h"
+#include "modulecache.h"
#include "parser.h"
#undef interface
namespace GL {
namespace SL {
-Parser::Parser():
+Parser::Parser(ModuleCache *s):
+ mod_cache(s),
preprocessor(tokenizer),
module(0)
{
preprocessor.signal_line.connect(sigc::mem_fun(this, &Parser::line_change));
}
-Parser::~Parser()
-{
- delete module;
-}
-
-Module &Parser::parse(const string &s, const string &n, int i)
+void Parser::parse(Module &m, const string &s, const string &n, int i)
{
+ SetForScope<Module *> set_module(module, &m);
source = s;
parse_source(n, i);
- return *module;
}
-Module &Parser::parse(IO::Base &io, const string &n, int i)
+void Parser::parse(Module &m, IO::Base &io, const string &n, int i)
{
+ SetForScope<Module *> set_module(module, &m);
source = string();
while(!io.eof())
{
source.append(buffer, len);
}
parse_source(n, i);
- return *module;
}
void Parser::parse_source(const string &name, int index)
{
- delete module;
- module = new Module;
-
cur_stage = &module->shared;
base_index = index;
source_index = index;
namespace GL {
namespace SL {
+class ModuleCache;
+
class Parser
{
private:
+ ModuleCache *mod_cache;
std::string source;
int base_index;
int source_index;
std::vector<std::string> errors;
public:
- Parser();
- ~Parser();
+ Parser(ModuleCache *);
- Module &parse(const std::string &, const std::string &, int);
- Module &parse(IO::Base &, const std::string &, int);
+ void parse(Module &, const std::string &, const std::string &, int);
+ void parse(Module &, IO::Base &, const std::string &, int);
private:
void parse_source(const std::string &, int);