1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the 'rewrite (x) { ... }' construct.
4 // We'll transform this construct into the equivalent 'rewrite class ...'
5 // and 'rewrite id { ... };' statements.
7 ///////////////////////////////////////////////////////////////////////////////
15 ///////////////////////////////////////////////////////////////////////////////
17 // Method for compiling a 'rewrite (x) { ... }' statement.
19 ///////////////////////////////////////////////////////////////////////////////
20 void RewritingCompiler::gen_rewriting
21 ( Protocols protocols,
28 { MEM::use_global_pools();
29 Id rewriter_name = Quark(options.mangled_file_prefix,vars.new_label());
33 (qualifiers & ~QUALapplicative) |
34 (dest == NOexp ? QUALnone : QUALapplicative);
36 // Get the return and argument types
37 match (protocols) and (dest)
38 { #[PROTOCOL{ ty ... } ... _], NOexp: { exp_ty = ty; ret_ty = void_ty; }
39 | #[PROTOCOL{ ty ... } ... _], dest: { exp_ty = ret_ty = ty; }
40 | _: { error("%Lempty type list in rewrite (...) ..."); }
43 // If it is destructive, use call by reference
44 if (! (qual & QUALapplicative)) exp_ty = mkrefty(exp_ty);
46 // Print the interface to the auxiliary function
47 pr("%+%^extern %t %s_rewrite(%t);", ret_ty, "", rewriter_name, exp_ty, "");
49 // Generate the rewriting call
51 { NOexp: { pr("%^%s_rewrite(%e);", rewriter_name, exp); }
52 | dest: { pr("%^%e = %s_rewrite(%e);", dest, rewriter_name, exp); }
57 // Add to the list of outstanding rewriting classes
58 Decl body = OPAQUEdecl(
59 #"\npublic:\n inline " + rewriter_name + #"() {}\n");
61 CLASSDEFdecl(new RewriteClass(rewriter_name,protocols,#[],qual,#[body]));
62 rewriters = #[new_def,REWRITEdecl(rewriter_name, Is, rules) ... rewriters];
63 MEM::use_local_pools();
66 ///////////////////////////////////////////////////////////////////////////////
68 // Method for compiling rewrite classes for the 'rewrite (...) { ... }'
71 ///////////////////////////////////////////////////////////////////////////////
72 void RewritingCompiler::gen_rewriters()
74 debug_msg("[Generating the rewriters in this file]\n");
75 for_each (Decl, d, rewriters)
78 { CLASSDEFdecl (a_class) |
79 a_class->class_type == ClassDefinition::REWRITE_CLASS &&
81 { Id id = a_class->class_name;
82 Ty ty = a_class->protocols->#1->ty;
83 TyQual qual = a_class->qualifiers;
84 // If it is destructive, use call by reference
85 Bool is_applicative = qual & QUALapplicative;
86 Bool do_traversal = qual & QUALtreeparser;
87 Ty exp_ty = is_applicative ? ty : mkrefty(ty);
88 Ty ret_ty = is_applicative ? ty : void_ty;
91 pr ("%^%t %s_rewrite(%t _x_) ", ret_ty, "", id, exp_ty, "");
92 // declare the rewriter
93 pr ("%^{ %s _r_;", id);
97 { pr ("%^ return _r_.reduce(_r_(_x_));"); }
99 { pr ("%^ _r_(_x_); %s_r_.reduce(_x_);",
100 ret_ty == void_ty ? "" : "return ");
103 { if (is_applicative)
104 { pr ("%^ return _r_(_x_);"); }
106 { pr ("%^ _r_(_x_);"); }
113 debug_msg("[Finished generating the rewriters in this file]\n");