source: dev/trunk/abdev/BasicCompiler_Common/Subroutine.cpp@ 353

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

インターフェイス実装周りの仕様整備

File size: 14.8 KB
RevLine 
[206]1#include "stdafx.h"
2
[182]3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
[193]6#include <Compiler.h>
[206]7#include <Procedure.h>
[195]8#include <NamespaceSupporter.h>
[182]9
[4]10#include "../BasicCompiler_Common/common.h"
11
12#ifdef _AMD64_
13#include "../BasicCompiler64/opcode.h"
14#else
[5]15#include "../BasicCompiler32/opcode.h"
[4]16#endif
17
18int GetCallProcName(char *buffer,char *name){
19 int i2,i3,IsStr=0;
20
21 for(i2=0;;i2++){
22 if(buffer[i2]=='\"') IsStr^=1;
23 if(IsDBCSLeadByte(buffer[i2])){
24 name[i2]=buffer[i2];
25 i2++;
26 name[i2]=buffer[i2];
27 continue;
28 }
29 if(buffer[i2]=='['&&IsStr==0){
30 i3=GetStringInBracket(name+i2,buffer+i2);
31 i2+=i3-1;
32 continue;
33 }
34 if(buffer[i2]=='('&&IsStr==0){
35 name[i2]=0;
36 break;
37 }
38 if(buffer[i2]=='='&&IsStr==0){
39 name[i2]=0;
40 break;
41 }
42
43 name[i2]=buffer[i2];
44 if(buffer[i2]=='\0') break;
45 }
46 return i2;
47}
48
49int GetProc(char *name,void **ppInfo){
50
51 //ユーザー定義関数
52 *ppInfo=(void *)GetSubHash(name);
53 if(*ppInfo) return PROC_DEFAULT;
54
55 //DLL関数
56 *ppInfo=(void *)GetDeclareHash(name);
57 if(*ppInfo) return PROC_DLL;
58
59 //コンパイラ埋め込み型
60 *ppInfo=(void *)(_int64)GetFunctionFromName(name);
61 if(*ppInfo) return PROC_BUILTIN;
62
[327]63
64 /////////////////////////////////////////////////////////////////
65 //関数ポインタ、またはデリゲート
66 /////////////////////////////////////////////////////////////////
67
[75]68 Type type;
69 if( !GetVarType( name, type, false ) ){
70 return 0;
71 }
[327]72
73 if( type.IsProcPtr() )
74 {
75 // 関数ポインタ
[75]76 return PROC_PTR;
77 }
[4]78
[332]79 if( type.IsDelegate() )
[327]80 {
81 // デリゲート
82 return PROC_DELEGATE;
83 }
84
[4]85 return 0;
86}
87
[290]88void SplitObjectName(const char *name,char *ObjectName, ReferenceKind &referenceFind )
89{
90 referenceFind = RefNon;
91
[4]92 int i4;
93 for(i4=lstrlen(name)-1;i4>=0;i4--){
94 if(name[i4]=='.'||(name[i4]==1&&name[i4+1]==ESC_PSMEM))
95 break;
96 }
97 if(i4==-1) ObjectName[0]=0;
98 else{
99 //参照タイプを判別
[290]100 if(name[i4]=='.')
101 {
102 referenceFind = RefDot;
103 }
104 else
105 {
106 referenceFind = RefPointer;
107 }
[4]108
109 if(i4==0) GetWithName(ObjectName);
110 else{
111 memcpy(ObjectName,name,i4);
112 ObjectName[i4]=0;
113 }
114 }
115}
[97]116
[331]117bool CallProc( int kind, const void *pProc, const char *fullCallName, const char *lpszParms, const Type &baseType, Type &resultType, bool isCallOn )
118{
[75]119 //GetSubHash内でエラー提示が行われた場合
120 if(pProc==(Procedure *)-1){
121 return false;
122 }
[50]123
[75]124 if(kind==PROC_DEFAULT){
[50]125 /////////////////////
126 // ユーザー定義関数
127 /////////////////////
128
[206]129 const UserProc *pUserProc = (const UserProc *)pProc;
[50]130
131 //オブジェクト名を取得
132 char ObjectName[VN_SIZE];
[290]133 ReferenceKind referenceKind;
134 SplitObjectName(fullCallName,ObjectName, referenceKind );
[50]135
136
137 ////////////////////////
138 // オーバーロードを解決
139 ////////////////////////
140
[206]141 std::vector<const UserProc *> subs;
[75]142 GetOverloadSubHash(fullCallName,subs);
[50]143 if(subs.size()){
144 //オーバーロードを解決
[75]145 pUserProc=OverloadSolutionWithStrParam(fullCallName,subs,lpszParms,ObjectName);
[50]146
[75]147 if(!pUserProc){
148 return false;
149 }
[50]150 }
151
[75]152 resultType = pUserProc->ReturnType();
[50]153
[75]154 if( isCallOn ){
[290]155 if( !Opcode_CallProc(lpszParms,pUserProc,0,ObjectName ) ){
[75]156 return false;
157 }
[50]158 }
159 }
[75]160 else if(kind==PROC_DLL){
[50]161 /////////////////////////
162 // DLL関数
163 /////////////////////////
[75]164 DllProc *pDllProc = (DllProc *)pProc;
[50]165
[75]166 resultType = pDllProc->ReturnType();
167
168 if( isCallOn ){
169 if( !Opcode_CallDllProc(lpszParms,pDllProc) ){
170 return false;
171 }
172 }
[50]173 }
[75]174 else if(kind==PROC_BUILTIN){
[50]175 /////////////////////////
176 // 組み込み関数
177 /////////////////////////
[75]178 int FuncId = (int)(_int64)pProc;
[50]179
[331]180 if( !Opcode_CallFunc( lpszParms, FuncId, baseType, resultType, isCallOn ) ){
[75]181 return false;
[50]182 }
183 }
[75]184 else if(kind==PROC_PTR){
[50]185 /////////////////
186 // 関数ポインタ
187 /////////////////
188
[75]189 Type type;
190 GetVarType(fullCallName,type,false);
[50]191
[265]192 ProcPointer *pProcPtr = compiler.GetObjectModule().meta.GetProcPointers()[type.GetIndex()];
[75]193 resultType = pProcPtr->ReturnType();
194
195 if( isCallOn ){
196 if( !Opcode_CallProcPtr(fullCallName,lpszParms,pProcPtr) ){
197 return false;
198 }
199 }
[50]200 }
[327]201 else if( kind == PROC_DELEGATE )
202 {
203 // デリゲート
204 char tempName[VN_SIZE];
205 lstrcpy( tempName, fullCallName );
206 lstrcat( tempName, ".Call" );
207
208 void *pInfo=(void *)GetSubHash( tempName );
209 if( !pInfo )
210 {
211 Jenga::Throw( "デリゲートの内部Callメソッドの取得に失敗" );
212 }
213
[331]214 return CallProc( PROC_DEFAULT, pInfo, tempName, lpszParms, baseType, resultType, isCallOn );
[327]215 }
[75]216 else{
217 return false;
218 }
[50]219
[75]220 return true;
[50]221}
[75]222bool CallPropertyMethod( const char *variable, const char *rightSide, Type &resultType){
[50]223 //プロパティ用のメソッドを呼び出す
224
225 //配列要素を取得
226 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
227 GetArrayElement(variable,VarName,ArrayElements);
228
229 //オブジェクト名を取得
230 char ObjectName[VN_SIZE];
[290]231 ReferenceKind referenceKind;
232 SplitObjectName(VarName,ObjectName, referenceKind );
[50]233
234 //オーバーロード用の関数リストを作成
[206]235 std::vector<const UserProc *> subs;
[50]236 GetOverloadSubHash(VarName,subs);
237 if(subs.size()==0){
[75]238 return false;
[50]239 }
240
241 //パラメータを整備
242 char *Parameter;
[75]243 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
[50]244 lstrcpy(Parameter,ArrayElements);
[75]245 if(rightSide){
246 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
247 lstrcat(Parameter,rightSide);
[50]248 }
249
250 //オーバーロードを解決
[206]251 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
[50]252
[75]253 if(pUserProc){
[50]254 //呼び出し
[290]255 Opcode_CallProc(Parameter,pUserProc,0,ObjectName);
[50]256
[75]257 resultType = pUserProc->ReturnType();
[292]258
259 Type leftType;
260 GetVarType( ObjectName, leftType, false );
261
[299]262 // 型パラメータを解決
263 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
[50]264 }
265
266 HeapDefaultFree(Parameter);
267
[75]268 return true;
[50]269}
270
[75]271bool GetReturnTypeOfPropertyMethod( const char *variable, const char *rightSide, Type &resultType ){
[4]272 //プロパティ用のメソッドを呼び出す
273
274 //配列要素を取得
275 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
276 GetArrayElement(variable,VarName,ArrayElements);
277
278 //オブジェクト名を取得
279 char ObjectName[VN_SIZE];
[290]280 ReferenceKind referenceKind;
281 SplitObjectName(VarName,ObjectName, referenceKind );
[4]282
283 //オーバーロード用の関数リストを作成
[206]284 std::vector<const UserProc *> subs;
[50]285 GetOverloadSubHash(VarName,subs);
286 if(subs.size()==0){
[4]287 return 0;
288 }
289
290 //パラメータを整備
291 char *Parameter;
[75]292 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
[4]293 lstrcpy(Parameter,ArrayElements);
[75]294 if(rightSide){
295 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
296 lstrcat(Parameter,rightSide);
[4]297 }
298
299 //オーバーロードを解決
[206]300 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
[4]301
[75]302 if(pUserProc){
303 resultType = pUserProc->ReturnType();
[4]304 }
305
306 return 1;
307}
308
[38]309//インデクサ(getter)の戻り値を取得
[292]310bool GetReturnTypeOfIndexerGetterProc( const Type &classType, Type &resultType )
311{
[206]312 vector<const UserProc *> subs;
[342]313 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
[50]314 if( subs.size() == 0 ){
[38]315 return false;
316 }
317
[299]318 const UserProc *pUserProc = subs[0];
[38]319
[299]320 resultType = pUserProc->ReturnType();
[292]321
322
[299]323 // 型パラメータを解決
324 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
[292]325
[38]326 return true;
327}
328
[209]329void CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
[206]330{
[4]331 extern HANDLE hHeap;
332 int i,i2,i3;
333 char temporary[8192];
334
[99]335 // 名前空間管理
[199]336 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
[101]337 namespaceScopes.clear();
[99]338
[108]339 // Importsされた名前空間の管理
[199]340 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
[108]341 importedNamespaces.clear();
342
[4]343 i=-1;
344 while(1){
345 i++;
346
[206]347 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
[4]348 /* Class ~ End Class
349 Interface ~ End Interface
350 を飛び越す */
[206]351 i3=GetEndXXXCommand(source[i+1]);
[4]352 for(i+=2,i2=0;;i++,i2++){
[206]353 if(source[i]=='\0') break;
354 if(source[i]==1&&source[i+1]==(char)i3){
[4]355 i++;
356 break;
357 }
358 }
[206]359 if(source[i]=='\0') break;
[4]360 continue;
361 }
362
[206]363 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
[99]364 for(i+=2,i2=0;;i2++,i++){
[206]365 if( IsCommandDelimitation( source[i] ) ){
[99]366 temporary[i2]=0;
367 break;
368 }
[206]369 temporary[i2]=source[i];
[99]370 }
371 namespaceScopes.push_back( temporary );
372
373 continue;
374 }
[206]375 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
[99]376 if( namespaceScopes.size() <= 0 ){
377 SetError(12, "End Namespace", i );
378 }
379 else{
380 namespaceScopes.pop_back();
381 }
382
383 i += 2;
384 continue;
385 }
[206]386 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
[108]387 for(i+=2,i2=0;;i2++,i++){
[206]388 if( IsCommandDelimitation( source[i] ) ){
[108]389 temporary[i2]=0;
390 break;
391 }
[206]392 temporary[i2]=source[i];
[108]393 }
[199]394 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
[169]395 {
396 SetError(64,temporary,cp );
397 }
[99]398
[108]399 continue;
400 }
[206]401 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
[108]402 importedNamespaces.clear();
403 continue;
404 }
405
[206]406 if(source[i]==1&&source[i+1]==ESC_DECLARE){
[4]407 for(i+=2,i2=0;;i2++,i++){
[206]408 if(source[i]=='\n'){
[4]409 temporary[i2]=0;
410 break;
411 }
[206]412 temporary[i2]=source[i];
413 if(source[i]=='\0') break;
[4]414 }
[209]415 dllProcs.Add(namespaceScopes,temporary,i);
[4]416
417 continue;
418 }
[206]419 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
420 char statementChar = source[i+1];
[108]421
[4]422 for(i2=0;;i2++,i++){
[206]423 if(IsCommandDelimitation(source[i])){
[4]424 temporary[i2]=0;
425 break;
426 }
[206]427 temporary[i2]=source[i];
428 if(source[i]=='\0') break;
[4]429 }
[353]430 userProcs.AddUserProc(namespaceScopes, importedNamespaces, temporary,i,false,NULL,false);
[4]431
[108]432 /* Sub ~ End Sub
433 Function ~ End Function
434 Macro ~ End Macro
435 を飛び越す */
436 char endStatementChar = GetEndXXXCommand( statementChar );
437 for(i2=0;;i++,i2++){
[206]438 if( source[i] == '\0' ) break;
439 if( source[i] == 1 && source[i+1] == endStatementChar ){
[108]440 i++;
441 break;
442 }
443 }
[206]444 if(source[i]=='\0') break;
[4]445 continue;
446 }
447
448 //次の行
449 for(;;i++){
[206]450 if(IsCommandDelimitation(source[i])) break;
[4]451 }
[206]452 if(source[i]=='\0') break;
[4]453 }
[308]454
455 ////////////
456 // 特殊関数
457 ////////////
458 namespaceScopes.clear();
459 importedNamespaces.clear();
460
461 compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
462 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
[353]463 userProcs.AddUserProc( namespaceScopes, importedNamespaces, temporary,0,false,NULL,false);
[4]464}
465
[94]466bool IsNeedProcCompile(){
[265]467 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
468 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
[206]469 {
[265]470 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
[206]471 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
472 return true;
[94]473 }
474 }
475 return false;
476}
[316]477
478void CompileBufferInProcedure( const UserProc &userProc ){
479 if( userProc.IsCompiled() ) return;
480
481 _compile_proc( &userProc );
482
483/*
484 // ログを履く
485 char temporary[8192];
486 temporary[0]=0;
487 lstrcat( temporary, "------------------------------------------------------------------\n" );
488 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
489 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
490 lstrcat( temporary, "------------------------------------------------------------------\n" );
491 lstrcat( temporary, "\n" );
492 Smoothie::Logger::Put( temporary );*/
493}
494void CompileLocal(){
495 if( compiler.IsDll() )
496 {
497 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
498 const UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
499 if(pUserProc){
500 CompileBufferInProcedure( *pUserProc );
501 }
502 else SetError(300,NULL,cp);
503 }
504 else
505 {
506 // グローバル領域を一番初めにコンパイルする
507 extern const UserProc *pSub_System_GlobalArea;
508 CompileBufferInProcedure( *pSub_System_GlobalArea );
509 }
510
511 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
512 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
513 pSubStaticMethod_System_TypeBase_InitializeUserTypes->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
[319]524 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
525 extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots;
526 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile();
527
[316]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 if( IsNeedProcCompile() ){
548 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
549
550 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
551 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
552 {
553 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
554 CompileBufferInProcedure( *pUserProc );
555 }
556 }
557
558 //_System_InitStaticLocalVariablesは一番最後にコンパイル
559 pSub_System_InitStaticLocalVariables->KillCompileStatus();
560 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
561
562 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
563 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
564 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
[319]565
566 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
567 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus();
568 CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots );
[316]569 }
570}
Note: See TracBrowser for help on using the repository browser.