1 /*****
2  * varinit.cc
3  * Andy Hammerlindl 2005/07/01
4  *
5  * Variable initializer are syntax that finish code such as
6  *   int var = ...
7  * As such, they are translated to yield a certain type, the type of the
8  * variable.  Expressions are a special case that can be translated without an
9  * associated variable or its type.
10  *****/
11 
12 #include "varinit.h"
13 #include "coenv.h"
14 #include "runtime.h"
15 #include "runarray.h"
16 
17 namespace absyntax {
18 
19 using namespace types;
20 using namespace trans;
21 
prettyprint(ostream & out,Int indent)22 void definit::prettyprint(ostream &out, Int indent)
23 {
24   prettyname(out, "definit",indent);
25 }
26 
transToType(coenv & e,types::ty * target)27 void definit::transToType(coenv &e, types::ty *target)
28 {
29   if (target->kind != ty_error) {
30     access *a=e.e.lookupInitializer(target);
31 
32     if (a)
33       a->encode(CALL, getPos(), e.c);
34     else {
35       em.error(getPos());
36       em << "no default initializer for type '" << *target << "'";
37     }
38   }
39 }
40 
prettyprint(ostream & out,Int indent)41 void arrayinit::prettyprint(ostream &out, Int indent)
42 {
43   prettyname(out, "arrayinit",indent);
44 
45   for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
46     (*p)->prettyprint(out, indent+2);
47   if (rest)
48     rest->prettyprint(out, indent+1);
49 }
50 
transMaker(coenv & e,Int size,bool rest)51 void arrayinit::transMaker(coenv &e, Int size, bool rest) {
52   // Push the number of cells and call the array maker.
53   e.c.encode(inst::intpush, size);
54   e.c.encode(inst::builtin, rest ? run::newAppendedArray :
55              run::newInitializedArray);
56 }
57 
transToType(coenv & e,types::ty * target)58 void arrayinit::transToType(coenv &e, types::ty *target)
59 {
60   types::ty *celltype;
61   if (target->kind != types::ty_array) {
62     em.error(getPos());
63     em << "array initializer used for non-array";
64     celltype = types::primError();
65   }
66   else {
67     celltype = ((types::array *)target)->celltype;
68   }
69 
70   // Push the values on the stack.
71   for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
72     (*p)->transToType(e, celltype);
73 
74   if (rest)
75     rest->transToType(e, target);
76 
77   transMaker(e, (Int)inits.size(), (bool)rest);
78 }
79 
80 } // namespace absyntax
81