1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "classdef.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
8 ///////////////////////////////////////////////////////////////////////////////
10 // This file implements the class definition mechanism of Prop.
12 ///////////////////////////////////////////////////////////////////////////////
15 #include <AD/strings/quark.h>
24 ///////////////////////////////////////////////////////////////////////////////
26 // Names of various class types
28 ///////////////////////////////////////////////////////////////////////////////
29 const char * ClassDefinition::class_type_name
[ClassDefinition::LAST_CLASS
] =
37 "attributegrammar class",
42 ///////////////////////////////////////////////////////////////////////////////
44 // Hashtable that contains all the classes indexed by name
46 ///////////////////////////////////////////////////////////////////////////////
47 HashTable
ClassDefinition::defined_classes(string_hash
, string_equal
);
49 ClassDefinition
* ClassDefinition::lookup_class(CLASS_TYPE ct
, Id name
)
50 { HashTable::Entry
* e
= defined_classes
.lookup(name
);
52 { error("%L%s %s has not been defined\n", class_type_name
[ct
], name
);
55 { ClassDefinition
* C
= (ClassDefinition
*)(e
->v
);
56 if (C
->class_type
!= ct
&& ct
!= ANY_CLASS
)
57 { error("%Lclass %s is not a %s\n"
58 "%!this is where %s %s was previously defined\n",
59 name
, class_type_name
[ct
],
60 C
->loc(), class_type_name
[C
->class_type
], name
);
67 void ClassDefinition::insert_class(ClassDefinition
* C
)
68 { HashTable::Entry
* e
= defined_classes
.lookup(C
->class_name
);
70 { ClassDefinition
* old_def
= (ClassDefinition
*)(e
->v
);
71 error("%Lredefinition of %s %s\n"
72 "%!this is where it was previously defined.\n",
73 class_type_name
[C
->class_type
], C
->class_name
,
76 { defined_classes
.insert(C
->class_name
,C
);
80 ///////////////////////////////////////////////////////////////////////////////
82 // Constructor and destructors for datatype compiler
84 ///////////////////////////////////////////////////////////////////////////////
85 ClassDefinition::ClassDefinition
86 (CLASS_TYPE ct
, Id id
,
87 TyVars p
, Inherits subclasses
, TyQual qual
, Decls body
)
89 class_name(id
), parameters(p
), inherited_classes(subclasses
),
90 qualifiers(qual
), class_body(body
)
92 #line 84 "classdef.pcc"
93 #line 84 "classdef.pcc"
95 #line 84 "classdef.pcc"
96 #line 84 "classdef.pcc"
99 #line 85 "classdef.pcc"
100 #line 85 "classdef.pcc"
102 #line 85 "classdef.pcc"
103 #line 85 "classdef.pcc"
108 ClassDefinition::~ClassDefinition() {}
110 ///////////////////////////////////////////////////////////////////////////////
112 // Method to generate a class definition
114 ///////////////////////////////////////////////////////////////////////////////
115 void ClassDefinition::gen_class_definition(CodeGen
& C
)
116 { gen_class_predefinition(C
);
117 C
.pr ("%^%Hclass %s", parameters
, class_name
);
118 if (inherited_classes
!=
119 #line 99 "classdef.pcc"
120 #line 99 "classdef.pcc"
122 #line 99 "classdef.pcc"
123 #line 99 "classdef.pcc"
124 ) C
.pr (" : %I",inherited_classes
);
126 gen_class_interface(C
);
127 C
.pr ("%&%-%^};\n", class_body
);
128 gen_class_postdefinition(C
);
131 ///////////////////////////////////////////////////////////////////////////////
133 // The default is to generate nothing for the following
135 ///////////////////////////////////////////////////////////////////////////////
136 void ClassDefinition::gen_class_predefinition(CodeGen
& C
) {}
137 void ClassDefinition::gen_class_interface(CodeGen
& C
) {}
138 void ClassDefinition::gen_class_postdefinition(CodeGen
& C
) {}
139 void ClassDefinition::gen_class_implementation(CodeGen
& C
, Tys
, DefKind
) {}
141 ///////////////////////////////////////////////////////////////////////////////
145 ///////////////////////////////////////////////////////////////////////////////
146 Id
ClassDefinition::mangled_name() const { return mangle(class_name
); }
147 Bool
ClassDefinition::is_polymorphic() const { return parameters
!=
148 #line 122 "classdef.pcc"
149 #line 122 "classdef.pcc"
151 #line 122 "classdef.pcc"
152 #line 122 "classdef.pcc"
154 Bool
ClassDefinition::is_view() const { return qualifiers
& QUALview
; }
156 ///////////////////////////////////////////////////////////////////////////////
158 // Method to add a base class to the inheritance list
160 ///////////////////////////////////////////////////////////////////////////////
161 void ClassDefinition::add_base_class (Id name
, Scope s
, TyQual q
)
163 inherited_classes
= add_inherit(name
,
164 #line 132 "classdef.pcc"
165 #line 132 "classdef.pcc"
167 #line 132 "classdef.pcc"
168 #line 132 "classdef.pcc"
169 ,inherited_classes
,s
,q
);
172 void ClassDefinition::append_base_class (Id name
, Scope s
, TyQual q
)
174 inherited_classes
= append(inherited_classes
,
176 #line 138 "classdef.pcc"
177 #line 138 "classdef.pcc"
179 #line 138 "classdef.pcc"
180 #line 138 "classdef.pcc"
182 #line 138 "classdef.pcc"
183 #line 138 "classdef.pcc"
185 #line 138 "classdef.pcc"
186 #line 138 "classdef.pcc"
190 ///////////////////////////////////////////////////////////////////////////////
192 // Method to generate a constructor
194 ///////////////////////////////////////////////////////////////////////////////
195 void ClassDefinition::gen_class_constructor(CodeGen
& C
, Tys tys
, DefKind k
)
198 { case INTERFACE_DEFINITION
:
199 C
.pr("%^%s ", class_name
); break;
200 case INLINE_IMPLEMENTATION
:
201 C
.pr("%^inline %s ", class_name
); break;
202 case EXTERNAL_IMPLEMENTATION
:
203 C
.pr("%^%H %s%V::%s ",parameters
, class_name
, parameters
, class_name
);
205 case EXTERNAL_INSTANTIATION
:
206 case EXTERNAL_DEFINITION
:
207 C
.pr("%^%s%P::%s ", class_name
, tys
, class_name
);
211 gen_class_constructor_parameters(C
, tys
, k
);
214 { case INLINE_IMPLEMENTATION
:
215 case EXTERNAL_IMPLEMENTATION
:
216 case EXTERNAL_INSTANTIATION
:
217 gen_class_constructor_initializers(C
, tys
, k
);
219 gen_class_constructor_body(C
, tys
, k
);
220 if (constructor_code
) C
.pr("%^%&", constructor_code
);
223 case INTERFACE_DEFINITION
:
224 case EXTERNAL_DEFINITION
:
229 ///////////////////////////////////////////////////////////////////////////////
231 // Method to generate a destructor
233 ///////////////////////////////////////////////////////////////////////////////
234 void ClassDefinition::gen_class_destructor(CodeGen
& C
, Tys tys
, DefKind k
)
236 Id v
= (qualifiers
& QUALvirtualdestr
) ? "virtual " : "";
238 { case INTERFACE_DEFINITION
:
239 C
.pr("%^%s~%s()", v
, class_name
); break;
240 case INLINE_IMPLEMENTATION
:
241 C
.pr("%^inline %s~%s()", v
, class_name
); break;
242 case EXTERNAL_IMPLEMENTATION
:
243 C
.pr("%^%H %s%V::~%s()",
244 parameters
, class_name
, parameters
, class_name
);
246 case EXTERNAL_INSTANTIATION
:
247 case EXTERNAL_DEFINITION
:
248 C
.pr("%^%s%P::~%s()", class_name
, tys
, class_name
);
253 { case INLINE_IMPLEMENTATION
:
254 case EXTERNAL_IMPLEMENTATION
:
255 case EXTERNAL_INSTANTIATION
:
257 gen_class_destructor_body(C
,tys
,k
);
258 if (destructor_code
) C
.pr("%^%&", destructor_code
);
261 case INTERFACE_DEFINITION
:
262 case EXTERNAL_DEFINITION
:
267 ///////////////////////////////////////////////////////////////////////////////
269 // Defaults method to generate various parts of the constructor and destructor
271 ///////////////////////////////////////////////////////////////////////////////
272 void ClassDefinition::gen_class_constructor_parameters(CodeGen
& C
,Tys
,DefKind
)
275 void ClassDefinition::gen_class_constructor_initializers(CodeGen
&,Tys
,DefKind
)
278 void ClassDefinition::gen_class_constructor_body(CodeGen
&,Tys
,DefKind
)
281 void ClassDefinition::gen_class_destructor_body(CodeGen
&,Tys
,DefKind
)
285 ///////////////////////////////////////////////////////////////////////////////
287 // Method to add constructor code to a class
289 ///////////////////////////////////////////////////////////////////////////////
290 ClassDefinition
* ClassDefinition::lookup_class_or_datatype
291 (Id class_name
, Id constructor
)
293 #line 243 "classdef.pcc"
294 #line 250 "classdef.pcc"
296 Ty _V1
= lookup_ty(class_name
);
298 switch (_V1
->tag__
) {
299 case a_Ty::tag_TYCONty
: {
300 if (boxed(((Ty_TYCONty
*)_V1
)->_1
)) {
301 switch (((Ty_TYCONty
*)_V1
)->_1
->tag__
) {
302 case a_TyCon::tag_DATATYPEtycon
: {
304 #line 244 "classdef.pcc"
305 (class_name
== constructor
)
306 #line 244 "classdef.pcc"
309 #line 245 "classdef.pcc"
310 return ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->hierarchy
;
311 #line 245 "classdef.pcc"
314 #line 247 "classdef.pcc"
315 Cons cons
= lookup_cons(constructor
);
316 if (cons
) return cons
->class_def
;
318 #line 249 "classdef.pcc"
323 #line 250 "classdef.pcc"
324 return lookup_class(ANY_CLASS
,class_name
);
325 #line 250 "classdef.pcc"
330 default: { goto L1
; } break;
334 #line 251 "classdef.pcc"
335 #line 251 "classdef.pcc"
340 ///////////////////////////////////////////////////////////////////////////////
342 // Method to add constructor code to a class
344 ///////////////////////////////////////////////////////////////////////////////
345 void ClassDefinition::add_constructor_code
346 (Id class_name
, Id constructor
, Decls body
)
347 { ClassDefinition
* C
= lookup_class_or_datatype(class_name
,constructor
);
348 if (C
) C
->constructor_code
= append(C
->constructor_code
, body
);
351 ///////////////////////////////////////////////////////////////////////////////
353 // Method to add destructor code to a class
355 ///////////////////////////////////////////////////////////////////////////////
356 void ClassDefinition::add_destructor_code
357 (Id class_name
, Id destructor
, Decls body
)
358 { ClassDefinition
* C
= lookup_class_or_datatype(class_name
,destructor
);
359 if (C
) C
->destructor_code
= append(C
->destructor_code
, body
);
361 #line 276 "classdef.pcc"
363 ------------------------------- Statistics -------------------------------
364 Merge matching rules = yes
365 Number of DFA nodes merged = 23
366 Number of ifs generated = 3
367 Number of switches generated = 2
370 Adaptive matching = enabled
371 Fast string matching = disabled
372 Inline downcasts = enabled
373 --------------------------------------------------------------------------