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

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

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