Mercurial > projects > dmdscript-tango
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 } |