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

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

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

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