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

Last change on this file since 507 was 507, checked in by dai_9181, 16 years ago

NamespaceSupporterクラスをab_commonプロジェクトに移動した。

File size: 15.2 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
325void CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
326{
327 extern HANDLE hHeap;
328 int i,i2,i3;
329 char temporary[8192];
330
331 // 名前空間管理
332 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
333 namespaceScopes.clear();
334
335 // Importsされた名前空間の管理
336 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
337 importedNamespaces.clear();
338
339 i=-1;
340 while(1){
341 i++;
342
343 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
344 /* Class ~ End Class
345 Interface ~ End Interface
346 を飛び越す */
347 i3=GetEndXXXCommand(source[i+1]);
348 for(i+=2,i2=0;;i++,i2++){
349 if(source[i]=='\0') break;
350 if(source[i]==1&&source[i+1]==(char)i3){
351 i++;
352 break;
353 }
354 }
355 if(source[i]=='\0') break;
356 continue;
357 }
358
359 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
360 for(i+=2,i2=0;;i2++,i++){
361 if( IsCommandDelimitation( source[i] ) ){
362 temporary[i2]=0;
363 break;
364 }
365 temporary[i2]=source[i];
366 }
367 namespaceScopes.push_back( temporary );
368
369 continue;
370 }
371 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
372 if( namespaceScopes.size() <= 0 ){
373 compiler.errorMessenger.Output(12, "End Namespace", i );
374 }
375 else{
376 namespaceScopes.pop_back();
377 }
378
379 i += 2;
380 continue;
381 }
382 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
383 for(i+=2,i2=0;;i2++,i++){
384 if( IsCommandDelimitation( source[i] ) ){
385 temporary[i2]=0;
386 break;
387 }
388 temporary[i2]=source[i];
389 }
390 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
391 {
392 compiler.errorMessenger.Output(64,temporary,cp );
393 }
394
395 continue;
396 }
397 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
398 importedNamespaces.clear();
399 continue;
400 }
401
402 if(source[i]==1&&source[i+1]==ESC_DECLARE){
403 for(i+=2,i2=0;;i2++,i++){
404 if(source[i]=='\n'){
405 temporary[i2]=0;
406 break;
407 }
408 temporary[i2]=source[i];
409 if(source[i]=='\0') break;
410 }
411 dllProcs.Add(namespaceScopes,temporary,i);
412
413 continue;
414 }
415 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
416 char statementChar = source[i+1];
417
418 for(i2=0;;i2++,i++){
419 if(IsCommandDelimitation(source[i])){
420 temporary[i2]=0;
421 break;
422 }
423 temporary[i2]=source[i];
424 if(source[i]=='\0') break;
425 }
426 userProcs.AddUserProc(namespaceScopes, importedNamespaces, temporary,i,false,NULL,false);
427
428 /* Sub ~ End Sub
429 Function ~ End Function
430 Macro ~ End Macro
431 を飛び越す */
432 char endStatementChar = GetEndXXXCommand( statementChar );
433 for(i2=0;;i++,i2++){
434 if( source[i] == '\0' ) break;
435 if( source[i] == 1 && source[i+1] == endStatementChar ){
436 i++;
437 break;
438 }
439 }
440 if(source[i]=='\0') break;
441 continue;
442 }
443
444 //次の行
445 for(;;i++){
446 if(IsCommandDelimitation(source[i])) break;
447 }
448 if(source[i]=='\0') break;
449 }
450
451 ////////////
452 // 特殊関数
453 ////////////
454 namespaceScopes.clear();
455 importedNamespaces.clear();
456
457 compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
458 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
459 userProcs.AddUserProc( namespaceScopes, importedNamespaces, temporary,0,false,NULL,false);
460}
461
462bool IsNeedProcCompile(){
463 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
464 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
465 {
466 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
467 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
468 return true;
469 }
470 }
471 return false;
472}
473
474void CompileBufferInProcedure( const UserProc &userProc ){
475 if( userProc.IsCompiled() ) return;
476
477 _compile_proc( &userProc );
478
479/*
480 // ログを履く
481 char temporary[8192];
482 temporary[0]=0;
483 lstrcat( temporary, "------------------------------------------------------------------\n" );
484 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
485 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
486 lstrcat( temporary, "------------------------------------------------------------------\n" );
487 lstrcat( temporary, "\n" );
488 Smoothie::Logger::Put( temporary );*/
489}
490void CompileLocal(){
491 if( compiler.IsDll() )
492 {
493 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
494 const UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
495 if(pUserProc){
496 CompileBufferInProcedure( *pUserProc );
497 }
498 else compiler.errorMessenger.Output(300,NULL,cp);
499 }
500 else
501 {
502 // グローバル領域を一番初めにコンパイルする
503 extern const UserProc *pSub_System_GlobalArea;
504 CompileBufferInProcedure( *pSub_System_GlobalArea );
505 }
506
507 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
508 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
509 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
510
511 //_System_TypeBase_InitializeUserTypesForBaseTypeは一番最後にコンパイル
512 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType;
513 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->CompleteCompile();
514
515 //_System_InitStaticLocalVariablesは一番最後にコンパイル
516 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
517 extern const UserProc *pSub_System_InitStaticLocalVariables;
518 pSub_System_InitStaticLocalVariables->CompleteCompile();
519
520 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
521 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
522 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
523
524 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
525 extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots;
526 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile();
527
528repeat:
529 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
530 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
531 {
532 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
533 CompileBufferInProcedure( *pUserProc );
534 }
535
536 if( IsNeedProcCompile() ){
537 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
538 goto repeat;
539 }
540
541 if( !compiler.IsStaticLibrary() )
542 {
543 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
544 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
545 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
546
547 //_System_TypeBase_InitializeUserTypesForBaseTypeは最後のほうでコンパイル
548 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->KillCompileStatus();
549 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType );
550
551 if( IsNeedProcCompile() ){
552 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
553
554 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
555 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
556 {
557 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
558 CompileBufferInProcedure( *pUserProc );
559 }
560 }
561
562 //_System_InitStaticLocalVariablesは一番最後にコンパイル
563 pSub_System_InitStaticLocalVariables->KillCompileStatus();
564 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
565
566 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
567 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
568 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
569
570 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
571 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus();
572 CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots );
573 }
574}
Note: See TracBrowser for help on using the repository browser.