typename fix
[prop.git] / prop-src / instance.pcc
blobea2f23b4513e2ccf700c6e7ebf3158dcdaa5b14d
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 //  This file implements datatype instantiations
4 //
5 //////////////////////////////////////////////////////////////////////////////
6 #include "datatype.ph"
7 #include "ast.ph"
8 #include "ir.ph"
9 #include "type.h"
10 #include "datagen.h"
11 #include "options.h"
13 //////////////////////////////////////////////////////////////////////////////
15 //  Method to instantiate a list of datatypes
17 //////////////////////////////////////////////////////////////////////////////
18 void DatatypeCompiler::instantiate_datatypes(Bool external, Tys tys)
19 {  
20    if (! external)
21    {  for_each (Ty, ty, tys) instantiate_datatypes(true,ty); }
22    {  for_each (Ty, ty, tys) instantiate_datatypes(external,ty); }
25 //////////////////////////////////////////////////////////////////////////////
27 //  Method to instantiate one datatype 
29 //////////////////////////////////////////////////////////////////////////////
30 void DatatypeCompiler::instantiate_datatypes(Bool e, Ty ty)
31 {  match (deref_all(ty))
32    {  my_ty as DATATYPEty({ id, hierarchy, polyty ... },arg_types):
33       {  if (hierarchy == 0)
34          {  error ("%Ldefinition of datatype %T is unknown\n", ty); 
35          } else
36          {  if (! is_ground(my_ty))
37               error("%Lmissing parameters in instantiation of datatype %T\n", 
38                     ty);
39             hierarchy->generate_datatype_instantiations(*this,arg_types,e);
40          }
41       }
42    |  ty: { error ("%Ldefinition of %T is not found\n", ty); }
43    }
46 //////////////////////////////////////////////////////////////////////////////
48 //  Method to instantiate a datatype
50 //////////////////////////////////////////////////////////////////////////////
51 void DatatypeHierarchy::generate_datatype_instantiations
52    (CodeGen& C, Tys argument_types, Bool interface)
54    if (is_view()) return;
56    get_info();
57    Id msg = interface ? "Interface specification" : "Instantiation";
58    C.pr("%^%/"
59         "%^//"
60         "%^// %s of datatype %s%P"
61         "%^//"
62         "%^%/"
63         "%#",
64         msg, datatype_name, argument_types, line, file
65        );
66    DefKind k = interface ? EXTERNAL_DEFINITION : EXTERNAL_INSTANTIATION;
68    gen_class_instantiation(C, argument_types, k);
69    gen_class_implementation(C, argument_types, k);
70    for (int i = 0; i < number_of_subclasses; i++)
71       subclasses[i]->gen_class_implementation(C, argument_types, k);
72    C.pr("\n\n");
75 //////////////////////////////////////////////////////////////////////////////
77 //  Method to generate the implementation of a class
79 //////////////////////////////////////////////////////////////////////////////
80 void DatatypeClass::gen_class_implementation(CodeGen& C, Tys tys, DefKind k)
82    ///////////////////////////////////////////////////////////////////////////
83    //
84    // Compute the new argument types of the constructors
85    //
86    ///////////////////////////////////////////////////////////////////////////
87    match (cons)
88    {  ONEcons { ty, cons_ty ... }:
89       {  switch (k)
90          {  case EXTERNAL_INSTANTIATION: 
91             case EXTERNAL_DEFINITION: 
92                cons_arg_ty = apply_ty(cons_ty,tys); break;
93             default:
94                cons_arg_ty = ty; break;
95          }
96       }
97    |  NOcons:
98       {  cons_arg_ty = NOty; }
99    }
100    ///////////////////////////////////////////////////////////////////////////
101    //
102    // Generate the constructors, destructors, and datatype constructor
103    // function if inline methods are not used.
104    //
105    ///////////////////////////////////////////////////////////////////////////
106    if (! root->inline_methods) 
107    {  
108       // Generate the constructor of the class
109       if (cons != NOcons && (k != EXTERNAL_DEFINITION || tys != #[])) 
110          gen_class_constructor(C, tys, k);
112       // Generate the destructor of the class
113       if ((k != EXTERNAL_DEFINITION || tys != #[]) &&
114           ((root->qualifiers & QUALvirtualdestr) ||
115            (qualifiers & QUALvirtualdestr) ||
116            (cons && is_array)))
117          gen_class_destructor(C, tys, k);
119       if (cons != NOcons && (k != EXTERNAL_DEFINITION || tys != #[])) 
120          generate_datatype_constructor(C, tys, k);
121    }
123    ///////////////////////////////////////////////////////////////////////////
124    //
125    // Generate the implementation methods for various features
126    //
127    ///////////////////////////////////////////////////////////////////////////
128    if (root->qualifiers & QUALpersistent && k == EXTERNAL_INSTANTIATION)
129        generate_persistence_implementation(C,tys,k);
130    //if (root->qualifiers & QUALvariable && k == EXTERNAL_INSTANTIATION)
131    //    generate_logic_implementation(C,tys,k);
132    if (root->qualifiers & QUALcollectable && k == EXTERNAL_INSTANTIATION)
133        generate_gc_implementation(C,tys,k);
134    if (root->qualifiers & QUALrelation && k == EXTERNAL_INSTANTIATION)
135        generate_inference_implementation(C,tys,k);
136    if (root->qualifiers & QUALprintable)
137        generate_print_implementation(C,tys,k);
140 void DatatypeHierarchy::gen_class_implementation(CodeGen& C, Tys tys,DefKind k)
142    DatatypeClass::gen_class_implementation(C,tys,k);
145 //////////////////////////////////////////////////////////////////////////////
147 //  Method to generate template instantiation of a class
149 //////////////////////////////////////////////////////////////////////////////
150 void DatatypeClass::gen_class_instantiation(CodeGen& C, Tys tys, DefKind k)
152    C.pr("%^template class %S%P;", class_name, tys);
154    if (cons != NOcons && root->inline_methods)
155    {  // Constructor function
156       C.pr("%^template %S%P * %S%b;", 
157            root->class_name, tys, 
158            constructor_name, cons_arg_ty, cons->name, TYsimpleformal);
159       // List constructor 
160       if (is_list)
161       {  C.pr("%^template %S%P * %S%b;", 
162               root->class_name, tys, constructor_name,
163               component_ty(cons_arg_ty,1), cons->name, TYsimpleformal);
164       }
165       // Array constructor
166    }
169 //////////////////////////////////////////////////////////////////////////////
171 //  Method to generate template instantiation of a class hierarchy
173 //////////////////////////////////////////////////////////////////////////////
174 void DatatypeHierarchy::gen_class_instantiation(CodeGen& C, Tys tys, DefKind k)
175 {  if (tys != #[] && k == EXTERNAL_INSTANTIATION && arg_constructors > 0)
176    {  C.pr("%n#ifdef PROP_EXPLICIT_TEMPLATE_INSTANTIATION"); 
177       DatatypeClass::gen_class_instantiation(C,tys,k);
178       for (int i = 0; i < number_of_subclasses; i++)
179       {  subclasses[i]->gen_class_instantiation(C,tys,k);
180       }
181       gen_untagging_function_instantiation(C,tys,k);
182       gen_downcasting_function_instantiation(C,tys,k);
183       C.pr("%n#endif /* PROP_EXPLICIT_TEMPLATE_INSTANTIATION */");
184    }
187 //////////////////////////////////////////////////////////////////////////////
189 //  Method to generate template instantiation of untagging functions.
191 //////////////////////////////////////////////////////////////////////////////
192 void DatatypeHierarchy::gen_untagging_function_instantiation
193    (CodeGen& C, Tys tys, DefKind k)
195    C.pr("%^template int boxed(const %S%P *);"
196         "%^template int untag(const %S%P *);", 
197         class_name, tys, class_name, tys);
198    if (optimizations & OPTtaggedpointer)
199    {  C.pr("%^template int untagp(const %S%P *);"
200            "%^template %S%P * derefp(const %S%P *);",
201            class_name, tys, class_name, tys, class_name, tys);
202    }
205 //////////////////////////////////////////////////////////////////////////////
207 //  Method to generate template instantiation of downcasting functions.
209 //////////////////////////////////////////////////////////////////////////////
210 void DatatypeHierarchy::gen_downcasting_function_instantiation
211    (CodeGen& C, Tys tys, DefKind k)
212 {  
213    if (options.inline_casts == false || parameters != #[])
214    {  for (int i = 0; i < number_of_subclasses; i++)
215       {  DatatypeClass * D = subclasses[i];
216          C.pr("%^template %S%P * _%S(const %S%P *);", 
217               root->class_name, tys, D->constructor_name, class_name, tys);
218       }
219    }