]> git.tdb.fi Git - libs/gl.git/commitdiff
Assorted refactoring and fixes
authorMikko Rasa <tdb@tdb.fi>
Fri, 11 Nov 2016 17:02:06 +0000 (19:02 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 11 Nov 2016 17:02:06 +0000 (19:02 +0200)
source/programcompiler.cpp
source/programcompiler.h
source/programparser.cpp
source/programparser.h
source/programsyntax.cpp
source/programsyntax.h

index bc021c97b04874ccf375d82383218da4d9a4b4d7..98b11e89b834d48a665e8e4059bfe306d882a7af 100644 (file)
@@ -63,15 +63,10 @@ void ProgramCompiler::generate(Stage &stage)
 {
        inject_block(stage.content, module->shared.content);
 
-       resolve_variables(stage);
-
-       InterfaceGenerator generator;
-       generator.visit(stage);
-
-       resolve_variables(stage);
-
-       VariableRenamer renamer;
-       stage.content.visit(renamer);
+       apply<VariableResolver>(stage);
+       apply<InterfaceGenerator>(stage);
+       apply<VariableResolver>(stage);
+       apply<VariableRenamer>(stage);
 }
 
 void ProgramCompiler::optimize(Stage &stage)
@@ -79,11 +74,11 @@ void ProgramCompiler::optimize(Stage &stage)
        while(1)
        {
                UnusedVariableLocator unused_locator;
-               unused_locator.visit(stage);
+               unused_locator.apply(stage);
 
                NodeRemover remover;
                remover.to_remove = unused_locator.unused_nodes;
-               remover.visit(stage);
+               remover.apply(stage);
 
                if(!remover.n_removed)
                        break;
@@ -97,20 +92,32 @@ void ProgramCompiler::inject_block(Block &target, const Block &source)
                target.body.insert(insert_point, (*i)->clone());
 }
 
-void ProgramCompiler::resolve_variables(Stage &stage)
+template<typename T>
+void ProgramCompiler::apply(Stage &stage)
 {
-       VariableResolver resolver;
-       stage.content.visit(resolver);
+       T visitor;
+       visitor.apply(stage);
 }
 
 string ProgramCompiler::create_source(Stage &stage)
 {
        Formatter formatter;
-       stage.content.visit(formatter);
+       formatter.apply(stage);
        return formatter.formatted;
 }
 
 
+ProgramCompiler::Visitor::Visitor():
+       stage(0)
+{ }
+
+void ProgramCompiler::Visitor::apply(Stage &s)
+{
+       SetForScope<Stage *> set(stage, &s);
+       stage->content.visit(*this);
+}
+
+
 ProgramCompiler::Formatter::Formatter():
        indent(0),
        parameter_list(false),
@@ -413,7 +420,6 @@ void ProgramCompiler::VariableResolver::visit(InterfaceBlock &iface)
 
 
 ProgramCompiler::InterfaceGenerator::InterfaceGenerator():
-       stage(0),
        scope_level(0),
        remove_node(false)
 { }
@@ -428,7 +434,7 @@ string ProgramCompiler::InterfaceGenerator::get_out_prefix(StageType type)
                return string();
 }
 
