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

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

DllProcsクラスを追加。

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