X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fprogramcompiler.h;h=96fee471cc7e5351a59e7d51f9b3772862bcc195;hb=acec85413f86c58ff262fbc26c2c1aa8726b5c58;hp=63ead7a4c8997f0a6f3bd4d76f8bee10da2a9958;hpb=70f9fe2964700fc199ab3cabb26f9b14d078c56b;p=libs%2Fgl.git diff --git a/source/programcompiler.h b/source/programcompiler.h index 63ead7a4..96fee471 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -1,6 +1,7 @@ #ifndef MSP_GL_PROGRAMCOMPILER_H_ #define MSP_GL_PROGRAMCOMPILER_H_ +#include #include "programparser.h" #include "programsyntax.h" @@ -8,19 +9,36 @@ namespace Msp { namespace GL { class Program; +class Resources; class ProgramCompiler { -public: - struct Formatter: ProgramSyntax::NodeVisitor +private: + struct Visitor: ProgramSyntax::TraversingVisitor + { + typedef void ResultType; + + ProgramSyntax::Stage *stage; + + Visitor(); + + virtual void apply(ProgramSyntax::Stage &); + void get_result() const { } + }; + + struct Formatter: Visitor { + typedef std::string ResultType; + std::string formatted; unsigned indent; bool parameter_list; - bool else_if; + unsigned else_if; + std::string block_interface; Formatter(); + const std::string &get_result() const { return formatted; } virtual void visit(ProgramSyntax::Block &); virtual void visit(ProgramSyntax::Literal &); virtual void visit(ProgramSyntax::ParenthesizedExpression &); @@ -28,8 +46,10 @@ public: virtual void visit(ProgramSyntax::MemberAccess &); virtual void visit(ProgramSyntax::UnaryExpression &); virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::Assignment &); virtual void visit(ProgramSyntax::FunctionCall &); virtual void visit(ProgramSyntax::ExpressionStatement &); + virtual void visit(ProgramSyntax::Import &); virtual void visit(ProgramSyntax::Layout &); virtual void visit(ProgramSyntax::StructDeclaration &); virtual void visit(ProgramSyntax::VariableDeclaration &); @@ -40,7 +60,193 @@ public: virtual void visit(ProgramSyntax::Return &); }; -private: + template + struct NodeGatherer: Visitor + { + typedef std::list ResultType; + + std::list nodes; + + const ResultType &get_result() const { return nodes; } + virtual void visit(T &n) { nodes.push_back(&n); } + }; + + struct DeclarationCombiner: Visitor + { + bool toplevel; + std::map > functions; + std::map variables; + bool remove_node; + + DeclarationCombiner(); + + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + }; + + struct VariableResolver: Visitor + { + std::vector blocks; + ProgramSyntax::StructDeclaration *type; + bool anonymous; + std::string block_interface; + bool record_target; + ProgramSyntax::VariableDeclaration *assignment_target; + bool self_referencing; + + VariableResolver(); + + virtual void apply(ProgramSyntax::Stage &); + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::MemberAccess &); + virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::Assignment &); + virtual void visit(ProgramSyntax::StructDeclaration &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::InterfaceBlock &); + }; + + struct FunctionResolver: Visitor + { + std::map > functions; + + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + }; + + struct BlockModifier: Visitor + { + bool remove_node; + std::list insert_nodes; + + BlockModifier(); + + void flatten_block(ProgramSyntax::Block &); + void apply_and_increment(ProgramSyntax::Block &, std::list >::iterator &); + virtual void visit(ProgramSyntax::Block &); + }; + + struct InterfaceGenerator: BlockModifier + { + std::string in_prefix; + std::string out_prefix; + unsigned scope_level; + std::map iface_declarations; + + InterfaceGenerator(); + + static std::string get_out_prefix(ProgramSyntax::StageType); + virtual void apply(ProgramSyntax::Stage &); + virtual void visit(ProgramSyntax::Block &); + std::string change_prefix(const std::string &, const std::string &) const; + bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &); + void insert_assignment(const std::string &, ProgramSyntax::Expression *); + virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::Passthrough &); + }; + + struct VariableRenamer: Visitor + { + virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + }; + + struct ExpressionEvaluator: ProgramSyntax::NodeVisitor + { + typedef std::map ValueMap; + + const ValueMap *variable_values; + float result; + bool result_valid; + + ExpressionEvaluator(); + ExpressionEvaluator(const ValueMap &); + + virtual void visit(ProgramSyntax::Literal &); + virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::UnaryExpression &); + virtual void visit(ProgramSyntax::BinaryExpression &); + }; + + struct ConstantConditionEliminator: BlockModifier + { + unsigned scope_level; + ExpressionEvaluator::ValueMap variable_values; + + ConstantConditionEliminator(); + + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::Assignment &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::Conditional &); + virtual void visit(ProgramSyntax::Iteration &); + }; + + struct UnusedVariableLocator: Visitor + { + struct AssignmentList + { + std::vector nodes; + bool conditional; + bool self_referencing; + }; + + typedef std::set ResultType; + typedef std::map BlockAssignmentMap; + + std::set unused_nodes; + std::map aggregates; + ProgramSyntax::Node *aggregate; + std::vector assignments; + ProgramSyntax::Assignment *assignment; + bool assignment_target; + + UnusedVariableLocator(); + + virtual void apply(ProgramSyntax::Stage &); + const ResultType &get_result() const { return unused_nodes; } + virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::MemberAccess &); + virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::Assignment &); + void record_assignment(ProgramSyntax::VariableDeclaration &, ProgramSyntax::Node &, bool); + virtual void visit(ProgramSyntax::ExpressionStatement &); + virtual void visit(ProgramSyntax::StructDeclaration &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::InterfaceBlock &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + void merge_down_assignments(); + virtual void visit(ProgramSyntax::Conditional &); + virtual void visit(ProgramSyntax::Iteration &); + }; + + struct UnusedFunctionLocator: Visitor + { + typedef std::set ResultType; + + std::set unused_nodes; + std::set used_definitions; + + const ResultType &get_result() const { return unused_nodes; } + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + }; + + struct NodeRemover: Visitor + { + std::set to_remove; + + NodeRemover() { } + NodeRemover(const std::set &); + + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + }; + + Resources *resources; ProgramParser parser; ProgramSyntax::Module *module; @@ -48,14 +254,22 @@ public: ProgramCompiler(); void compile(const std::string &); - void compile(IO::Base &); + void compile(IO::Base &, Resources * = 0); void add_shaders(Program &); private: + static ProgramSyntax::Module *create_builtins_module(); + static ProgramSyntax::Module &get_builtins_module(); + static ProgramSyntax::Stage *get_builtins(ProgramSyntax::StageType); void process(); - void process(ProgramSyntax::Context &); + void import(const std::string &); + void generate(ProgramSyntax::Stage &); + bool optimize(ProgramSyntax::Stage &); static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &); - std::string format_context(ProgramSyntax::Context &); + template + static typename T::ResultType apply(ProgramSyntax::Stage &); + template + static typename T::ResultType apply(ProgramSyntax::Stage &, const A &); }; } // namespace GL