-void ProgramCompiler::InterfaceGenerator::visit(Stage &s)
+void ProgramCompiler::InterfaceGenerator::apply(Stage &s)
 {
        SetForScope<Stage *> set(stage, &s);
        if(stage->previous)
@@ -446,7 +452,7 @@ void ProgramCompiler::InterfaceGenerator::visit(Block &block)
 
                if(scope_level==1)
                {
-                       for(map<string, NodePtr<Node> >::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j)
+                       for(map<string, Node *>::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j)
                        {
                                list<NodePtr<Node> >::iterator k = block.body.insert(i, j->second);
                                (*k)->visit(*this);
@@ -454,7 +460,7 @@ void ProgramCompiler::InterfaceGenerator::visit(Block &block)
                        iface_declarations.clear();
                }
 
-               for(list<NodePtr<Node> >::iterator j=insert_nodes.begin(); j!=insert_nodes.end(); ++j)
+               for(list<Node *>::iterator j=insert_nodes.begin(); j!=insert_nodes.end(); ++j)
                        block.body.insert(i, *j);
                insert_nodes.clear();
 
@@ -488,7 +494,7 @@ bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration
        iface_var->array_size = out.array_size;
        if(iface=="in")
                iface_var->linked_declaration = &out;
-       iface_declarations[iface_var->name] = iface_var;
+       iface_declarations[name] = iface_var;
 
        return true;
 }
@@ -602,17 +608,10 @@ void ProgramCompiler::VariableRenamer::visit(VariableDeclaration &var)
 
 
 ProgramCompiler::UnusedVariableLocator::UnusedVariableLocator():
-       stage(0),
        assignment(false),
        assignment_target(0)
 { }
 
-void ProgramCompiler::UnusedVariableLocator::visit(Stage &s)
-{
-       stage = &s;
-       stage->content.visit(*this);
-}
-
 void ProgramCompiler::UnusedVariableLocator::visit(VariableReference &var)
 {
        if(assignment)
@@ -670,18 +669,11 @@ void ProgramCompiler::UnusedVariableLocator::visit(VariableDeclaration &var)
 
 
 ProgramCompiler::NodeRemover::NodeRemover():
-       stage(0),
        n_removed(0),
        immutable_block(false),
        remove_block(false)
 { }
 
-void ProgramCompiler::NodeRemover::visit(Stage &s)
-{
-       stage = &s;
-       stage->content.visit(*this);
-}
-
 void ProgramCompiler::NodeRemover::visit(Block &block)
 {
        remove_block = immutable_block;
index 7200679e1813723aca6857a70889663b096955b1..db7aefe9ac3762a9234cd88d4b614dfc4c56ccd0 100644 (file)
@@ -12,8 +12,17 @@ class Program;
 
 class ProgramCompiler
 {
-public:
-       struct Formatter: ProgramSyntax::NodeVisitor
+private:
+       struct Visitor: ProgramSyntax::TraversingVisitor
+       {
+               ProgramSyntax::Stage *stage;
+
+               Visitor();
+
+               virtual void apply(ProgramSyntax::Stage &);
+       };
+
+       struct Formatter: Visitor
        {
                std::string formatted;
                unsigned indent;
@@ -41,8 +50,7 @@ public:
                virtual void visit(ProgramSyntax::Return &);
        };
 
-private:
-       struct VariableResolver: ProgramSyntax::TraversingVisitor
+       struct VariableResolver: Visitor
        {
                std::vector<ProgramSyntax::Block *> blocks;
                ProgramSyntax::StructDeclaration *type;
@@ -59,20 +67,19 @@ private:
                virtual void visit(ProgramSyntax::InterfaceBlock &);
        };
 
-       struct InterfaceGenerator: ProgramSyntax::TraversingVisitor
+       struct InterfaceGenerator: Visitor
        {
-               ProgramSyntax::Stage *stage;
                std::string in_prefix;
                std::string out_prefix;
                unsigned scope_level;
-               std::map<std::string, ProgramSyntax::NodePtr<ProgramSyntax::Node> > iface_declarations;
+               std::map<std::string, ProgramSyntax::Node *> iface_declarations;
                bool remove_node;
-               std::list<ProgramSyntax::NodePtr<ProgramSyntax::Node> > insert_nodes;
+               std::list<ProgramSyntax::Node *> insert_nodes;
 
                InterfaceGenerator();
 
                static std::string get_out_prefix(ProgramSyntax::StageType);
-               void visit(ProgramSyntax::Stage &);
+               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 &);
@@ -82,15 +89,14 @@ private:
                virtual void visit(ProgramSyntax::Passthrough &);
        };
 
-       struct VariableRenamer: ProgramSyntax::TraversingVisitor
+       struct VariableRenamer: Visitor
        {
                virtual void visit(ProgramSyntax::VariableReference &);
                virtual void visit(ProgramSyntax::VariableDeclaration &);
        };
 
-       struct UnusedVariableLocator: ProgramSyntax::TraversingVisitor
+       struct UnusedVariableLocator: Visitor
        {
-               ProgramSyntax::Stage *stage;
                std::set<ProgramSyntax::Node *> unused_nodes;
                std::map<ProgramSyntax::VariableDeclaration *, ProgramSyntax::Node *> assignments;
                bool assignment;
@@ -98,7 +104,6 @@ private:
 
                UnusedVariableLocator();
 
-               void visit(ProgramSyntax::Stage &);
                virtual void visit(ProgramSyntax::VariableReference &);
                virtual void visit(ProgramSyntax::MemberAccess &);
                virtual void visit(ProgramSyntax::BinaryExpression &);
@@ -106,9 +111,8 @@ private:
                virtual void visit(ProgramSyntax::VariableDeclaration &);
        };
 
-       struct NodeRemover: ProgramSyntax::TraversingVisitor
+       struct NodeRemover: Visitor
        {
-               ProgramSyntax::Stage *stage;
                std::set<ProgramSyntax::Node *> to_remove;
                unsigned n_removed;
                bool immutable_block;
@@ -116,7 +120,6 @@ private:
 
                NodeRemover();
 
-               void visit(ProgramSyntax::Stage &);
                virtual void visit(ProgramSyntax::Block &);
                virtual void visit(ProgramSyntax::StructDeclaration &);
                virtual void visit(ProgramSyntax::VariableDeclaration &);
@@ -138,7 +141,8 @@ private:
        void generate(ProgramSyntax::Stage &);
        void optimize(ProgramSyntax::Stage &);
        static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
-       static void resolve_variables(ProgramSyntax::Stage &);
+       template<typename T>
+       static void apply(ProgramSyntax::Stage &);
        std::string create_source(ProgramSyntax::Stage &);
 };
 
index 16299d20cf157f8281fc2face34d55a21712eee1..36cc6e081b1da26d5ef745b9bd7a66e8ff7099b5 100644 (file)
@@ -218,7 +218,6 @@ bool ProgramParser::skip_comment_and_whitespace()
        unsigned slashes = 0;
        while(iter!=source.end())
        {
-               //IO::print("%d '%c'\n", comment, *iter);
                if(comment==0)
                {
                        if(*iter=='/')
@@ -614,7 +613,18 @@ FunctionDeclaration *ProgramParser::parse_function_declaration()
 
        func->return_type = expect_type();
        func->name = expect_identifier();
-       parse_function_parameter_list(*func);
+       expect("(");
+       while(peek_token()!=")")
+       {
+               if(!func->parameters.empty())
+                       expect(",");
+
+               RefPtr<VariableDeclaration> var = new VariableDeclaration;
+               var->type = expect_type();
+               var->name = expect_identifier();
+               func->parameters.push_back(var.release());
+       }
+       expect(")");
 
        string token = peek_token();
        if(token=="{")
@@ -630,22 +640,6 @@ FunctionDeclaration *ProgramParser::parse_function_declaration()
        return func.release();
 }
 
-void ProgramParser::parse_function_parameter_list(FunctionDeclaration &func)
-{
-       expect("(");
-       while(peek_token()!=")")
-       {
-               if(!func.parameters.empty())
-                       expect(",");
-
-               RefPtr<VariableDeclaration> var = new VariableDeclaration;
-               var->type = expect_type();
-               var->name = expect_identifier();
-               func.parameters.push_back(var.release());
-       }
-       expect(")");
-}
-
 InterfaceBlock *ProgramParser::parse_interface_block()
 {
        RefPtr<InterfaceBlock> iface = new InterfaceBlock;
@@ -724,7 +718,8 @@ Return *ProgramParser::parse_return()
 {
        expect("return");
        RefPtr<Return> ret = new Return;
-       ret->expression = parse_expression();
+       if(peek_token()!=";")
+               ret->expression = parse_expression();
        expect(";");
        return ret.release();
 }
index 4c2d7b7ea5bc1049ddacede49a9f6a1cb280d3e7..e246251676bdd4b7b453b0c884c55c2da8ae4122 100644 (file)
@@ -84,7 +84,6 @@ private:
        ProgramSyntax::StructDeclaration *parse_struct_declaration();
        ProgramSyntax::VariableDeclaration *parse_variable_declaration();
        ProgramSyntax::FunctionDeclaration *parse_function_declaration();
-       void parse_function_parameter_list(ProgramSyntax::FunctionDeclaration &);
        ProgramSyntax::InterfaceBlock *parse_interface_block();
        ProgramSyntax::Conditional *parse_conditional();
        ProgramSyntax::Iteration *parse_iteration();
index 6e4d070e2b3e480cd29b09ccabbb7e7ae4194415..4341f06b72c4542393c052d62c39acccb80fe53e 100644 (file)
@@ -137,19 +137,19 @@ void Conditional::visit(NodeVisitor &visitor)
 }
 
 
-void Passthrough::visit(NodeVisitor &visitor)
+void Iteration::visit(NodeVisitor &visitor)
 {
        visitor.visit(*this);
 }
 
 
-void Return::visit(NodeVisitor &visitor)
+void Passthrough::visit(NodeVisitor &visitor)
 {
        visitor.visit(*this);
 }
 
 
-void Iteration::visit(NodeVisitor &visitor)
+void Return::visit(NodeVisitor &visitor)
 {
        visitor.visit(*this);
 }
index c645a60a442ec91a616060f11c55327e9a34d4f6..cbce078e2d65c1eb74bb9985fa2639c4bc525326 100644 (file)
@@ -33,6 +33,10 @@ public:
        NodePtr(T *n = 0): node(n) { }
        NodePtr(const NodePtr &p): node(clone(p.node)) { }
        NodePtr &operator=(const NodePtr &p) { delete node; node = clone(p.node); return *this; }
+#if __cplusplus>=201103L
+       NodePtr(NodePtr &&p): node(p.node) { p.node = 0; }
+       NodePtr &operator=(NodePtr &&p) { delete node; node = p.node; p.node = 0; return *this; }
+#endif
        ~NodePtr() { delete node; }
 
 private:
@@ -223,7 +227,7 @@ struct FunctionDeclaration: Node
 
 struct Conditional: Node
 {
-       Expression *condition;
+       NodePtr<Expression> condition;
        Block body;
        Block else_body;