From 7cd066816f7faab6f8f0eba1fca4dee67ee5dc3b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 11 Nov 2016 19:02:06 +0200 Subject: [PATCH] Assorted refactoring and fixes --- source/programcompiler.cpp | 60 +++++++++++++++++--------------------- source/programcompiler.h | 38 +++++++++++++----------- source/programparser.cpp | 33 +++++++++------------ source/programparser.h | 1 - source/programsyntax.cpp | 6 ++-- source/programsyntax.h | 6 +++- 6 files changed, 69 insertions(+), 75 deletions(-) diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index bc021c97..98b11e89 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -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(stage); + apply(stage); + apply(stage); + apply(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 +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 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 set(stage, &s); if(stage->previous) @@ -446,7 +452,7 @@ void ProgramCompiler::InterfaceGenerator::visit(Block &block) if(scope_level==1) { - for(map >::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j) + for(map::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j) { list >::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 >::iterator j=insert_nodes.begin(); j!=insert_nodes.end(); ++j) + for(list::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; diff --git a/source/programcompiler.h b/source/programcompiler.h index 7200679e..db7aefe9 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -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 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 > iface_declarations; + std::map iface_declarations; bool remove_node; - std::list > insert_nodes; + std::list 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 unused_nodes; std::map 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 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 + static void apply(ProgramSyntax::Stage &); std::string create_source(ProgramSyntax::Stage &); }; diff --git a/source/programparser.cpp b/source/programparser.cpp index 16299d20..36cc6e08 100644 --- a/source/programparser.cpp +++ b/source/programparser.cpp @@ -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 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 var = new VariableDeclaration; - var->type = expect_type(); - var->name = expect_identifier(); - func.parameters.push_back(var.release()); - } - expect(")"); -} - InterfaceBlock *ProgramParser::parse_interface_block() { RefPtr iface = new InterfaceBlock; @@ -724,7 +718,8 @@ Return *ProgramParser::parse_return() { expect("return"); RefPtr ret = new Return; - ret->expression = parse_expression(); + if(peek_token()!=";") + ret->expression = parse_expression(); expect(";"); return ret.release(); } diff --git a/source/programparser.h b/source/programparser.h index 4c2d7b7e..e2462516 100644 --- a/source/programparser.h +++ b/source/programparser.h @@ -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(); diff --git a/source/programsyntax.cpp b/source/programsyntax.cpp index 6e4d070e..4341f06b 100644 --- a/source/programsyntax.cpp +++ b/source/programsyntax.cpp @@ -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); } diff --git a/source/programsyntax.h b/source/programsyntax.h index c645a60a..cbce078e 100644 --- a/source/programsyntax.h +++ b/source/programsyntax.h @@ -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 condition; Block body; Block else_body; -- 2.43.0