1 ///////////////////////////////////////////////////////////////////////////////
3 // The file implements the class Compiler and this is the main entry
4 // point of the Prop -> C++ translator.
6 ///////////////////////////////////////////////////////////////////////////////
14 ///////////////////////////////////////////////////////////////////////////////
16 // Constructor and destructor
18 ///////////////////////////////////////////////////////////////////////////////
19 Compiler:: Compiler(TyOpt opt, int embedded_tags)
20 : DatatypeCompiler (opt,embedded_tags) {}
21 Compiler::~Compiler() {}
23 ///////////////////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////////////////
28 void Compiler::emit_header(const char * text, int n) { header.emit(text,n); }
29 void Compiler::emit_header_text()
30 { const char * header_text = header.text();
31 if (header_text) pr("%s",header_text);
34 ///////////////////////////////////////////////////////////////////////////////
36 // Additional printing method
38 ///////////////////////////////////////////////////////////////////////////////
39 va_list Compiler::printer(char fmt, va_list arg)
41 { 'm': { MatchCompiler::gen(va_arg(arg,Match)); }
42 | '&': { gen(va_arg(arg,Decls)); }
43 | 'D': { gen(va_arg(arg,Decl)); }
44 | _ : { bug("undefined print format '%%%c'\n", (int)fmt); }
49 ///////////////////////////////////////////////////////////////////////////////
51 // Top level code generation method
53 ///////////////////////////////////////////////////////////////////////////////
54 void Compiler::generate(Decls ds)
56 // generate the quark literals
57 if (quark_map.size() > 0)
61 foreach_entry (e, quark_map)
62 { Id name = (Id)quark_map.key(e);
63 Id quark = (Id)quark_map.value(e);
64 pr ("%^static const Quark %s(%s);\n", quark, name);
68 // now generate the main program.
71 // finally, generate any outstanding rewriters
74 // if the visualization is on then print GDL
75 if (options.visualization) print_definitions_as_GDL();
78 ///////////////////////////////////////////////////////////////////////////////
80 // Method to generate a list of declarations.
82 ///////////////////////////////////////////////////////////////////////////////
83 void Compiler::gen(Decls ds)
84 { Bool line_prefix = true;
85 Bool line_suffix = true;
89 { TYPEEXPdecl _: { line_suffix = line_prefix; line_prefix = false; }
90 | _: { line_suffix = line_prefix; line_prefix = true; }
92 gen(one,line_prefix,line_suffix);
98 ///////////////////////////////////////////////////////////////////////////////
100 // Method to generate one declaration.
102 ///////////////////////////////////////////////////////////////////////////////
103 void Compiler::gen(Decl d, Bool line_prefix, Bool line_suffix)
105 NOdecl: { /* skip */ }
106 | OPAQUEdecl d: { pr ("%C",d); }
107 | DATATYPEdecl(d,v,l,t): { gen_datatype(d,v,l,t); }
108 | INSTANTIATEdecl(e,t): { instantiate_datatypes(e,t);}
109 | REWRITEdecl (id,indices,rules): { gen_rewrite(id, indices, rules); }
110 | REWRITINGdecl (a,b,c,d,e,f): { gen_rewriting(a,b,c,d,e,f); }
111 | FUNdecl (fundefs): { gen_fun_def(fundefs); }
112 | MATCHdecl (exps, rules, opt, ty): { gen_match_stmt(exps,rules,opt,ty); }
113 | SYNTAXdecl(id, gram_exp): { gen_parser(id,gram_exp); }
114 | ATTRIBUTEGRAMMARdecl(id, e): { gen_attribute_grammar(id,e); }
115 | INFERENCEdecl (id, rules): { gen_inference_rules(id, rules); }
116 | SETLSTMTdecl stmt: { gen_setl(stmt); }
117 | SETLDEFdecl def: { gen_setl(def); }
118 // | CONSTRAINTdecl(id,rules): { compile_ruleset(id,rules); }
119 | REPLACEMENTdecl(exp,mode): { gen_replacement(exp,mode); }
120 | CUTREWRITEdecl(exp,mode): { gen_cutreplacement(exp,mode); }
121 | FAILREWRITEdecl(mode): { gen_failrewrite(mode); }
122 | CLASSDEFdecl(a_class):
123 { a_class->gen_class_definition(*this); }
125 { match (lookup_ty(id))
126 { TYCONty(DATATYPEtycon { id ... }, _):
129 { match (find_cons(id))
130 { ONEcons { ty = NOty ... }:
131 { error ("%Lconstructor %s is not a class\n", id); }
132 | ONEcons { opt ... } | opt & OPTunboxed:
133 { error ("%Lthe class representation of constructor %s has been elided\n", id); }
137 TYCONty(DATATYPEtycon{ id, opt ... },_)
139 { if (opt & OPTsubclassless) pr ("a_%s", id);
140 else pr ("%s_%S", id, name);
143 { error ("%Ltype or constructor %s is undefined\n", id); }
147 { error ("%Ltype %s has unknown class: %T\n",id, ty); }
150 | TYPEEXPdecl ty: { pr ("%t", ty,""); }
151 | GOTOdecl label: { pr ("%^goto %s;\n", label); }
152 | SETSTATEdecl state: { pr ("s__ = %i;", state); }
153 | INJECTdecl { node_number, direction = RIGHTdirection }:
154 { pr (" if (i__) insert_alpha(%i,fact__); else remove_alpha(%i,fact__); ",
155 node_number, node_number); }
156 | INJECTdecl { node_number, direction = LEFTdirection }:
157 { pr (" if (i__) insert_beta(%i,f__); else remove_beta(%i,f__); ",
158 node_number, node_number); }
159 // | BITFIELDdecl { name, width, field_names, laws }:
160 // { define_bitfield(name, width, field_names, laws);
161 // gen_bitfield(name, width, field_names, laws);
163 | EXPdecl { exp = e as (SYNexp _ || THISSYNexp _) ... }:
165 | EXPdecl { prefix, exp, suffix}:
166 { pr ("%^%s%e%s", (prefix ? prefix : ""),exp, (suffix ? suffix : "")); }
167 | MARKEDdecl (loc,d):
168 { line = loc.begin_line;
169 file = loc.file_name;
170 if (line_prefix) pr ("%#",line,file);
173 if (line_suffix) pr ("%#",line,file);
175 | d: { bug("Unimplemented feature"); }
179 ///////////////////////////////////////////////////////////////////////////////
181 // Method to generate a report.
183 ///////////////////////////////////////////////////////////////////////////////
184 ostream& Compiler::print_report(ostream& f)
186 "------------------------------- Statistics -------------------------------"
187 << "\nMerge matching rules = " << (options.merge_match ? "yes" : "no")
188 << "\nNumber of DFA nodes merged = " << merges
189 << "\nNumber of ifs generated = " << ifs
190 << "\nNumber of switches generated = " << switches
191 << "\nNumber of labels = " << goto_labels
192 << "\nNumber of gotos = " << gotos
193 << "\nAdaptive matching = " << (options.adaptive_matching ? "enabled" : "disabled")
194 << "\nFast string matching = " << (options.fast_string_match ? "enabled" : "disabled")
195 << "\nInline downcasts = " << (options.inline_casts ? "enabled" : "disabled")
197 "--------------------------------------------------------------------------"