comparison dmdscript_tango/functiondefinition.d @ 0:55c2951c07be

initial, files origin, premoved tree
author saaadel
date Sun, 24 Jan 2010 12:34:47 +0200
parents
children 8363a4bf6a8f
comparison
equal deleted inserted replaced
-1:000000000000 0:55c2951c07be
1
2 /* Digital Mars DMDScript source code.
3 * Copyright (c) 2000-2002 by Chromium Communications
4 * D version Copyright (c) 2004-2007 by Digital Mars
5 * All Rights Reserved
6 * written by Walter Bright
7 * www.digitalmars.com
8 * Use at your own risk. There is no warranty, express or implied.
9 * License for redistribution is by the GNU General Public License in gpl.txt.
10 *
11 * A binary, non-exclusive license for commercial use can be
12 * purchased from www.digitalmars.com/dscript/buy.html.
13 *
14 * DMDScript is implemented in the D Programming Language,
15 * www.digitalmars.com/d/
16 *
17 * For a C++ implementation of DMDScript, including COM support,
18 * see www.digitalmars.com/dscript/cppscript.html.
19 */
20
21
22 module dmdscript.functiondefinition;
23
24 import std.stdio;
25
26 import dmdscript.script;
27 import dmdscript.identifier;
28 import dmdscript.statement;
29 import dmdscript.dfunction;
30 import dmdscript.scopex;
31 import dmdscript.irstate;
32 import dmdscript.opcodes;
33 import dmdscript.ddeclaredfunction;
34 import dmdscript.symbol;
35 import dmdscript.dobject;
36 import dmdscript.ir;
37 import dmdscript.errmsgs;
38 import dmdscript.value;
39 import dmdscript.property;
40
41 /* ========================== FunctionDefinition ================== */
42
43 class FunctionDefinition : TopStatement
44 {
45 // Maybe the following two should be done with derived classes instead
46 int isglobal; // !=0 if the global anonymous function
47 int isanonymous; // !=0 if anonymous function
48 int iseval; // !=0 if eval function
49
50 Identifier* name; // null for anonymous function
51 Identifier*[] parameters; // array of Identifier's
52 TopStatement[] topstatements; // array of TopStatement's
53
54 Identifier*[] varnames; // array of Identifier's
55 FunctionDefinition[] functiondefinitions;
56 FunctionDefinition enclosingFunction;
57 int nestDepth;
58 int withdepth; // max nesting of ScopeStatement's
59
60 SymbolTable *labtab; // symbol table for LabelSymbol's
61
62 IR *code;
63 uint nlocals;
64
65
66 this(TopStatement[] topstatements)
67 {
68 super(0);
69 st = FUNCTIONDEFINITION;
70 this.isglobal = 1;
71 this.topstatements = topstatements;
72 }
73
74 this(Loc loc, int isglobal,
75 Identifier *name, Identifier*[] parameters,
76 TopStatement[] topstatements)
77 {
78 super(loc);
79
80 //writef("FunctionDefinition('%ls')\n", name ? name.string : L"");
81 st = FUNCTIONDEFINITION;
82 this.isglobal = isglobal;
83 this.name = name;
84 this.parameters = parameters;
85 this.topstatements = topstatements;
86 }
87
88 Statement semantic(Scope *sc)
89 {
90 uint i;
91 TopStatement ts;
92 FunctionDefinition fd;
93
94 //writef("FunctionDefinition::semantic(%s)\n", this);
95
96 // Log all the FunctionDefinition's so we can rapidly
97 // instantiate them at runtime
98 fd = enclosingFunction = sc.funcdef;
99
100 // But only push it if it is not already in the array
101 for (i = 0; ; i++)
102 {
103 if (i == fd.functiondefinitions.length) // not in the array
104 { fd.functiondefinitions ~= this;
105 break;
106 }
107 if (fd.functiondefinitions[i] is this) // already in the array
108 break;
109 }
110
111 //writef("isglobal = %d, isanonymous = %d\n", isglobal, isanonymous);
112 if (!isglobal && !isanonymous)
113 { sc = sc.push(this);
114 sc.nestDepth++;
115 }
116 nestDepth = sc.nestDepth;
117 //writefln("nestDepth = %d", nestDepth);
118
119 if (topstatements.length)
120 {
121 for (i = 0; i < topstatements.length; i++)
122 {
123 ts = topstatements[i];
124 //writefln("calling semantic routine %d which is %x\n",i, cast(uint)cast(void*)ts);
125 if (!ts.done)
126 { ts = ts.semantic(sc);
127 if (sc.errinfo.message)
128 break;
129
130 if (iseval)
131 {
132 // There's an implied "return" on the last statement
133 if ((i + 1) == topstatements.length)
134 {
135 ts = ts.ImpliedReturn();
136 }
137 }
138 topstatements[i] = ts;
139 ts.done = 1;
140 }
141 }
142
143 // Make sure all the LabelSymbol's are defined
144 if (labtab)
145 {
146 foreach (Symbol s; labtab.members)
147 { LabelSymbol ls = cast(LabelSymbol) s;
148 if (!ls.statement)
149 error(sc, errmsgtbl[ERR_UNDEFINED_LABEL],
150 ls.toString(), toString());
151 }
152 }
153 }
154
155 if (!isglobal && !isanonymous)
156 sc.pop();
157
158 FunctionDefinition fdx = this;
159 return cast(Statement)cast(void*)fdx;
160 }
161
162 void toBuffer(inout tchar[] buf)
163 { uint i;
164
165 //writef("FunctionDefinition::toBuffer()\n");
166 if (!isglobal)
167 {
168 buf ~= "function ";
169 if (isanonymous)
170 buf ~= "anonymous";
171 else if (name)
172 buf ~= name.toString();
173 buf ~= '(';
174 for (i = 0; i < parameters.length; i++)
175 {
176 if (i)
177 buf ~= ',';
178 buf ~= parameters[i].toString();
179 }
180 buf ~= ")\n{ \n";
181 }
182 if (topstatements)
183 {
184 for (i = 0; i < topstatements.length; i++)
185 {
186 topstatements[i].toBuffer(buf);
187 }
188 }
189 if (!isglobal)
190 {
191 buf ~= "}\n";
192 }
193 }
194
195 void toIR(IRstate *ignore)
196 {
197 IRstate irs;
198 uint i;
199
200 //writefln("FunctionDefinition.toIR() done = %d", done);
201 irs.ctor();
202 if (topstatements.length)
203 {
204 for (i = 0; i < topstatements.length; i++)
205 { TopStatement ts;
206 FunctionDefinition fd;
207
208 ts = topstatements[i];
209 if (ts.st == FUNCTIONDEFINITION)
210 {
211 fd = cast(FunctionDefinition)ts;
212 if (fd.code)
213 continue;
214 }
215 ts.toIR(&irs);
216 }
217
218 // Don't need parse trees anymore, release to garbage collector
219 topstatements[] = null;
220 topstatements = null;
221 labtab = null; // maybe delete it?
222 }
223 irs.gen0(0, IRret);
224 irs.gen0(0, IRend);
225
226 //irs.validate();
227
228 irs.doFixups();
229 irs.optimize();
230
231 code = cast(IR *) irs.codebuf.data;
232 irs.codebuf.data = null;
233 nlocals = irs.nlocals;
234 }
235
236 void instantiate(Dobject[] scopex, Dobject actobj, uint attributes)
237 {
238 //writefln("FunctionDefinition.instantiate() %s nestDepth = %d", name ? name.toString() : "", nestDepth);
239
240 // Instantiate all the Var's per 10.1.3
241 foreach (Identifier* name; varnames)
242 {
243 // If name is already declared, don't override it
244 //writefln("\tVar Put(%s)", name.toString());
245 actobj.Put(name.toString(), &vundefined, Instantiate | DontOverride | attributes);
246 }
247
248 // Instantiate the Function's per 10.1.3
249 foreach (FunctionDefinition fd; functiondefinitions)
250 {
251 // Set [[Scope]] property per 13.2 step 7
252 Dfunction fobject = new DdeclaredFunction(fd);
253 fobject.scopex = scopex;
254
255 if (fd.name) // skip anonymous functions
256 {
257 //writefln("\tFunction Put(%s)", fd.name.toString());
258 actobj.Put(fd.name.toString(), fobject, Instantiate | attributes);
259 }
260 }
261 //writefln("-FunctionDefinition.instantiate()");
262 }
263 }