source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/Subroutine.cpp@ 514

Last change on this file since 514 was 511, checked in by dai_9181, 17 years ago

幾つかの構文解析系の処理をLexicalAnalyzerに実装し直した

File size: 11.8 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4#include <Procedure.h>
5
6#include "../BasicCompiler_Common/common.h"
7
8#ifdef _AMD64_
9#include "../compiler_x64/opcode.h"
10#else
11#include "../compiler_x86/opcode.h"
12#endif
13
14int GetCallProcName(char *buffer,char *name){
15 int i2,i3,IsStr=0;
16
17 for(i2=0;;i2++){
18 if(buffer[i2]=='\"') IsStr^=1;
19 if(IsDBCSLeadByte(buffer[i2])){
20 name[i2]=buffer[i2];
21 i2++;
22 name[i2]=buffer[i2];
23 continue;
24 }
25 if(buffer[i2]=='['&&IsStr==0){
26 i3=GetStringInBracket(name+i2,buffer+i2);
27 i2+=i3-1;
28 continue;
29 }
30 if(buffer[i2]=='('&&IsStr==0){
31 name[i2]=0;
32 break;
33 }
34 if(buffer[i2]=='='&&IsStr==0){
35 name[i2]=0;
36 break;
37 }
38
39 name[i2]=buffer[i2];
40 if(buffer[i2]=='\0') break;
41 }
42 return i2;
43}
44
45int GetProc(char *name,void **ppInfo){
46
47 //ユーザー定義関数
48 *ppInfo=(void *)GetSubHash(name);
49 if(*ppInfo) return PROC_DEFAULT;
50
51 //DLL関数
52 *ppInfo=(void *)GetDeclareHash(name);
53 if(*ppInfo) return PROC_DLL;
54
55 //コンパイラ埋め込み型
56 *ppInfo=(void *)(_int64)GetFunctionFromName(name);
57 if(*ppInfo) return PROC_BUILTIN;
58
59
60 /////////////////////////////////////////////////////////////////
61 //関数ポインタ、またはデリゲート
62 /////////////////////////////////////////////////////////////////
63
64 Type type;
65 if( !GetVarType( name, type, false ) ){
66 return 0;
67 }
68
69 if( type.IsProcPtr() )
70 {
71 // 関数ポインタ
72 return PROC_PTR;
73 }
74
75 if( type.IsDelegate() )
76 {
77 // デリゲート
78 return PROC_DELEGATE;
79 }
80
81 return 0;
82}
83
84void SplitObjectName(const char *name,char *ObjectName, ReferenceKind &referenceFind )
85{
86 referenceFind = RefNon;
87
88 int i4;
89 for(i4=lstrlen(name)-1;i4>=0;i4--){
90 if(name[i4]=='.'||(name[i4]==1&&name[i4+1]==ESC_PSMEM))
91 break;
92 }
93 if(i4==-1) ObjectName[0]=0;
94 else{
95 //参照タイプを判別
96 if(name[i4]=='.')
97 {
98 referenceFind = RefDot;
99 }
100 else
101 {
102 referenceFind = RefPointer;
103 }
104
105 if(i4==0) GetWithName(ObjectName);
106 else{
107 memcpy(ObjectName,name,i4);
108 ObjectName[i4]=0;
109 }
110 }
111}
112
113bool CallProc( int kind, const void *pProc, const char *fullCallName, const char *lpszParms, const Type &baseType, Type &resultType, bool isCallOn )
114{
115 //GetSubHash内でエラー提示が行われた場合
116 if(pProc==(Procedure *)-1){
117 return false;
118 }
119
120 if(kind==PROC_DEFAULT){
121 /////////////////////
122 // ユーザー定義関数
123 /////////////////////
124
125 const UserProc *pUserProc = (const UserProc *)pProc;
126
127 //オブジェクト名を取得
128 char ObjectName[VN_SIZE];
129 ReferenceKind referenceKind;
130 SplitObjectName(fullCallName,ObjectName, referenceKind );
131
132
133 ////////////////////////
134 // オーバーロードを解決
135 ////////////////////////
136
137 std::vector<const UserProc *> subs;
138 GetOverloadSubHash(fullCallName,subs);
139 if(subs.size()){
140 //オーバーロードを解決
141 pUserProc=OverloadSolutionWithStrParam(fullCallName,subs,lpszParms,ObjectName);
142
143 if(!pUserProc){
144 return false;
145 }
146 }
147
148 resultType = pUserProc->ReturnType();
149
150 if( isCallOn ){
151 if( !Opcode_CallProc(lpszParms,pUserProc,0,ObjectName ) ){
152 return false;
153 }
154 }
155 }
156 else if(kind==PROC_DLL){
157 /////////////////////////
158 // DLL関数
159 /////////////////////////
160 DllProc *pDllProc = (DllProc *)pProc;
161
162 resultType = pDllProc->ReturnType();
163
164 if( isCallOn ){
165 if( !Opcode_CallDllProc(lpszParms,pDllProc) ){
166 return false;
167 }
168 }
169 }
170 else if(kind==PROC_BUILTIN){
171 /////////////////////////
172 // 組み込み関数
173 /////////////////////////
174 int FuncId = (int)(_int64)pProc;
175
176 if( !Opcode_CallFunc( lpszParms, FuncId, baseType, resultType, isCallOn ) ){
177 return false;
178 }
179 }
180 else if(kind==PROC_PTR){
181 /////////////////
182 // 関数ポインタ
183 /////////////////
184
185 Type type;
186 GetVarType(fullCallName,type,false);
187
188 ProcPointer *pProcPtr = compiler.GetObjectModule().meta.GetProcPointers()[type.GetIndex()];
189 resultType = pProcPtr->ReturnType();
190
191 if( isCallOn ){
192 if( !Opcode_CallProcPtr(fullCallName,lpszParms,pProcPtr) ){
193 return false;
194 }
195 }
196 }
197 else if( kind == PROC_DELEGATE )
198 {
199 // デリゲート
200 char tempName[VN_SIZE];
201 lstrcpy( tempName, fullCallName );
202 lstrcat( tempName, ".Call" );
203
204 void *pInfo=(void *)GetSubHash( tempName );
205 if( !pInfo )
206 {
207 Jenga::Throw( "デリゲートの内部Callメソッドの取得に失敗" );
208 }
209
210 return CallProc( PROC_DEFAULT, pInfo, tempName, lpszParms, baseType, resultType, isCallOn );
211 }
212 else{
213 return false;
214 }
215
216 return true;
217}
218bool CallPropertyMethod( const char *variable, const char *rightSide, Type &resultType){
219 //プロパティ用のメソッドを呼び出す
220
221 //配列要素を取得
222 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
223 GetArrayElement(variable,VarName,ArrayElements);
224
225 //オブジェクト名を取得
226 char ObjectName[VN_SIZE];
227 ReferenceKind referenceKind;
228 SplitObjectName(VarName,ObjectName, referenceKind );
229
230 //オーバーロード用の関数リストを作成
231 std::vector<const UserProc *> subs;
232 GetOverloadSubHash(VarName,subs);
233 if(subs.size()==0){
234 return false;
235 }
236
237 //パラメータを整備
238 char *Parameter;
239 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
240 lstrcpy(Parameter,ArrayElements);
241 if(rightSide){
242 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
243 lstrcat(Parameter,rightSide);
244 }
245
246 //オーバーロードを解決
247 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
248
249 if(pUserProc){
250 //呼び出し
251 Opcode_CallProc(Parameter,pUserProc,0,ObjectName);
252
253 resultType = pUserProc->ReturnType();
254
255 Type leftType;
256 GetVarType( ObjectName, leftType, false );
257
258 // 型パラメータを解決
259 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
260 }
261
262 HeapDefaultFree(Parameter);
263
264 return true;
265}
266
267bool GetReturnTypeOfPropertyMethod( const char *variable, const char *rightSide, Type &resultType ){
268 //プロパティ用のメソッドを呼び出す
269
270 //配列要素を取得
271 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
272 GetArrayElement(variable,VarName,ArrayElements);
273
274 //オブジェクト名を取得
275 char ObjectName[VN_SIZE];
276 ReferenceKind referenceKind;
277 SplitObjectName(VarName,ObjectName, referenceKind );
278
279 //オーバーロード用の関数リストを作成
280 std::vector<const UserProc *> subs;
281 GetOverloadSubHash(VarName,subs);
282 if(subs.size()==0){
283 return 0;
284 }
285
286 //パラメータを整備
287 char *Parameter;
288 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
289 lstrcpy(Parameter,ArrayElements);
290 if(rightSide){
291 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
292 lstrcat(Parameter,rightSide);
293 }
294
295 //オーバーロードを解決
296 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
297
298 if(pUserProc){
299 resultType = pUserProc->ReturnType();
300 }
301
302 return 1;
303}
304
305//インデクサ(getter)の戻り値を取得
306bool GetReturnTypeOfIndexerGetterProc( const Type &classType, Type &resultType )
307{
308 vector<const UserProc *> subs;
309 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
310 if( subs.size() == 0 ){
311 return false;
312 }
313
314 const UserProc *pUserProc = subs[0];
315
316 resultType = pUserProc->ReturnType();
317
318
319 // 型パラメータを解決
320 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
321
322 return true;
323}
324
325bool IsNeedProcCompile(){
326 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
327 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
328 {
329 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
330 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
331 return true;
332 }
333 }
334 return false;
335}
336
337void CompileBufferInProcedure( const UserProc &userProc ){
338 if( userProc.IsCompiled() ) return;
339
340 _compile_proc( &userProc );
341
342/*
343 // ログを履く
344 char temporary[8192];
345 temporary[0]=0;
346 lstrcat( temporary, "------------------------------------------------------------------\n" );
347 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
348 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
349 lstrcat( temporary, "------------------------------------------------------------------\n" );
350 lstrcat( temporary, "\n" );
351 Smoothie::Logger::Put( temporary );*/
352}
353void CompileLocal(){
354 if( compiler.IsDll() )
355 {
356 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
357 const UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
358 if(pUserProc){
359 CompileBufferInProcedure( *pUserProc );
360 }
361 else compiler.errorMessenger.Output(300,NULL,cp);
362 }
363 else
364 {
365 // グローバル領域を一番初めにコンパイルする
366 extern const UserProc *pSub_System_GlobalArea;
367 CompileBufferInProcedure( *pSub_System_GlobalArea );
368 }
369
370 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
371 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
372 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
373
374 //_System_TypeBase_InitializeUserTypesForBaseTypeは一番最後にコンパイル
375 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType;
376 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->CompleteCompile();
377
378 //_System_InitStaticLocalVariablesは一番最後にコンパイル
379 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
380 extern const UserProc *pSub_System_InitStaticLocalVariables;
381 pSub_System_InitStaticLocalVariables->CompleteCompile();
382
383 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
384 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
385 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
386
387 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
388 extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots;
389 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile();
390
391repeat:
392 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
393 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
394 {
395 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
396 CompileBufferInProcedure( *pUserProc );
397 }
398
399 if( IsNeedProcCompile() ){
400 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
401 goto repeat;
402 }
403
404 if( !compiler.IsStaticLibrary() )
405 {
406 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
407 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
408 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
409
410 //_System_TypeBase_InitializeUserTypesForBaseTypeは最後のほうでコンパイル
411 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->KillCompileStatus();
412 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType );
413
414 if( IsNeedProcCompile() ){
415 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
416
417 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
418 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
419 {
420 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
421 CompileBufferInProcedure( *pUserProc );
422 }
423 }
424
425 //_System_InitStaticLocalVariablesは一番最後にコンパイル
426 pSub_System_InitStaticLocalVariables->KillCompileStatus();
427 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
428
429 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
430 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
431 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
432
433 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
434 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus();
435 CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots );
436 }
437}
Note: See TracBrowser for help on using the repository browser.