#include #include #include // forward declaration class PrintVisitor; class Printable { public: virtual void Print(PrintVisitor& visitor) = 0; }; class PrintVisitor { public: // Constructor PrintVisitor(int start, int stop, int step) : current( start ), stop( stop ), step( step ), col( 0 ), row( 0 ) { } bool Done() { // opcode return current > stop; } void Print(std::string to_print) { // opcode std::cout << to_print; } void Newline() { // opcode std::cout << "\n"; col = 0; row += 1; } void Integer() { // opcode std::cout << current; current += step; } void Row() { // opcode std::cout << row; } void Col() { // opcode std::cout << col; col += 1; } private: // interpretive state (e.g. registers) int current; int stop; int step; int col; int row; }; class Loop : public Printable { public: // Constructor. explicit Loop(Printable& body) : body(body) {} void Print(PrintVisitor& visitor) { while (not visitor.Done()) { body.Print(visitor); } } private: Printable& body; }; class Literal : public Printable { public: // Constructor. explicit Literal(std::string to_print) : to_print(to_print) {} void Print(PrintVisitor& visitor) { visitor.Print(to_print); } private: std::string to_print; }; class Newline : public Printable { public: void Print(PrintVisitor& visitor) { visitor.Newline(); } }; class Integer : public Printable { public: void Print(PrintVisitor& visitor) { visitor.Integer(); } }; class Row : public Printable { public: void Print(PrintVisitor& visitor) { visitor.Row(); } }; class Col : public Printable { public: void Print(PrintVisitor& visitor) { visitor.Col(); } }; class Sequence : public Printable { public: // Mutator void Add(Printable& to_add) { to_print.push_back(&to_add); } void Print(PrintVisitor& visitor) { for (int i= 0; i < to_print.size(); ++i) { to_print[i]->Print(visitor); } } private: std::vector to_print; }; class ExampleReport : public Printable { public: // Constructor ExampleReport() : tab_col_lit("\tcol"), c(), nl90, row_lit("row"), r, colon_tab_lit(":\t"), i, comma_tab_lit(",\t"), loop_body(), loop(loop_body), total() { loop_body.Add(row_lit); loop_body.Add(r); loop_body.Add(colon_tab_lit); loop_body.Add(i); loop_body.Add(comma_tab_lit); loop_body.Add(i); loop_body.Add(comma_tab_lit); loop_body.Add(i); loop_body.Add(nl); total.Add(tab_col_lit); total.Add(c); total.Add(tab_col_lit); total.Add(c); total.Add(tab_col_lit); total.Add(c); total.Add(nl); total.Add(loop); } void Print(PrintVisitor& visitor) { total.Print(visitor); } private: Literal tab_col_lit; Col c; Newline nl; Literal row_lit; Row r; Literal colon_tab_lit; Integer i; Literal comma_tab_lit; Sequence loop_body; Loop loop; Sequence total; }; int main(int argc, char* argv[]) { ExampleReport report; PrintVisitor visitor(10, 30, 3); report.Print(visitor); return 0; }