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

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

GCのバグをいくつか修正

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