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

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

静的領域に初期オブジェクトを配置可能にした

File size: 15.3 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
6#include <Compiler.h>
7#include <Procedure.h>
8#include <NamespaceSupporter.h>
9
10#include "../BasicCompiler_Common/common.h"
11
12#ifdef _AMD64_
13#include "../BasicCompiler64/opcode.h"
14#else
15#include "../BasicCompiler32/opcode.h"
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
63
64 /////////////////////////////////////////////////////////////////
65 //関数ポインタ、またはデリゲート
66 /////////////////////////////////////////////////////////////////
67
68 Type type;
69 if( !GetVarType( name, type, false ) ){
70 return 0;
71 }
72
73 if( type.IsProcPtr() )
74 {
75 // 関数ポインタ
76 return PROC_PTR;
77 }
78
79 if( type.IsDelegate() )
80 {
81 // デリゲート
82 return PROC_DELEGATE;
83 }
84
85 return 0;
86}
87
88void SplitObjectName(const char *name,char *ObjectName, ReferenceKind &referenceFind )
89{
90 referenceFind = RefNon;
91
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 //参照タイプを判別
100 if(name[i4]=='.')
101 {
102 referenceFind = RefDot;
103 }
104 else
105 {
106 referenceFind = RefPointer;
107 }
108
109 if(i4==0) GetWithName(ObjectName);
110 else{
111 memcpy(ObjectName,name,i4);
112 ObjectName[i4]=0;
113 }
114 }
115}
116
117bool CallProc( int kind, const void *pProc, const char *fullCallName, const char *lpszParms, const Type &baseType, Type &resultType, bool isCallOn )
118{
119 //GetSubHash内でエラー提示が行われた場合
120 if(pProc==(Procedure *)-1){
121 return false;
122 }
123
124 if(kind==PROC_DEFAULT){
125 /////////////////////
126 // ユーザー定義関数
127 /////////////////////
128
129 const UserProc *pUserProc = (const UserProc *)pProc;
130
131 //オブジェクト名を取得
132 char ObjectName[VN_SIZE];
133 ReferenceKind referenceKind;
134 SplitObjectName(fullCallName,ObjectName, referenceKind );
135
136
137 ////////////////////////
138 // オーバーロードを解決
139 ////////////////////////
140
141 std::vector<const UserProc *> subs;
142 GetOverloadSubHash(fullCallName,subs);
143 if(subs.size()){
144 //オーバーロードを解決
145 pUserProc=OverloadSolutionWithStrParam(fullCallName,subs,lpszParms,ObjectName);
146
147 if(!pUserProc){
148 return false;
149 }
150 }
151
152 resultType = pUserProc->ReturnType();
153
154 if( isCallOn ){
155 if( !Opcode_CallProc(lpszParms,pUserProc,0,ObjectName ) ){
156 return false;
157 }
158 }
159 }
160 else if(kind==PROC_DLL){
161 /////////////////////////
162 // DLL関数
163 /////////////////////////
164 DllProc *pDllProc = (DllProc *)pProc;
165
166 resultType = pDllProc->ReturnType();
167
168 if( isCallOn ){
169 if( !Opcode_CallDllProc(lpszParms,pDllProc) ){
170 return false;
171 }
172 }
173 }
174 else if(kind==PROC_BUILTIN){
175 /////////////////////////
176 // 組み込み関数
177 /////////////////////////
178 int FuncId = (int)(_int64)pProc;
179
180 if( !Opcode_CallFunc( lpszParms, FuncId, baseType, resultType, isCallOn ) ){
181 return false;
182 }
183 }
184 else if(kind==PROC_PTR){
185 /////////////////
186 // 関数ポインタ
187 /////////////////
188
189 Type type;
190 GetVarType(fullCallName,type,false);
191
192 ProcPointer *pProcPtr = compiler.GetObjectModule().meta.GetProcPointers()[type.GetIndex()];
193 resultType = pProcPtr->ReturnType();
194
195 if( isCallOn ){
196 if( !Opcode_CallProcPtr(fullCallName,lpszParms,pProcPtr) ){
197 return false;
198 }
199 }
200 }
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
214 return CallProc( PROC_DEFAULT, pInfo, tempName, lpszParms, baseType, resultType, isCallOn );
215 }
216 else{
217 return false;
218 }
219
220 return true;
221}
222bool CallPropertyMethod( const char *variable, const char *rightSide, Type &resultType){
223 //プロパティ用のメソッドを呼び出す
224
225 //配列要素を取得
226 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
227 GetArrayElement(variable,VarName,ArrayElements);
228
229 //オブジェクト名を取得
230 char ObjectName[VN_SIZE];
231 ReferenceKind referenceKind;
232 SplitObjectName(VarName,ObjectName, referenceKind );
233
234 //オーバーロード用の関数リストを作成
235 std::vector<const UserProc *> subs;
236 GetOverloadSubHash(VarName,subs);
237 if(subs.size()==0){
238 return false;
239 }
240
241 //パラメータを整備
242 char *Parameter;
243 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
244 lstrcpy(Parameter,ArrayElements);
245 if(rightSide){
246 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
247 lstrcat(Parameter,rightSide);
248 }
249
250 //オーバーロードを解決
251 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
252
253 if(pUserProc){
254 //呼び出し
255 Opcode_CallProc(Parameter,pUserProc,0,ObjectName);
256
257 resultType = pUserProc->ReturnType();
258
259 Type leftType;
260 GetVarType( ObjectName, leftType, false );
261
262 // 型パラメータを解決
263 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
264 }
265
266 HeapDefaultFree(Parameter);
267
268 return true;
269}
270
271bool GetReturnTypeOfPropertyMethod( const char *variable, const char *rightSide, Type &resultType ){
272 //プロパティ用のメソッドを呼び出す
273
274 //配列要素を取得
275 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
276 GetArrayElement(variable,VarName,ArrayElements);
277
278 //オブジェクト名を取得
279 char ObjectName[VN_SIZE];
280 ReferenceKind referenceKind;
281 SplitObjectName(VarName,ObjectName, referenceKind );
282
283 //オーバーロード用の関数リストを作成
284 std::vector<const UserProc *> subs;
285 GetOverloadSubHash(VarName,subs);
286 if(subs.size()==0){
287 return 0;
288 }
289
290 //パラメータを整備
291 char *Parameter;
292 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
293 lstrcpy(Parameter,ArrayElements);
294 if(rightSide){
295 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
296 lstrcat(Parameter,rightSide);
297 }
298
299 //オーバーロードを解決
300 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
301
302 if(pUserProc){
303 resultType = pUserProc->ReturnType();
304 }
305
306 return 1;
307}
308
309//インデクサ(getter)の戻り値を取得
310bool GetReturnTypeOfIndexerGetterProc( const Type &classType, Type &resultType )
311{
312 vector<const UserProc *> subs;
313 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
314 if( subs.size() == 0 ){
315 return false;
316 }
317
318 const UserProc *pUserProc = subs[0];
319
320 resultType = pUserProc->ReturnType();
321
322
323 // 型パラメータを解決
324 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
325
326 return true;
327}
328
329void CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
330{
331 extern HANDLE hHeap;
332 int i,i2,i3;
333 char temporary[8192];
334
335 // 名前空間管理
336 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
337 namespaceScopes.clear();
338
339 // Importsされた名前空間の管理
340 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
341 importedNamespaces.clear();
342
343 i=-1;
344 while(1){
345 i++;
346
347 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
348 /* Class ~ End Class
349 Interface ~ End Interface
350 を飛び越す */
351 i3=GetEndXXXCommand(source[i+1]);
352 for(i+=2,i2=0;;i++,i2++){
353 if(source[i]=='\0') break;
354 if(source[i]==1&&source[i+1]==(char)i3){
355 i++;
356 break;
357 }
358 }
359 if(source[i]=='\0') break;
360 continue;
361 }
362
363 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
364 for(i+=2,i2=0;;i2++,i++){
365 if( IsCommandDelimitation( source[i] ) ){
366 temporary[i2]=0;
367 break;
368 }
369 temporary[i2]=source[i];
370 }
371 namespaceScopes.push_back( temporary );
372
373 continue;
374 }
375 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
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 }
386 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
387 for(i+=2,i2=0;;i2++,i++){
388 if( IsCommandDelimitation( source[i] ) ){
389 temporary[i2]=0;
390 break;
391 }
392 temporary[i2]=source[i];
393 }
394 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
395 {
396 SetError(64,temporary,cp );
397 }
398
399 continue;
400 }
401 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
402 importedNamespaces.clear();
403 continue;
404 }
405
406 if(source[i]==1&&source[i+1]==ESC_DECLARE){
407 for(i+=2,i2=0;;i2++,i++){
408 if(source[i]=='\n'){
409 temporary[i2]=0;
410 break;
411 }
412 temporary[i2]=source[i];
413 if(source[i]=='\0') break;
414 }
415 dllProcs.Add(namespaceScopes,temporary,i);
416
417 continue;
418 }
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];
421
422 for(i2=0;;i2++,i++){
423 if(IsCommandDelimitation(source[i])){
424 temporary[i2]=0;
425 break;
426 }
427 temporary[i2]=source[i];
428 if(source[i]=='\0') break;
429 }
430 userProcs.AddUserProc(namespaceScopes, importedNamespaces, temporary,i,false,NULL,false);
431
432 /* Sub ~ End Sub
433 Function ~ End Function
434 Macro ~ End Macro
435 を飛び越す */
436 char endStatementChar = GetEndXXXCommand( statementChar );
437 for(i2=0;;i++,i2++){
438 if( source[i] == '\0' ) break;
439 if( source[i] == 1 && source[i+1] == endStatementChar ){
440 i++;
441 break;
442 }
443 }
444 if(source[i]=='\0') break;
445 continue;
446 }
447
448 //次の行
449 for(;;i++){
450 if(IsCommandDelimitation(source[i])) break;
451 }
452 if(source[i]=='\0') break;
453 }
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());
463 userProcs.AddUserProc( namespaceScopes, importedNamespaces, temporary,0,false,NULL,false);
464}
465
466bool IsNeedProcCompile(){
467 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
468 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
469 {
470 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
471 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
472 return true;
473 }
474 }
475 return false;
476}
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_TypeBase_InitializeUserTypesForBaseTypeは一番最後にコンパイル
516 extern const UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType;
517 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->CompleteCompile();
518
519 //_System_InitStaticLocalVariablesは一番最後にコンパイル
520 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
521 extern const UserProc *pSub_System_InitStaticLocalVariables;
522 pSub_System_InitStaticLocalVariables->CompleteCompile();
523
524 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
525 extern const UserProc *pSub_System_Call_Destructor_of_GlobalObject;
526 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
527
528 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
529 extern const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots;
530 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->CompleteCompile();
531
532repeat:
533 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
534 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
535 {
536 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
537 CompileBufferInProcedure( *pUserProc );
538 }
539
540 if( IsNeedProcCompile() ){
541 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
542 goto repeat;
543 }
544
545 if( !compiler.IsStaticLibrary() )
546 {
547 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
548 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
549 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
550
551 //_System_TypeBase_InitializeUserTypesForBaseTypeは最後のほうでコンパイル
552 pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType->KillCompileStatus();
553 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType );
554
555 if( IsNeedProcCompile() ){
556 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
557
558 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
559 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
560 {
561 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
562 CompileBufferInProcedure( *pUserProc );
563 }
564 }
565
566 //_System_InitStaticLocalVariablesは一番最後にコンパイル
567 pSub_System_InitStaticLocalVariables->KillCompileStatus();
568 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
569
570 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
571 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
572 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
573
574 // _System_CGarbageCollection.RegisterGlobalRootsは一番最後にコンパイル
575 pUserProc_System_CGarbageCollection_RegisterGlobalRoots->KillCompileStatus();
576 CompileBufferInProcedure( *pUserProc_System_CGarbageCollection_RegisterGlobalRoots );
577 }
578}
Note: See TracBrowser for help on using the repository browser.