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

Last change on this file since 292 was 292, checked in by dai_9181, 17 years ago
File size: 11.1 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
63 //関数ポインタ
[75]64 Type type;
65 if( !GetVarType( name, type, false ) ){
66 return 0;
67 }
68 if( type.IsProcPtr() ){
69 return PROC_PTR;
70 }
[4]71
72 return 0;
73}
74
[290]75void SplitObjectName(const char *name,char *ObjectName, ReferenceKind &referenceFind )
76{
77 referenceFind = RefNon;
78
[4]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 //参照タイプを判別
[290]87 if(name[i4]=='.')
88 {
89 referenceFind = RefDot;
90 }
91 else
92 {
93 referenceFind = RefPointer;
94 }
[4]95
96 if(i4==0) GetWithName(ObjectName);
97 else{
98 memcpy(ObjectName,name,i4);
99 ObjectName[i4]=0;
100 }
101 }
102}
[97]103
[75]104bool CallProc( int kind, const void *pProc, const char *fullCallName, const char *lpszParms, Type &resultType, bool isCallOn ){
[50]105
[75]106 //GetSubHash内でエラー提示が行われた場合
107 if(pProc==(Procedure *)-1){
108 return false;
109 }
[50]110
[75]111 if(kind==PROC_DEFAULT){
[50]112 /////////////////////
113 // ユーザー定義関数
114 /////////////////////
115
[206]116 const UserProc *pUserProc = (const UserProc *)pProc;
[50]117
118 //オブジェクト名を取得
119 char ObjectName[VN_SIZE];
[290]120 ReferenceKind referenceKind;
121 SplitObjectName(fullCallName,ObjectName, referenceKind );
[50]122
123
124 ////////////////////////
125 // オーバーロードを解決
126 ////////////////////////
127
[206]128 std::vector<const UserProc *> subs;
[75]129 GetOverloadSubHash(fullCallName,subs);
[50]130 if(subs.size()){
131 //オーバーロードを解決
[75]132 pUserProc=OverloadSolutionWithStrParam(fullCallName,subs,lpszParms,ObjectName);
[50]133
[75]134 if(!pUserProc){
135 return false;
136 }
[50]137 }
138
[75]139 resultType = pUserProc->ReturnType();
[50]140
[75]141 if( isCallOn ){
[290]142 if( !Opcode_CallProc(lpszParms,pUserProc,0,ObjectName ) ){
[75]143 return false;
144 }
[50]145 }
146 }
[75]147 else if(kind==PROC_DLL){
[50]148 /////////////////////////
149 // DLL関数
150 /////////////////////////
[75]151 DllProc *pDllProc = (DllProc *)pProc;
[50]152
[75]153 resultType = pDllProc->ReturnType();
154
155 if( isCallOn ){
156 if( !Opcode_CallDllProc(lpszParms,pDllProc) ){
157 return false;
158 }
159 }
[50]160 }
[75]161 else if(kind==PROC_BUILTIN){
[50]162 /////////////////////////
163 // 組み込み関数
164 /////////////////////////
[75]165 int FuncId = (int)(_int64)pProc;
[50]166
[75]167 if( !Opcode_CallFunc( lpszParms, FuncId, resultType, isCallOn ) ){
168 return false;
[50]169 }
170 }
[75]171 else if(kind==PROC_PTR){
[50]172 /////////////////
173 // 関数ポインタ
174 /////////////////
175
[75]176 Type type;
177 GetVarType(fullCallName,type,false);
[50]178
[265]179 ProcPointer *pProcPtr = compiler.GetObjectModule().meta.GetProcPointers()[type.GetIndex()];
[75]180 resultType = pProcPtr->ReturnType();
181
182 if( isCallOn ){
183 if( !Opcode_CallProcPtr(fullCallName,lpszParms,pProcPtr) ){
184 return false;
185 }
186 }
[50]187 }
[75]188 else{
189 return false;
190 }
[50]191
[75]192 return true;
[50]193}
[75]194bool CallPropertyMethod( const char *variable, const char *rightSide, Type &resultType){
[50]195 //プロパティ用のメソッドを呼び出す
196
197 //配列要素を取得
198 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
199 GetArrayElement(variable,VarName,ArrayElements);
200
201 //オブジェクト名を取得
202 char ObjectName[VN_SIZE];
[290]203 ReferenceKind referenceKind;
204 SplitObjectName(VarName,ObjectName, referenceKind );
[50]205
206 //オーバーロード用の関数リストを作成
[206]207 std::vector<const UserProc *> subs;
[50]208 GetOverloadSubHash(VarName,subs);
209 if(subs.size()==0){
[75]210 return false;
[50]211 }
212
213 //パラメータを整備
214 char *Parameter;
[75]215 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
[50]216 lstrcpy(Parameter,ArrayElements);
[75]217 if(rightSide){
218 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
219 lstrcat(Parameter,rightSide);
[50]220 }
221
222 //オーバーロードを解決
[206]223 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
[50]224
[75]225 if(pUserProc){
[50]226 //呼び出し
[290]227 Opcode_CallProc(Parameter,pUserProc,0,ObjectName);
[50]228
[75]229 resultType = pUserProc->ReturnType();
[292]230
231 Type leftType;
232 GetVarType( ObjectName, leftType, false );
233
234 /////////////////////////////////////////////////////////
235 // ☆★☆ ジェネリクスサポート ☆★☆
236
237 if( resultType.IsTypeParameter() )
238 {
239 // 型パラメータだったとき
240
241 int ptrLevel = PTR_LEVEL( resultType.GetBasicType() );
242
243 if( leftType.HasActualGenericType() )
244 {
245 // TODO: GetDummyActualGenericTypeを適切な形に実装し直す
246 resultType = leftType.GetDummyActualGenericType();
247 }
248 else
249 {
250 // TODO: ベースオブジェクト(指定されていないときはObjectクラス)にセットする
251 resultType.SetBasicType( DEF_OBJECT );
252 }
253
254 for( int i=0; i<ptrLevel; i++ )
255 {
256 resultType.PtrLevelUp();
257 }
258 }
259
260 //
261 /////////////////////////////////////////////////////////
[50]262 }
263
264 HeapDefaultFree(Parameter);
265
[75]266 return true;
[50]267}
268
[75]269bool GetReturnTypeOfPropertyMethod( const char *variable, const char *rightSide, Type &resultType ){
[4]270 //プロパティ用のメソッドを呼び出す
271
272 //配列要素を取得
273 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
274 GetArrayElement(variable,VarName,ArrayElements);
275
276 //オブジェクト名を取得
277 char ObjectName[VN_SIZE];
[290]278 ReferenceKind referenceKind;
279 SplitObjectName(VarName,ObjectName, referenceKind );
[4]280
281 //オーバーロード用の関数リストを作成
[206]282 std::vector<const UserProc *> subs;
[50]283 GetOverloadSubHash(VarName,subs);
284 if(subs.size()==0){
[4]285 return 0;
286 }
287
288 //パラメータを整備
289 char *Parameter;
[75]290 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(rightSide)+32);
[4]291 lstrcpy(Parameter,ArrayElements);
[75]292 if(rightSide){
293 if(Parameter[0]&&rightSide[0]) lstrcat(Parameter,",");
294 lstrcat(Parameter,rightSide);
[4]295 }
296
297 //オーバーロードを解決
[206]298 const UserProc *pUserProc = OverloadSolutionWithStrParam(VarName,subs,Parameter,ObjectName);
[4]299
[75]300 if(pUserProc){
301 resultType = pUserProc->ReturnType();
[4]302 }
303
304 return 1;
305}
306
[38]307//インデクサ(getter)の戻り値を取得
[292]308bool GetReturnTypeOfIndexerGetterProc( const Type &classType, Type &resultType )
309{
[206]310 vector<const UserProc *> subs;
[292]311 classType.GetClass().GetMethods().Enum( CALC_ARRAY_GET, subs );
[50]312 if( subs.size() == 0 ){
[38]313 return false;
314 }
315
[75]316 resultType = subs[0]->ReturnType();
[38]317
[292]318
319 /////////////////////////////////////////////////////////
320 // ☆★☆ ジェネリクスサポート ☆★☆
321
322 if( resultType.IsTypeParameter() )
323 {
324 // 型パラメータだったとき
325
326 int ptrLevel = PTR_LEVEL( resultType.GetBasicType() );
327
328 if( classType.HasActualGenericType() )
329 {
330 // TODO: GetDummyActualGenericTypeを適切な形に実装し直す
331 resultType = classType.GetDummyActualGenericType();
332 }
333 else
334 {
335 // TODO: ベースオブジェクト(指定されていないときはObjectクラス)にセットする
336 resultType.SetBasicType( DEF_OBJECT );
337 }
338
339 for( int i=0; i<ptrLevel; i++ )
340 {
341 resultType.PtrLevelUp();
342 }
343 }
344
345 //
346 /////////////////////////////////////////////////////////
347
[38]348 return true;
349}
350
[209]351void CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
[206]352{
[4]353 extern HANDLE hHeap;
354 int i,i2,i3;
355 char temporary[8192];
356
[99]357 // 名前空間管理
[199]358 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
[101]359 namespaceScopes.clear();
[99]360
[108]361 // Importsされた名前空間の管理
[199]362 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
[108]363 importedNamespaces.clear();
364
[4]365 i=-1;
366 while(1){
367 i++;
368
[206]369 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
[4]370 /* Class ~ End Class
371 Interface ~ End Interface
372 を飛び越す */
[206]373 i3=GetEndXXXCommand(source[i+1]);
[4]374 for(i+=2,i2=0;;i++,i2++){
[206]375 if(source[i]=='\0') break;
376 if(source[i]==1&&source[i+1]==(char)i3){
[4]377 i++;
378 break;
379 }
380 }
[206]381 if(source[i]=='\0') break;
[4]382 continue;
383 }
384
[206]385 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
[99]386 for(i+=2,i2=0;;i2++,i++){
[206]387 if( IsCommandDelimitation( source[i] ) ){
[99]388 temporary[i2]=0;
389 break;
390 }
[206]391 temporary[i2]=source[i];
[99]392 }
393 namespaceScopes.push_back( temporary );
394
395 continue;
396 }
[206]397 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
[99]398 if( namespaceScopes.size() <= 0 ){
399 SetError(12, "End Namespace", i );
400 }
401 else{
402 namespaceScopes.pop_back();
403 }
404
405 i += 2;
406 continue;
407 }
[206]408 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
[108]409 for(i+=2,i2=0;;i2++,i++){
[206]410 if( IsCommandDelimitation( source[i] ) ){
[108]411 temporary[i2]=0;
412 break;
413 }
[206]414 temporary[i2]=source[i];
[108]415 }
[199]416 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
[169]417 {
418 SetError(64,temporary,cp );
419 }
[99]420
[108]421 continue;
422 }
[206]423 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
[108]424 importedNamespaces.clear();
425 continue;
426 }
427
[206]428 if(source[i]==1&&source[i+1]==ESC_DECLARE){
[4]429 for(i+=2,i2=0;;i2++,i++){
[206]430 if(source[i]=='\n'){
[4]431 temporary[i2]=0;
432 break;
433 }
[206]434 temporary[i2]=source[i];
435 if(source[i]=='\0') break;
[4]436 }
[209]437 dllProcs.Add(namespaceScopes,temporary,i);
[4]438
439 continue;
440 }
[206]441 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
442 char statementChar = source[i+1];
[108]443
[4]444 for(i2=0;;i2++,i++){
[206]445 if(IsCommandDelimitation(source[i])){
[4]446 temporary[i2]=0;
447 break;
448 }
[206]449 temporary[i2]=source[i];
450 if(source[i]=='\0') break;
[4]451 }
[206]452 userProcs.Add(namespaceScopes, importedNamespaces, temporary,i,false,NULL,false);
[4]453
[108]454 /* Sub ~ End Sub
455 Function ~ End Function
456 Macro ~ End Macro
457 を飛び越す */
458 char endStatementChar = GetEndXXXCommand( statementChar );
459 for(i2=0;;i++,i2++){
[206]460 if( source[i] == '\0' ) break;
461 if( source[i] == 1 && source[i+1] == endStatementChar ){
[108]462 i++;
463 break;
464 }
465 }
[206]466 if(source[i]=='\0') break;
[4]467 continue;
468 }
469
470 //次の行
471 for(;;i++){
[206]472 if(IsCommandDelimitation(source[i])) break;
[4]473 }
[206]474 if(source[i]=='\0') break;
[4]475 }
476}
477
[94]478bool IsNeedProcCompile(){
[265]479 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset();
480 while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() )
[206]481 {
[265]482 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext();
[206]483 if( pUserProc->IsUsing() && pUserProc->IsCompiled() == false ){
484 return true;
[94]485 }
486 }
487 return false;
488}
Note: See TracBrowser for help on using the repository browser.