1 #pragma once 2 3 #include "CodeGenerator.h" 4 #include <cstddef> 5 #include <iostream> 6 #include <rumur/rumur.h> 7 #include <string> 8 #include <unordered_map> 9 #include <unordered_set> 10 #include <vector> 11 12 // generator for C-like code 13 class __attribute__((visibility("hidden"))) CLikeGenerator 14 : public CodeGenerator, 15 public rumur::ConstBaseTraversal { 16 17 protected: 18 std::ostream &out; 19 bool pack; 20 21 // mapping of Enum unique_ids to the name of a TypeDecl to them 22 std::unordered_map<size_t, std::string> enum_typedefs; 23 24 // collection of unique_ids that were emitted as pointers instead of standard 25 // variables 26 std::unordered_set<size_t> is_pointer; 27 28 // list of comments from the original source 29 std::vector<rumur::Comment> comments; 30 31 // whether each comment has been written to the output yet 32 std::vector<bool> emitted; 33 34 public: CLikeGenerator(const std::vector<rumur::Comment> & comments_,std::ostream & out_,bool pack_)35 CLikeGenerator(const std::vector<rumur::Comment> &comments_, 36 std::ostream &out_, bool pack_) 37 : out(out_), pack(pack_), comments(comments_), 38 emitted(comments_.size(), false) {} 39 40 void visit_add(const rumur::Add &n) final; 41 void visit_aliasdecl(const rumur::AliasDecl &n) final; 42 void visit_aliasrule(const rumur::AliasRule &) final; 43 void visit_aliasstmt(const rumur::AliasStmt &n) final; 44 void visit_and(const rumur::And &n) final; 45 void visit_array(const rumur::Array &n) final; 46 void visit_assignment(const rumur::Assignment &n) final; 47 void visit_band(const rumur::Band &n) final; 48 void visit_bnot(const rumur::Bnot &n) final; 49 void visit_bor(const rumur::Bor &n) final; 50 void visit_clear(const rumur::Clear &n) final; 51 void visit_div(const rumur::Div &n) final; 52 void visit_element(const rumur::Element &n) final; 53 void visit_enum(const rumur::Enum &n) final; 54 void visit_eq(const rumur::Eq &n) final; 55 void visit_errorstmt(const rumur::ErrorStmt &n) final; 56 void visit_exists(const rumur::Exists &n) final; 57 void visit_exprid(const rumur::ExprID &n) final; 58 void visit_field(const rumur::Field &n) final; 59 void visit_implication(const rumur::Implication &n) final; 60 void visit_isundefined(const rumur::IsUndefined &) final; 61 void visit_for(const rumur::For &n) final; 62 void visit_forall(const rumur::Forall &n) final; 63 void visit_functioncall(const rumur::FunctionCall &n) final; 64 void visit_geq(const rumur::Geq &n) final; 65 void visit_gt(const rumur::Gt &n) final; 66 void visit_if(const rumur::If &n) final; 67 void visit_ifclause(const rumur::IfClause &n) final; 68 void visit_leq(const rumur::Leq &n) final; 69 void visit_lsh(const rumur::Lsh &n) final; 70 void visit_lt(const rumur::Lt &n) final; 71 void visit_mod(const rumur::Mod &n) final; 72 void visit_model(const rumur::Model &n) final; 73 void visit_mul(const rumur::Mul &n) final; 74 void visit_negative(const rumur::Negative &n) final; 75 void visit_neq(const rumur::Neq &n) final; 76 void visit_not(const rumur::Not &n) final; 77 void visit_number(const rumur::Number &n) final; 78 void visit_or(const rumur::Or &n) final; 79 void visit_procedurecall(const rumur::ProcedureCall &n) final; 80 void visit_property(const rumur::Property &) final; 81 void visit_propertystmt(const rumur::PropertyStmt &n) final; 82 void visit_put(const rumur::Put &n) final; 83 void visit_quantifier(const rumur::Quantifier &n) final; 84 void visit_range(const rumur::Range &) final; 85 void visit_record(const rumur::Record &n) final; 86 void visit_return(const rumur::Return &n) final; 87 void visit_rsh(const rumur::Rsh &n) final; 88 void visit_ruleset(const rumur::Ruleset &) final; 89 void visit_scalarset(const rumur::Scalarset &) final; 90 void visit_sub(const rumur::Sub &n) final; 91 void visit_switch(const rumur::Switch &n) final; 92 void visit_switchcase(const rumur::SwitchCase &n) final; 93 void visit_ternary(const rumur::Ternary &n) final; 94 void visit_typedecl(const rumur::TypeDecl &n) final; 95 void visit_typeexprid(const rumur::TypeExprID &n) final; 96 void visit_undefine(const rumur::Undefine &n) final; 97 void visit_while(const rumur::While &n) final; 98 void visit_xor(const rumur::Xor &n) final; 99 100 // helpers to make output more natural 101 CLikeGenerator &operator<<(const std::string &s); 102 CLikeGenerator &operator<<(const rumur::Node &n); 103 104 // make this class abstract 105 virtual ~CLikeGenerator() = 0; 106 107 private: 108 // generate a print statement of the given expression and (possibly 109 // not-terminal) type 110 void print(const std::string &suffix, const rumur::TypeExpr &t, 111 const rumur::Expr &e, size_t counter); 112 113 protected: 114 // output comments preceding the given node 115 size_t emit_leading_comments(const rumur::Node &n); 116 117 // discard any un-emitted comments preceding the given position 118 size_t drop_comments(const rumur::position &pos); 119 120 // output single line comments following the given node 121 size_t emit_trailing_comments(const rumur::Node &n); 122 }; 123