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 "datatype.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_QUARK_USED
9 ///////////////////////////////////////////////////////////////////////////////
11 ///////////////////////////////////////////////////////////////////////////////
12 static const Quark
_d_a_t_a_t_y_p_eco_c_c_Q1("a_");
13 #line 1 "datatype.pcc"
14 /////////////////////////////////////////////////////////////////////////////
16 // This file implements the DatatypeClass
18 //////////////////////////////////////////////////////////////////////////////
19 #include <AD/strings/quark.h>
28 //////////////////////////////////////////////////////////////////////////////
30 // Constructor for DatatypeClass
32 //////////////////////////////////////////////////////////////////////////////
33 DatatypeClass::DatatypeClass
34 (CLASS_TYPE my_class_type
,
35 Id cid
, Id id
, TyVars p
, Inherits i
, TyQual q
, Decls d
, Cons c
,
36 DatatypeHierarchy
* r
)
37 : ClassDefinition(my_class_type
,id
,p
,i
,q
,d
),
38 constructor_name(cid
), cons(c
), root(r
),
39 generating_list_special_forms(false),
40 cons_arg_ty(NOty
), has_destructor(false)
42 is_const
= (qualifiers
& QUALconst
) ? "const " : "";
43 is_list
= is_list_constructor(constructor_name
);
44 is_array
= is_array_constructor(constructor_name
);
47 DatatypeClass::~DatatypeClass() {}
49 //////////////////////////////////////////////////////////////////////////////
51 // Method to update the qualifiers and other
53 //////////////////////////////////////////////////////////////////////////////
54 void DatatypeHierarchy::get_info()
61 match (lookup_ty(datatype_name))
62 { DATATYPEty({ qualifiers = q, body = b, unit, arg, terms ... },_):
65 for (int i = 0; i < number_of_subclasses; i++)
66 { match (subclasses[i]->cons)
67 { ONEcons { inherit, qual, body ... }:
68 { // subclasses[i]->inherited_classes = inherit;
69 subclasses[i]->qualifiers |= qual;
70 subclasses[i]->class_body = body;
82 // Construct the inheritance list and fix it up if necessary
84 build_inheritance_list();
87 // Use inline methods if we are not in space saving mode
88 // or if the user specificately specified the inline qualifier
90 Bool must_inline
= (qualifiers
& QUALinline
);
91 Bool must_not_inline
= (qualifiers
& QUALextern
);
92 if (must_inline
&& must_not_inline
)
93 { error("%Ldatatype %s%V cannot be inline and external at the same time",
94 datatype_name
, parameters
97 if (must_inline
) inline_methods
= true;
98 else if (must_not_inline
) inline_methods
= false;
99 else inline_methods
= (! options
.save_space
);
102 // Use a variant tag if we have subclasses in our hierarchy
103 // and if the tag is not embedded into the pointer representation
105 has_variant_tag
= ((optimizations
& OPTtagless
) == 0);
107 has_destructor
= (qualifiers
& QUALvirtualdestr
) || (cons
&& is_array
);
110 //////////////////////////////////////////////////////////////////////////////
112 // Constructor for DatatypeHierarchy
114 //////////////////////////////////////////////////////////////////////////////
115 DatatypeHierarchy::DatatypeHierarchy
116 (Id id
, TyVars p
, Inherits i
, TyQual q
, TermDefs t
, Decls d
)
117 : DatatypeClass(DATATYPE_CLASS
,id
,
118 #line 104 "datatype.pcc"
119 #line 104 "datatype.pcc"
120 _d_a_t_a_t_y_p_eco_c_c_Q1
121 #line 104 "datatype.pcc"
122 #line 104 "datatype.pcc"
123 + id
,p
,i
,q
,d
,NOcons
,this),
124 datatype_name(id
), term_defs(t
), subclasses(0),
125 number_of_subclasses(0), datatype_ty(NOty
)
127 unit_constructors
= 0;
128 arg_constructors
= 0;
129 constructor_terms
= 0;
130 use_persist_base
= false;
135 // Build the class hierarchy
137 build_class_hierarchy();
141 DatatypeHierarchy::~DatatypeHierarchy()
143 delete [] subclasses
;
146 //////////////////////////////////////////////////////////////////////////////
148 // Method to build the class hierarchy given a datatype.
149 // We'll create a DatatypeClass object for each subclass.
151 //////////////////////////////////////////////////////////////////////////////
152 void DatatypeHierarchy::build_class_hierarchy()
154 // don't bother building the class hierarchy for views
155 if (is_view()) return;
157 // construct class hierarchy
159 #line 139 "datatype.pcc"
160 #line 174 "datatype.pcc"
162 Ty _V1
= lookup_ty(datatype_name
);
164 switch (_V1
->tag__
) {
165 case a_Ty::tag_TYCONty
: {
166 if (boxed(((Ty_TYCONty
*)_V1
)->_1
)) {
167 switch (((Ty_TYCONty
*)_V1
)->_1
->tag__
) {
168 case a_TyCon::tag_DATATYPEtycon
: {
169 #line 141 "datatype.pcc"
170 arity
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->unit
+ ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->arg
;
171 unit_constructors
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->unit
;
172 arg_constructors
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->arg
;
173 constructor_terms
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
;
174 optimizations
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->opt
;
176 ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->hierarchy
= this;
177 if (((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->arg
> 0) // build class hierarchy only if we have more than
179 { if (((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->opt
& OPTsubclassless
) // no subclass
180 { number_of_subclasses
= 0;
181 for (int i
= 0; i
< arity
; i
++)
182 { if (((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
[i
]->ty
!= NOty
)
183 { cons
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
[i
];
184 constructor_name
= cons
->name
;
185 is_list
= is_list_constructor(constructor_name
);
186 is_array
= is_array_constructor(constructor_name
);
187 class_body
= append(class_body
, ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
[i
]->body
);
192 { number_of_subclasses
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->arg
;
193 subclasses
= new DatatypeClass
* [number_of_subclasses
];
194 for (int i
= 0, j
= 0; i
< arity
; i
++)
195 { if (((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
[i
]->ty
!= NOty
)
196 { subclasses
[j
++] = build_one_subclass(((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
[i
]);
202 #line 172 "datatype.pcc"
209 default: { goto L1
; } break;
213 #line 174 "datatype.pcc"
214 #line 174 "datatype.pcc"
218 //////////////////////////////////////////////////////////////////////////////
220 // Method to build one subclass in the hierarchy.
222 //////////////////////////////////////////////////////////////////////////////
223 DatatypeClass
* DatatypeHierarchy::build_one_subclass(Cons cons
)
225 #line 183 "datatype.pcc"
226 #line 196 "datatype.pcc"
229 #line 185 "datatype.pcc"
230 return cons
->class_def
= new DatatypeClass(
233 Quark(mangle(datatype_name
),"_",mangle(cons
->name
)),
235 add_inherit(class_name
,parameters
,cons
->inherit
),
241 #line 195 "datatype.pcc"
243 #line 196 "datatype.pcc"
245 #line 196 "datatype.pcc"
248 #line 197 "datatype.pcc"
249 #line 197 "datatype.pcc"
253 //////////////////////////////////////////////////////////////////////////////
255 // Method to build the inheritance list of the class hierachy.
257 //////////////////////////////////////////////////////////////////////////////
258 void DatatypeHierarchy::build_inheritance_list()
260 if (qualifiers
& QUALrelation
) append_base_class("Fact");
261 if (qualifiers
& QUALrewritable
) append_base_class("TermObj");
262 if (qualifiers
& QUALpersistent
) append_base_class("PObject");
264 if (qualifiers
& QUALcollectable
)
265 { // Make sure we are only inheriting from one collectable object
266 // Make sure virtual inheritance is not used.
267 // Make sure that the collectable object is the first base class.
271 for_each (Inherit
, inh
, inherited_classes
)
272 { if((inh
->qualifiers
& QUALcollectable
) || is_gc_ty(inh
->super_class
))
275 { msg("%!%wcollectable object %T must be first base class\n",
276 inh
->loc(), inh
->super_class
);
279 if (inh
->qualifiers
& QUALvirtual
)
280 { msg("%!%wvirtual inheritance of %T may fail"
281 " with garbage collection\n",
282 inh
->loc(), inh
->super_class
);
287 { error("%Linheritance of multiple collectable object will fail\n");
290 { add_base_class("GCObject");
295 //////////////////////////////////////////////////////////////////////////////
297 // Method to generate a class constructor
299 //////////////////////////////////////////////////////////////////////////////
300 void DatatypeClass::gen_class_constructor(CodeGen
& C
, Tys tys
, DefKind k
)
302 ClassDefinition::gen_class_constructor(C
,tys
,k
);
305 { generating_list_special_forms
= true;
306 ClassDefinition::gen_class_constructor(C
,tys
,k
);
307 generating_list_special_forms
= false;
311 //////////////////////////////////////////////////////////////////////////////
313 // Method to generate the constructor parameters.
315 //////////////////////////////////////////////////////////////////////////////
316 void DatatypeClass::gen_class_constructor_parameters
317 (CodeGen
& C
, Tys tys
, DefKind k
)
319 Ty arg_ty
= cons_arg_ty
;
321 #line 267 "datatype.pcc"
322 #line 271 "datatype.pcc"
324 Ty _V2
= deref(arg_ty
);
326 switch (_V2
->tag__
) {
327 case a_Ty::tag_TYCONty
: {
328 if (boxed(((Ty_TYCONty
*)_V2
)->_1
)) {
330 switch ((int)((Ty_TYCONty
*)_V2
)->_1
) {
331 case ((int)TUPLEtycon
): {
332 if (((Ty_TYCONty
*)_V2
)->_2
) {
333 if (((Ty_TYCONty
*)_V2
)->_2
->_2
) {
334 if (((Ty_TYCONty
*)_V2
)->_2
->_2
->_2
) { goto L2
; } else {
336 #line 268 "datatype.pcc"
337 generating_list_special_forms
338 #line 268 "datatype.pcc"
341 #line 269 "datatype.pcc"
343 #line 269 "datatype.pcc"
344 #line 269 "datatype.pcc"
345 list_1_(((Ty_TYCONty
*)_V2
)->_2
->_1
)
346 #line 269 "datatype.pcc"
347 #line 269 "datatype.pcc"
349 #line 269 "datatype.pcc"
356 default: { goto L2
; } break;
360 default: { goto L2
; } break;
364 #line 271 "datatype.pcc"
365 #line 271 "datatype.pcc"
369 { case EXTERNAL_IMPLEMENTATION
:
370 case EXTERNAL_INSTANTIATION
:
371 param
= TYsimpleformal
; break;
373 param
= TYformal
; break;
375 C
.pr("%b", arg_ty
, cons
->name
, param
);
378 //////////////////////////////////////////////////////////////////////////////
380 // Method to generate the constructor initializers.
382 //////////////////////////////////////////////////////////////////////////////
383 void DatatypeClass::gen_class_constructor_initializers
384 (CodeGen
& C
, Tys tys
, DefKind k
)
387 #line 291 "datatype.pcc"
388 #line 312 "datatype.pcc"
391 #line 293 "datatype.pcc"
396 // First generate the tag initializer
397 if (root
->has_variant_tag
)
398 { if (k
== EXTERNAL_INSTANTIATION
)
399 C
.pr(" : %s%P(tag_%S)",
400 root
->class_name
, tys
, constructor_name
);
402 C
.pr(" : %s%V(tag_%S)",
403 root
->class_name
, parameters
, constructor_name
);
404 colon
= ""; comma
= ", ";
407 // Now generate the initializers for the arguments
408 gen_constructor_initializers(C
,tys
,k
,cons_arg_ty
,colon
,comma
);
410 #line 310 "datatype.pcc"
413 #line 312 "datatype.pcc"
414 #line 312 "datatype.pcc"
418 //////////////////////////////////////////////////////////////////////////////
420 // Method to generate the constructor initializers.
422 //////////////////////////////////////////////////////////////////////////////
423 void DatatypeClass::gen_constructor_initializers
424 (CodeGen
& C
, Tys tys
, DefKind k
, Ty ty
, Id colon
, Id comma
)
427 { C
.pr("%s%slen_(x__len_)", colon
, comma
);
428 colon
= ""; comma
= ", ";
429 ty
= mkarrayty(ty
,IDexp("len_"));
433 #line 329 "datatype.pcc"
434 #line 367 "datatype.pcc"
438 switch (_V3
->tag__
) {
439 case a_Ty::tag_TYCONty
: {
440 if (boxed(((Ty_TYCONty
*)_V3
)->_1
)) {
441 switch (((Ty_TYCONty
*)_V3
)->_1
->tag__
) {
442 case a_TyCon::tag_RECORDtycon
: {
443 #line 353 "datatype.pcc"
445 for (l
= ((TyCon_RECORDtycon
*)((Ty_TYCONty
*)_V3
)->_1
)->_1
, t
= ((Ty_TYCONty
*)_V3
)->_2
; l
&& t
; l
= l
->_2
, t
= t
->_2
) {
446 if (! is_array_ty(t
->_1
))
447 { C
.pr("%s%s%s(x_%s)", colon
, comma
, l
->_1
, l
->_1
);
448 colon
= ""; comma
= ", ";
452 #line 360 "datatype.pcc"
456 #line 362 "datatype.pcc"
457 if (! is_array_ty(_V3
))
458 { C
.pr("%s%s%S(x_%S)",
459 colon
, comma
, constructor_name
, constructor_name
);
460 colon
= ""; comma
= ", ";
463 #line 367 "datatype.pcc"
467 switch ((int)((Ty_TYCONty
*)_V3
)->_1
) {
468 case ((int)TUPLEtycon
): {
469 if (((Ty_TYCONty
*)_V3
)->_2
) {
470 #line 332 "datatype.pcc"
472 for_each(Ty
, t
, ((Ty_TYCONty
*)_V3
)->_2
)
473 { if (generating_list_special_forms
&& i
== 2)
474 { if (k
== EXTERNAL_INSTANTIATION
)
475 C
.pr("%s%s_%i((%s%P *)0)", colon
, comma
,
476 i
, root
->class_name
, tys
, i
);
478 C
.pr("%s%s_%i((%s%V *)0)", colon
, comma
,
479 i
, root
->class_name
, parameters
, i
);
480 colon
= ""; comma
= ", ";
483 { if (! is_array_ty(t
))
484 { C
.pr("%s%s_%i(x_%i)", colon
, comma
, i
, i
);
485 colon
= ""; comma
= ", ";
491 #line 351 "datatype.pcc"
494 default: { goto L3
; } break;
498 default: { goto L3
; } break;
502 #line 368 "datatype.pcc"
503 #line 368 "datatype.pcc"
507 //////////////////////////////////////////////////////////////////////////////
509 // Methods to generate body of a constructor
511 //////////////////////////////////////////////////////////////////////////////
512 void DatatypeClass::gen_class_constructor_body(CodeGen
& C
, Tys tys
, DefKind k
)
514 if (cons
== NOcons
) return;
518 { ty
= mkarrayty(ty
,IDexp("len_"));
521 // Now generate the initializers for array arguments
523 #line 386 "datatype.pcc"
524 #line 401 "datatype.pcc"
528 switch (_V4
->tag__
) {
529 case a_Ty::tag_TYCONty
: {
530 if (boxed(((Ty_TYCONty
*)_V4
)->_1
)) {
531 switch (((Ty_TYCONty
*)_V4
)->_1
->tag__
) {
532 case a_TyCon::tag_RECORDtycon
: {
533 #line 396 "datatype.pcc"
535 for(ls
= ((TyCon_RECORDtycon
*)((Ty_TYCONty
*)_V4
)->_1
)->_1
, ts
= ((Ty_TYCONty
*)_V4
)->_2
; ls
&& ts
; ls
= ls
->_2
, ts
= ts
->_2
)
536 { gen_array_initializer(C
,((Ty_TYCONty
*)_V4
)->_2
,k
,ls
->_1
,ts
->_1
,"x_");
539 #line 400 "datatype.pcc"
543 #line 401 "datatype.pcc"
544 gen_array_initializer(C
,tys
,k
,mangle(cons
->name
),_V4
,"x_");
545 #line 401 "datatype.pcc"
549 switch ((int)((Ty_TYCONty
*)_V4
)->_1
) {
550 case ((int)TUPLEtycon
): {
551 if (((Ty_TYCONty
*)_V4
)->_2
) {
552 #line 389 "datatype.pcc"
554 for_each(Ty
, t
, ((Ty_TYCONty
*)_V4
)->_2
)
555 { gen_array_initializer(C
,tys
,k
,index_of(i
),t
,"x");
559 #line 394 "datatype.pcc"
562 default: { goto L4
; } break;
566 default: { goto L4
; } break;
570 #line 402 "datatype.pcc"
571 #line 402 "datatype.pcc"
575 //////////////////////////////////////////////////////////////////////////////
577 // Methods to generate body of a constructor
579 //////////////////////////////////////////////////////////////////////////////
580 void DatatypeClass::gen_array_initializer
581 (CodeGen
& C
, Tys tys
, DefKind k
, Id exp
, Ty ty
, Id prefix
)
583 #line 412 "datatype.pcc"
584 #line 429 "datatype.pcc"
588 switch (_V5
->tag__
) {
589 case a_Ty::tag_TYCONty
: {
590 if (boxed(((Ty_TYCONty
*)_V5
)->_1
)) {
591 switch (((Ty_TYCONty
*)_V5
)->_1
->tag__
) {
592 case a_TyCon::tag_ARRAYtycon
: {
593 if (((Ty_TYCONty
*)_V5
)->_2
) {
594 if (((Ty_TYCONty
*)_V5
)->_2
->_2
) {
596 #line 414 "datatype.pcc"
598 "%^for (int i__ = 0; i__ < (%e); i__++)"
600 ((TyCon_ARRAYtycon
*)((Ty_TYCONty
*)_V5
)->_1
)->ARRAYtycon
);
602 { C
.pr("%^typedef %t ELEMENT_TYPE__;"
603 "%^new (%S + i__) ELEMENT_TYPE__ (%s%S[i__]);",
604 ((Ty_TYCONty
*)_V5
)->_2
->_1
, "", exp
, prefix
, exp
);
606 { C
.pr("%^%S[i__] = %s%S[i__];", exp
, prefix
, exp
);
611 #line 427 "datatype.pcc"
615 default: { goto L5
; } break;
619 default: { goto L5
; } break;
623 #line 429 "datatype.pcc"
624 #line 429 "datatype.pcc"
628 //////////////////////////////////////////////////////////////////////////////
630 // Methods to generate array initialization code.
632 //////////////////////////////////////////////////////////////////////////////
634 //////////////////////////////////////////////////////////////////////////////
636 // Methods to generate destructor code.
638 //////////////////////////////////////////////////////////////////////////////
639 void DatatypeClass::gen_class_destructor_body(CodeGen
& C
, Tys tys
, DefKind
)
641 if (is_array
&& cons
)
643 "%^for (int i__; i__ < len_; i__++)"
645 "%^typedef %t ELEMENT_TYPE;"
646 "%^(%S+i__)->~ELEMENT_TYPE();"
649 cons_arg_ty
, "", constructor_name
654 //////////////////////////////////////////////////////////////////////////////
656 // Methods to generate the forward declarations for a datatype.
657 // These include unit constructors for the class.
659 //////////////////////////////////////////////////////////////////////////////
660 void DatatypeHierarchy::generate_forward_declarations(CodeGen
& C
)
662 // don't generate code for views
663 if (is_view()) return;
666 generate_forward_class_declarations(C
);
667 generate_forward_constructor_declarations(C
);
669 // don't generate code for forward definitions
671 #line 474 "datatype.pcc"
672 #line 474 "datatype.pcc"
674 #line 474 "datatype.pcc"
675 #line 474 "datatype.pcc"
678 generate_unit_constructors(C
);
681 //////////////////////////////////////////////////////////////////////////////
683 // Method to generate forward class declarations.
684 // If the datatype is monomorphic, generate a typedef.
685 // Otherwise, generate a forward template declaration
688 //////////////////////////////////////////////////////////////////////////////
689 void DatatypeHierarchy::generate_forward_class_declarations(CodeGen
& C
)
690 { // Generate forward declarations only if we have at least one variant
691 if (arg_constructors
== 0 && term_defs
!=
692 #line 489 "datatype.pcc"
693 #line 489 "datatype.pcc"
695 #line 489 "datatype.pcc"
696 #line 489 "datatype.pcc"
701 "%^// Forward class definition for %s%V"
704 "%n#ifndef datatype_%S_defined"
705 "%n#define datatype_%S_defined",
706 datatype_name
, parameters
, datatype_name
, datatype_name
709 if (is_polymorphic())
710 { // Polymorphic datatypes
711 C
.pr("%^%Hclass %s;", parameters
, class_name
);
712 C
.pr("%n#define %s%v %s%s%V *\n",
713 datatype_name
, parameters
, is_const
, class_name
, parameters
);
715 { // Monomorphic datatypes
716 C
.pr("%^ class %s;", class_name
);
717 C
.pr("%^ typedef %s%s * %s;", is_const
, class_name
, datatype_name
);
720 C
.pr("%n#endif\n\n");
723 //////////////////////////////////////////////////////////////////////////////
725 // Method to generate forward declarations for datatype constructors.
727 //////////////////////////////////////////////////////////////////////////////
728 void DatatypeHierarchy::generate_forward_constructor_declarations(CodeGen
& C
)
733 //////////////////////////////////////////////////////////////////////////////
735 // Method to generate code for the definition of a datatype
737 //////////////////////////////////////////////////////////////////////////////
738 void DatatypeHierarchy::generate_datatype_definitions(CodeGen
& C
)
740 // don't generate code for views
741 if (is_view()) return;
743 // don't generate code for forward definitions
745 #line 536 "datatype.pcc"
746 #line 536 "datatype.pcc"
748 #line 536 "datatype.pcc"
749 #line 536 "datatype.pcc"
752 // If there are no argument constructors, don't generate code
755 if (arg_constructors
== 0)
757 gen_class_postdefinition(C
);
761 // Otherwise generate code for all the classes.
762 gen_class_definition(C
);
763 for (int i
= 0; i
< number_of_subclasses
; i
++)
764 subclasses
[i
]->gen_class_definition(C
);
766 // Generate datatype constructors
767 DefKind kind
= inline_methods
768 ? INLINE_IMPLEMENTATION
: INTERFACE_DEFINITION
;
770 generate_datatype_constructors(C
,
771 #line 556 "datatype.pcc"
772 #line 556 "datatype.pcc"
774 #line 556 "datatype.pcc"
775 #line 556 "datatype.pcc"
778 if (options
.inline_casts
== false || parameters
!=
779 #line 558 "datatype.pcc"
780 #line 558 "datatype.pcc"
782 #line 558 "datatype.pcc"
783 #line 558 "datatype.pcc"
785 generate_downcasting_functions(C
);
790 //////////////////////////////////////////////////////////////////////////////
792 // Method to generate the unit constructor names.
793 // If there are no argument constructors, represent the constructors as
794 // enum's. Otherwise, represent them as #define constants.
796 //////////////////////////////////////////////////////////////////////////////
797 void DatatypeHierarchy::generate_unit_constructors(CodeGen
& C
)
798 { if (unit_constructors
== 0) return;
799 if (arg_constructors
== 0)
800 generate_constructor_tags(C
,"","", unit_constructors
, constructor_terms
);
802 generate_define_tags(C
,unit_constructors
,constructor_terms
);
806 //////////////////////////////////////////////////////////////////////////////
808 // Method to generate the constructor tags as enum's.
809 // Constructor tags are used to represent unit constructors
812 //////////////////////////////////////////////////////////////////////////////
813 void DatatypeHierarchy::generate_constructor_tags
814 (CodeGen
& C
, Id enum_prefix
, Id tag_prefix
, int n
, Cons terms
[])
815 { C
.pr("%^enum %s%s {%+", enum_prefix
, datatype_name
);
817 for (int i
= 0; i
< n
; i
++)
818 { if (comma
) C
.pr (", ");
819 if (i
% 3 == 0) C
.pr("%^");
820 C
.pr("%s%S = %i", tag_prefix
, terms
[i
]->name
, tag_of(terms
[i
]));
826 //////////////////////////////////////////////////////////////////////////////
828 // Method to generate the unit constructor tags as #define constants.
829 // This is necessary if we have both unit and argument constructors
830 // for a type. If polymorphic types are used, the #define constants
831 // are not given a type.
833 //////////////////////////////////////////////////////////////////////////////
834 void DatatypeHierarchy::generate_define_tags(CodeGen
& C
, int n
, Cons terms
[])
835 { for (int i
= 0; i
< n
; i
++)
836 { if (is_polymorphic())
837 C
.pr("%n# define %S %i", terms
[i
]->name
, tag_of(terms
[i
]));
839 C
.pr("%n# define %S (%s)%i",
840 terms
[i
]->name
, datatype_name
, tag_of(terms
[i
]));
844 //////////////////////////////////////////////////////////////////////////////
846 // Method to generate datatype constructor functions for a datatype.
847 // Datatype constructor functions are just external functions.
849 //////////////////////////////////////////////////////////////////////////////
850 void DatatypeHierarchy::generate_datatype_constructors
851 (CodeGen
& C
, Tys tys
, DefKind kind
)
855 "%^// Datatype constructor functions for %s%V"
858 datatype_name
, parameters
);
859 generate_datatype_constructor(C
,tys
,kind
);
860 for (int i
= 0; i
< number_of_subclasses
; i
++)
861 { subclasses
[i
]->generate_datatype_constructor(C
,tys
,kind
);
865 //////////////////////////////////////////////////////////////////////////////
867 // Method to generate a datatype constructor function.
869 //////////////////////////////////////////////////////////////////////////////
870 void DatatypeClass::generate_datatype_constructor
871 (CodeGen
& C
, Tys tys
, DefKind kind
)
873 // No datatype descriptor, then no datatype constructor function
874 if (cons
== NOcons
) return;
879 { case INLINE_IMPLEMENTATION
: prefix
= "inline "; break;
880 case INTERFACE_DEFINITION
:
881 case EXTERNAL_DEFINITION
: prefix
= "extern "; break;
882 case EXTERNAL_IMPLEMENTATION
:
883 case EXTERNAL_INSTANTIATION
: prefix
= ""; break;
886 // Generate special form constructors for lists and vectors
887 int special_forms
= 1;
888 if (is_list
) special_forms
= 2;
889 else if (is_array
) special_forms
= options
.max_vector_len
+ 2;
891 #line 664 "datatype.pcc"
892 #line 664 "datatype.pcc"
894 #line 664 "datatype.pcc"
895 #line 664 "datatype.pcc"
898 #line 665 "datatype.pcc"
899 #line 665 "datatype.pcc"
901 #line 665 "datatype.pcc"
902 #line 665 "datatype.pcc"
905 for (int form
= 1; form
<= special_forms
; form
++)
907 Ty formals_ty
= cons_arg_ty
;
908 Ty actuals_ty
= cons_arg_ty
;
909 Id formals_name
= constructor_name
;
911 // If it is a list special form, fake the second argument
912 if (is_list
&& form
== 2)
914 #line 675 "datatype.pcc"
915 #line 679 "datatype.pcc"
917 Ty _V6
= deref(formals_ty
);
919 switch (_V6
->tag__
) {
920 case a_Ty::tag_TYCONty
: {
921 if (boxed(((Ty_TYCONty
*)_V6
)->_1
)) {
923 #line 678 "datatype.pcc"
924 bug("%LDatatypeClass::generate_datatype_constructor: %T\n",
926 #line 679 "datatype.pcc"
928 switch ((int)((Ty_TYCONty
*)_V6
)->_1
) {
929 case ((int)TUPLEtycon
): {
930 if (((Ty_TYCONty
*)_V6
)->_2
) {
931 if (((Ty_TYCONty
*)_V6
)->_2
->_2
) {
932 if (((Ty_TYCONty
*)_V6
)->_2
->_2
->_2
) { goto L6
; } else {
933 #line 677 "datatype.pcc"
934 formals_ty
= actuals_ty
= mktuplety(
935 #line 677 "datatype.pcc"
936 #line 677 "datatype.pcc"
937 list_1_(((Ty_TYCONty
*)_V6
)->_2
->_1
)
938 #line 677 "datatype.pcc"
939 #line 677 "datatype.pcc"
941 #line 677 "datatype.pcc"
946 default: { goto L6
; } break;
950 default: { goto L6
; } break;
954 #line 680 "datatype.pcc"
955 #line 680 "datatype.pcc"
959 // If it is an array special form, fake the parameter arguments
960 if (is_array
&& form
>= 2)
963 #line 686 "datatype.pcc"
964 #line 686 "datatype.pcc"
965 list_1_(cons_arg_ty
,params
)
966 #line 686 "datatype.pcc"
967 #line 686 "datatype.pcc"
969 labels
= append(labels
,
970 #line 687 "datatype.pcc"
971 #line 687 "datatype.pcc"
972 list_1_(index_of((form
- 2)))
973 #line 687 "datatype.pcc"
974 #line 687 "datatype.pcc"
977 formals_ty
= mkrecordty(labels
,params
,false);
978 formals_name
= mangle(constructor_name
);
982 { case EXTERNAL_INSTANTIATION
:
983 case EXTERNAL_DEFINITION
:
984 C
.pr("%^%s%s%P * %S %b",
985 prefix
, root
->class_name
, tys
, constructor_name
,
986 formals_ty
, formals_name
, TYsimpleformal
);
989 C
.pr("%^%H%s%s%V * %S %b",
991 prefix
, root
->class_name
, parameters
, constructor_name
,
992 formals_ty
, formals_name
, TYformal
);
996 // Don't generate code for interface definitions
997 if (kind
== INTERFACE_DEFINITION
||
998 kind
== EXTERNAL_DEFINITION
) { C
.pr(";"); continue; }
1003 // Generate a temporary array
1005 if (is_array
&& form
>= 2)
1006 { C
.pr("%^const int x__len_ = %i;", form
- 2);
1007 C
.pr("%^%t x_%S[%i];", cons_arg_ty
, "", constructor_name
, form
- 2);
1008 for (int i
= 0; i
< form
- 2; i
++)
1009 C
.pr("%^x_%S[%i] = x__%i;", constructor_name
,i
,i
+1);
1015 // In the tagged pointer representation, the variant tag is embedded
1016 // within the data address.
1018 if (root
->optimizations
& OPTtaggedpointer
)
1020 { case EXTERNAL_INSTANTIATION
:
1021 C
.pr ("(%s%P*)((unsigned long)(", root
->class_name
, tys
);
1024 C
.pr ("(%s%V*)((unsigned long)(", root
->class_name
, parameters
);
1030 // In the unboxed representation, the argument is embedded within
1033 if (root
->optimizations
& OPTunboxed
)
1035 int tag_bits
= DatatypeCompiler::max_embedded_bits
;
1036 for (int i
= root
->unit_constructors
;
1037 i
>= DatatypeCompiler::max_embedded_tags
; i
>>= 1) tag_bits
++;
1038 C
.pr ("(%s *)(((unsigned long)%b<<(%i+1))|%i)",
1039 root
->class_name
, actuals_ty
, constructor_name
, TYactual
,
1040 tag_bits
, (1 << tag_bits
));
1044 // The usual boxed implementation
1050 { case EXTERNAL_INSTANTIATION
:
1052 C
.pr ("(sizeof(%s%P)+sizeof(%t)*x__len_) ",
1053 class_name
, tys
, cons_arg_ty
, "");
1054 C
.pr ("%s%P %b", class_name
, tys
, actuals_ty
,
1055 constructor_name
, TYactual
);
1059 C
.pr ("(sizeof(%s%V)+sizeof(%t)*x__len_) ",
1060 class_name
, parameters
, cons_arg_ty
, "");
1061 C
.pr ("%s%V %b", class_name
, parameters
, actuals_ty
,
1062 constructor_name
, TYactual
);
1067 if (root
->optimizations
& OPTtaggedpointer
)
1069 { case EXTERNAL_INSTANTIATION
:
1070 C
.pr (")|%s%P::tag_%S)",
1071 root
->class_name
, tys
, constructor_name
); break;
1073 C
.pr (")|%s%V::tag_%S)",
1074 root
->class_name
, parameters
, constructor_name
); break;
1083 //////////////////////////////////////////////////////////////////////////////
1085 // Method to generate code before the interface
1087 //////////////////////////////////////////////////////////////////////////////
1088 void DatatypeClass::gen_class_predefinition(CodeGen
& C
)
1091 #line 802 "datatype.pcc"
1092 #line 820 "datatype.pcc"
1095 #line 804 "datatype.pcc"
1096 cons_arg_ty
= cons
->ty
;
1099 "%^// Class for datatype constructor %s%V::%s"
1102 root
->datatype_name
, parameters
, cons
->name
);
1104 #line 811 "datatype.pcc"
1106 #line 813 "datatype.pcc"
1110 "%^// Base class for datatype %s%V"
1113 root
->datatype_name
, parameters
);
1115 #line 820 "datatype.pcc"
1118 #line 821 "datatype.pcc"
1119 #line 821 "datatype.pcc"
1123 //////////////////////////////////////////////////////////////////////////////
1125 // Method to generate the interface of a class
1127 //////////////////////////////////////////////////////////////////////////////
1128 void DatatypeClass::gen_class_interface(CodeGen
& C
)
1130 // Generate the internal representation
1131 // if there is a constructor descripter and the
1132 // argument is not represented in unboxed form.
1133 C
.pr("%-%^public:%+");
1135 #line 835 "datatype.pcc"
1136 #line 843 "datatype.pcc"
1139 #line 837 "datatype.pcc"
1140 if ((cons
->opt
& OPTunboxed
) == 0)
1141 { C
.pr ("%#%^%b\n", cons
->location
->begin_line
, cons
->location
->file_name
,
1142 cons
->ty
, cons
->name
, TYbody
);
1145 #line 841 "datatype.pcc"
1148 #line 843 "datatype.pcc"
1149 #line 843 "datatype.pcc"
1152 DefKind kind
= root
->inline_methods
1153 ? INLINE_IMPLEMENTATION
: INTERFACE_DEFINITION
;
1155 // Generate the constructor of the class
1157 { gen_class_constructor(C
,
1158 #line 850 "datatype.pcc"
1159 #line 850 "datatype.pcc"
1161 #line 850 "datatype.pcc"
1162 #line 850 "datatype.pcc"
1166 // Generate the destructor of the class
1167 if ((root
->qualifiers
& QUALvirtualdestr
) ||
1168 (qualifiers
& QUALvirtualdestr
) ||
1170 gen_class_destructor(C
,
1171 #line 857 "datatype.pcc"
1172 #line 857 "datatype.pcc"
1174 #line 857 "datatype.pcc"
1175 #line 857 "datatype.pcc"
1178 // Generate the method declarations for all different types
1179 // of extra functionality
1180 if (root
->qualifiers
& QUALpersistent
) generate_persistence_interface(C
);
1181 //if (root->qualifiers & QUALvariable) generate_logic_interface(C);
1182 if (root
->qualifiers
& QUALcollectable
) generate_gc_interface(C
);
1183 if (root
->qualifiers
& QUALrelation
) generate_inference_interface(C
);
1186 //////////////////////////////////////////////////////////////////////////////
1188 // Method to generate the interface of a base class
1190 //////////////////////////////////////////////////////////////////////////////
1191 void DatatypeHierarchy::gen_class_interface(CodeGen
& C
)
1193 // Generate tags for arg constructors
1194 if (arg_constructors
> 1)
1195 { C
.pr("%-%^public:%+");
1196 generate_constructor_tags(C
,"Tag_","tag_",
1197 arg_constructors
, constructor_terms
+ unit_constructors
);
1200 // Generate a variant tag and a base class constructor for it
1201 // only if we have a variant_tag representation.
1202 if (has_variant_tag
)
1203 { C
.pr("%-%^public:%+"
1204 "%^const Tag_%s tag__; // variant tag"
1206 "%^inline %s(Tag_%s t__) : tag__(t__) {%&}",
1207 datatype_name
, class_name
, datatype_name
, constructor_code
1211 // Generate the untagging functions
1212 generate_untagging_member_functions(C
);
1214 DatatypeClass::gen_class_interface(C
);
1217 //////////////////////////////////////////////////////////////////////////////
1219 // Method to generate untagging functions for a datatype class.
1220 // Three untagging functions are generated:
1221 // int untag() const --- returns the variant tag of the class
1222 // friend int untag(type * x) -- return a tag for the object x
1223 // so that each variant (boxed or unboxed)
1224 // gets a unique tag.
1225 // friend int boxed(type * x) -- returns true if object is boxed.
1227 //////////////////////////////////////////////////////////////////////////////
1228 void DatatypeHierarchy::generate_untagging_member_functions(CodeGen
& C
)
1230 ///////////////////////////////////////////////////////////////////////////
1231 // Generate untagger
1232 ///////////////////////////////////////////////////////////////////////////
1233 // if (has_variant_tag)
1234 // C.pr("%^inline int untag() const { return tag__; }");
1237 void DatatypeHierarchy::generate_untagging_functions(CodeGen
& C
)
1240 if (arg_constructors
== 0) return;
1242 ///////////////////////////////////////////////////////////////////////////
1243 // Generate boxed() predicate
1244 ///////////////////////////////////////////////////////////////////////////
1245 if (unit_constructors
== 0)
1246 C
.pr("%^%Hinline int boxed(const %s%V *) { return 1; }",
1247 parameters
, class_name
, parameters
);
1248 else if (unit_constructors
== 1)
1249 C
.pr("%^%Hinline int boxed(const %s%V * x) { return x != 0; }",
1250 parameters
, class_name
, parameters
);
1252 C
.pr("%^%Hinline int boxed(const %s%V * x)"
1253 " { return (unsigned long)x >= %i; }",
1254 parameters
, class_name
, parameters
, unit_constructors
);
1256 ///////////////////////////////////////////////////////////////////////////
1257 // Generate function that untags the pointer if
1258 // the tags are embedded into a pointer.
1259 ///////////////////////////////////////////////////////////////////////////
1260 if (optimizations
& OPTtaggedpointer
)
1263 "%^// Embbeded tag extraction functions"
1266 "%^%Hinline int untagp(const %s%V * x)"
1267 "%^ { return (unsigned long)x & %i; }"
1268 "%^%Hinline %s%s%V * derefp(const %s%V * x)"
1269 "%^ { return (%s%s%V*)((unsigned long)x & ~%i); }",
1270 parameters
, class_name
, parameters
,
1271 DatatypeCompiler::max_embedded_tags
- 1,
1272 parameters
,is_const
,class_name
, parameters
, class_name
, parameters
,
1273 is_const
, class_name
, parameters
,
1274 DatatypeCompiler::max_embedded_tags
- 1);
1277 ///////////////////////////////////////////////////////////////////////////
1278 // Generate a generic untag function that works on all boxed
1279 // and unboxed variants.
1280 ///////////////////////////////////////////////////////////////////////////
1281 if (unit_constructors
== 0) {
1282 // No unboxed variants.
1283 if (optimizations
& OPTtaggedpointer
)
1284 C
.pr("%^%Hinline int untag(const %s%V * x) { return untagp(x); }",
1285 parameters
, class_name
, parameters
);
1286 else if (arg_constructors
== 1)
1287 C
.pr("%^%Hinline int untag(const %s%V *) { return 0; }",
1288 parameters
, class_name
, parameters
);
1290 C
.pr("%^%Hinline int untag(const %s%V * x) { return x->tag__; }",
1291 parameters
, class_name
, parameters
);
1292 } else if (unit_constructors
== 1) {
1293 // Only one unboxed variants.
1294 if (optimizations
& OPTtaggedpointer
)
1295 C
.pr("%^%Hinline int untag(const %s%V * x) "
1296 "{ return x ? untagp(x)+1 : 0; }",
1297 parameters
, class_name
, parameters
);
1298 else if (arg_constructors
== 1)
1299 C
.pr("%^%Hinline int untag(const %s%V * x) { return x ? 1 : 0; }",
1300 parameters
, class_name
, parameters
);
1302 C
.pr("%^%Hinline int untag(const %s%V * x)"
1303 " { return x ? (x->tag__+1) : 0; }",
1304 parameters
, class_name
, parameters
);
1306 // More than one unboxed variants.
1307 if (optimizations
& OPTtaggedpointer
)
1308 C
.pr("%^%Hinline int untag(const %s%V * x)"
1309 " { return boxed(x) ? untagp(x) + %i : (int)x; }",
1310 parameters
, class_name
, parameters
, unit_constructors
);
1311 else if (arg_constructors
== 1)
1312 C
.pr("%^%Hinline int untag(const %s%V * x)"
1313 " { return boxed(x) ? %i : (int)x; }",
1314 parameters
, class_name
, parameters
, 1 + unit_constructors
);
1316 C
.pr("%^%Hinline int untag(const %s%V * x)"
1317 " { return boxed(x) ? x->tag__ + %i : (int)x; }",
1318 parameters
, class_name
, parameters
, unit_constructors
);
1322 //////////////////////////////////////////////////////////////////////////////
1324 // Method to generate downcasting functions
1326 //////////////////////////////////////////////////////////////////////////////
1327 void DatatypeHierarchy::generate_downcasting_functions(CodeGen
& C
)
1331 "%^// Downcasting functions for %s%V"
1334 datatype_name
, parameters
);
1335 for (int i
= 0; i
< number_of_subclasses
; i
++)
1336 { DatatypeClass
* D
= subclasses
[i
];
1337 C
.pr("%^%Hinline %s%V * _%S(const %s%V * _x_) { return (%s%V *)_x_; }",
1338 parameters
, D
->class_name
, parameters
, D
->constructor_name
,
1339 class_name
, parameters
, D
->class_name
, parameters
);
1343 //////////////////////////////////////////////////////////////////////////////
1345 // Method to generate code right after the main class definition.
1347 //////////////////////////////////////////////////////////////////////////////
1348 void DatatypeClass::gen_class_postdefinition(CodeGen
& C
)
1352 // Interfaces for extra features
1353 if (root
->qualifiers
& QUALprintable
) generate_print_interface(C
);
1356 //////////////////////////////////////////////////////////////////////////////
1358 // Method to generate code right after the main class definition.
1360 //////////////////////////////////////////////////////////////////////////////
1361 void DatatypeHierarchy::gen_class_postdefinition(CodeGen
& C
)
1363 generate_untagging_functions(C
);
1364 DatatypeClass::gen_class_postdefinition(C
);
1367 #line 1048 "datatype.pcc"
1369 ------------------------------- Statistics -------------------------------
1370 Merge matching rules = yes
1371 Number of DFA nodes merged = 156
1372 Number of ifs generated = 27
1373 Number of switches generated = 14
1374 Number of labels = 6
1375 Number of gotos = 27
1376 Adaptive matching = enabled
1377 Fast string matching = disabled
1378 Inline downcasts = enabled
1379 --------------------------------------------------------------------------