source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Procedure.cpp @ 572

Last change on this file since 572 was 572, checked in by dai_9181, 15 years ago

ParseDllProc?/SetParamsAndReturnTypeForUserProcを実装。

File size: 11.4 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4#include <Procedure.h>
5
6#include "../common.h"
7#ifdef _AMD64_
8#include "../../compiler_x64/opcode.h"
9#else
10#include "../../compiler_x86/opcode.h"
11#endif
12
13using namespace ActiveBasic::Compiler;
14
15
16bool UserProc::IsEqualForOverride( const Types &actualTypeParametersForThisProc, const UserProc *pUserProc ) const
17{
18    if( this->GetName() == pUserProc->GetName()                     // 名前空間及び名前が等しい
19        && this->Params().Equals( actualTypeParametersForThisProc, pUserProc->Params() ) )          // パラメータが等しい
20    {
21        if( this->returnType.Equals( pUserProc->returnType ) )
22        {
23            // 戻り値が等しい
24            return true;
25        }
26        else if( this->returnType.IsCovariant( pUserProc->returnType ) )
27        {
28            // 戻り値が共変
29            return true;
30        }
31        else if( this->returnType.IsTypeParameter() )
32        {
33            // 型パラメータだったとき
34
35            if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].Equals( pUserProc->returnType ) )
36            {
37                // 戻り値が等しい
38                return true;
39            }
40            else if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].IsCovariant( pUserProc->returnType ) )
41            {
42                // 戻り値が共変
43                return true;
44            }
45        }
46    }
47    return false;
48}
49   
50
51std::string UserProc::GetFullName() const
52{
53    if( HasParentClass() ){
54        return GetParentClass().GetName() + "." + GetName();
55    }
56
57    return GetName();
58}
59bool UserProc::IsCastOperator() const
60{
61    if( GetName()[0] == 1 && GetName()[1] == ESC_OPERATOR && GetName()[2] == CALC_AS )
62    {
63        return true;
64    }
65    return false;
66}
67const NamespaceScopes &UserProc::GetNamespaceScopes() const
68{
69    if( HasParentClass() ){
70        return GetParentClassPtr()->GetNamespaceScopes();
71    }
72    return Symbol::GetNamespaceScopes();
73}
74const NamespaceScopesCollection &UserProc::GetImportedNamespaces() const
75{
76    if( pParentClass )
77    {
78        return pParentClass->GetImportedNamespaces();
79    }
80    return importedNamespaces;
81}
82bool UserProc::IsVirtual() const
83{
84    if( pMethod == NULL ){
85        return false;
86    }
87    return ( pMethod->IsVirtual() != 0 );
88}
89const CMethod &UserProc::GetMethod() const
90{
91    if( !HasParentClass() )
92    {
93        Jenga::Throw( "グローバル関数に対してUserProc::GetMethodメソッドが呼ばれた" );
94    }
95    return *pMethod;
96}
97
98const UserProc *UserProc::pGlobalProc = NULL;
99
100
101bool UserProcs::Insert( UserProc *pUserProc, int nowLine )
102{
103    /////////////////////////////////
104    // ハッシュデータに追加
105    /////////////////////////////////
106
107    if( !Put( pUserProc ) )
108    {
109        // 重複しているため、失敗
110        compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
111        return false;
112    }
113
114    return true;
115}
116
117void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector<const UserProc *> &subs )
118{
119    ///////////////////////////
120    // グローバル関数を検索
121    ///////////////////////////
122
123    // ハッシュ値を取得
124    UserProc *pUserProc = GetHashArrayElement( simpleName );
125    while(pUserProc){
126        if( pUserProc->IsGlobalProcedure() ){
127            if( pUserProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( localName ) ) ){
128                subs.push_back( pUserProc );
129            }
130        }
131
132        pUserProc=pUserProc->GetChainNext();
133    }
134}
135
136bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
137    int i = 0;
138    int i2,i3,sw;
139    char temporary[8192],temp2[VN_SIZE];
140
141    //ソースコードの位置
142    this->codePos = nowLine;
143
144    //パラメータ
145    if(sourceOfParams[i]!='('){
146        compiler.errorMessenger.Output(1,NULL,nowLine);
147        return 0;
148    }
149    i++;
150
151    while(1){
152        if(sourceOfParams[i]==')') break;
153
154        //ByRef
155        bool isRef;
156        if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
157            isRef = false;
158            i+=2;
159        }
160        else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
161            isRef = true;
162            i+=2;
163        }
164        else isRef = false;
165
166        //パラメータ名
167        bool isArray = false;
168        Subscripts subscripts;
169        char name[VN_SIZE];
170        sw=0;
171        for(i2=0;;i++,i2++){
172            if(sourceOfParams[i]=='('){
173                if(!sw) sw=1;
174
175                i3=GetStringInPare(name+i2,sourceOfParams+i);
176                i2+=i3-1;
177                i+=i3-1;
178                continue;
179            }
180            if(sourceOfParams[i]=='['){
181                if(!sw) sw=1;
182
183                i3=GetStringInBracket(name+i2,sourceOfParams+i);
184                i2+=i3-1;
185                i+=i3-1;
186                continue;
187            }
188            if(!IsVariableChar(sourceOfParams[i])){
189                name[i2]=0;
190                break;
191            }
192            name[i2]=sourceOfParams[i];
193        }
194        if(sw){
195            //配列パラメータ
196            if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
197            isArray = true;
198
199            if((name[i2-2]=='('&&name[i2-1]==')')||
200                (name[i2-2]=='['&&name[i2-1]==']'))
201            {
202                subscripts.push_back( LONG_MAX );
203
204                name[i2-2]=0;
205            }
206            else{
207                GetArrange(name,temp2,subscripts);
208                lstrcpy(name,temp2);
209            }
210
211            i2=lstrlen(name);
212        }
213
214        //型
215        Type type( DEF_NON );
216        if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE );
217        else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
218            i+=2;
219
220            i2=0;
221            while(sourceOfParams[i]=='*'){
222                temporary[i2]=sourceOfParams[i];
223                i++;
224                i2++;
225            }
226            for(;;i++,i2++){
227                if(!IsVariableChar(sourceOfParams[i])){
228                    if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
229                        temporary[i2++]=sourceOfParams[i++];
230                        temporary[i2]=sourceOfParams[i];
231                        continue;
232                    }
233                    temporary[i2]=0;
234                    break;
235                }
236                temporary[i2]=sourceOfParams[i];
237            }
238
239            compiler.StringToType( temporary, type );
240
241            if( type.IsNull() ){
242                compiler.errorMessenger.Output(3,temporary,nowLine);
243                type.SetBasicType( DEF_PTR_VOID );
244            }
245        }
246        else{
247            type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
248            compiler.errorMessenger.Output(-103,temporary,nowLine);
249        }
250
251        Parameter *pParam = new Parameter( name, type, isRef );
252        if( isArray ){
253            pParam->SetArray( subscripts );
254        }
255
256        //パラメータを追加
257        this->GetParameters().push_back( pParam );
258
259        if(sourceOfParams[i]==','){
260            i++;
261            continue;
262        }
263        else if(sourceOfParams[i]==')') continue;
264        else{
265            compiler.errorMessenger.Output(1,NULL,nowLine);
266            break;
267        }
268    }
269    i++;
270
271    if(sourceOfParams[i]){
272        ///////////////////
273        // 戻り値を取得
274        ///////////////////
275
276        i2=lstrlen(sourceOfParams)-2;
277
278        int sw_as=0;
279        for(;i2>0;i2--){
280            if(sourceOfParams[i2]==')') break;
281
282            if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
283                i2+=2;
284                i3=0;
285                while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
286                for(;;i2++,i3++){
287                    if(!IsVariableChar(sourceOfParams[i2])){
288                        temporary[i3]=0;
289                        break;
290                    }
291                    temporary[i3]=sourceOfParams[i2];
292                }
293                compiler.StringToType( temporary, this->returnType );
294                if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
295
296                sw_as=1;
297                break;
298            }
299        }
300    }
301    else{
302        //戻り値なしのSub定義
303        this->returnType.SetNull();
304    }
305
306    return true;
307}
308
309bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
310    int i = 0;
311    int i2,i3,sw;
312    char temporary[8192],temp2[VN_SIZE];
313
314    //ソースコードの位置
315    this->codePos = nowLine;
316
317    //パラメータ
318    if(sourceOfParams[i]!='('){
319        compiler.errorMessenger.Output(1,NULL,nowLine);
320        return 0;
321    }
322    i++;
323    while(1){
324        if(sourceOfParams[i]==')') break;
325
326        //ByRef
327        bool isRef;
328        if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
329            isRef = false;
330            i+=2;
331        }
332        else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
333            isRef = true;
334            i+=2;
335        }
336        else isRef = false;
337
338        //パラメータ名
339        bool isArray = false;
340        Subscripts subscripts;
341        char name[VN_SIZE];
342        sw=0;
343        for(i2=0;;i++,i2++){
344            if(sourceOfParams[i]=='('){
345                if(!sw) sw=1;
346
347                i3=GetStringInPare(name+i2,sourceOfParams+i);
348                i2+=i3-1;
349                i+=i3-1;
350                continue;
351            }
352            if(sourceOfParams[i]=='['){
353                if(!sw) sw=1;
354
355                i3=GetStringInBracket(name+i2,sourceOfParams+i);
356                i2+=i3-1;
357                i+=i3-1;
358                continue;
359            }
360            if(!IsVariableChar(sourceOfParams[i])){
361                name[i2]=0;
362                break;
363            }
364            name[i2]=sourceOfParams[i];
365        }
366        if(sw){
367            //配列パラメータ
368            if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
369            isArray = true;
370
371            if((name[i2-2]=='('&&name[i2-1]==')')||
372                (name[i2-2]=='['&&name[i2-1]==']'))
373            {
374                subscripts.push_back( LONG_MAX );
375
376                name[i2-2]=0;
377            }
378            else{
379                GetArrange(name,temp2,subscripts);
380                lstrcpy(name,temp2);
381            }
382
383            i2=lstrlen(name);
384        }
385
386        //型
387        Type type( DEF_NON );
388        if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
389            i+=2;
390
391            i2=0;
392            while(sourceOfParams[i]=='*'){
393                temporary[i2]=sourceOfParams[i];
394                i++;
395                i2++;
396            }
397            for(;;i++,i2++){
398                if(!IsVariableChar(sourceOfParams[i])){
399                    if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
400                        temporary[i2++]=sourceOfParams[i++];
401                        temporary[i2]=sourceOfParams[i];
402                        continue;
403                    }
404                    temporary[i2]=0;
405                    break;
406                }
407                temporary[i2]=sourceOfParams[i];
408            }
409
410            compiler.StringToType( temporary, type );
411
412            if( type.IsNull() ){
413                compiler.errorMessenger.Output(3,temporary,nowLine);
414                type.SetBasicType( DEF_PTR_VOID );
415            }
416        }
417        else{
418            type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
419            compiler.errorMessenger.Output(-103,temporary,nowLine);
420        }
421
422        Parameter *pParam = new Parameter( name, type, isRef );
423        if( isArray ){
424            pParam->SetArray( subscripts );
425        }
426
427        //パラメータを追加
428        this->GetParameters().push_back( pParam );
429
430        if(sourceOfParams[i]==','){
431            i++;
432            continue;
433        }
434        else if(sourceOfParams[i]==')') continue;
435        else{
436            compiler.errorMessenger.Output(1,NULL,nowLine);
437            break;
438        }
439    }
440    i++;
441
442    if(sourceOfParams[i]){
443        ///////////////////
444        // 戻り値を取得
445        ///////////////////
446
447        i2=lstrlen(sourceOfParams)-2;
448
449        int sw_as=0;
450        for(;i2>0;i2--){
451            if(sourceOfParams[i2]==')') break;
452
453            if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
454                i2+=2;
455                i3=0;
456                while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
457                for(;;i2++,i3++){
458                    if(!IsVariableChar(sourceOfParams[i2])){
459                        temporary[i3]=0;
460                        break;
461                    }
462                    temporary[i3]=sourceOfParams[i2];
463                }
464                compiler.StringToType( temporary, this->returnType );
465                if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
466
467                sw_as=1;
468                break;
469            }
470        }
471    }
472    else{
473        //戻り値なしのSub定義
474        this->returnType.SetNull();
475    }
476
477    //戻り値のエラーチェック
478    if( IsFunction() ){
479        // Function定義
480
481        if( this->ReturnType().IsNull() ){
482            // 戻り値がない
483            compiler.errorMessenger.Output(26,this->GetName(),nowLine);
484        }
485    }
486    else{
487        if( !this->ReturnType().IsNull() ){
488            // Sub定義なのに、戻り値がある
489            compiler.errorMessenger.Output(38,this->GetName(),nowLine);
490        }
491    }
492
493    return true;
494}
495
496int ProcPointers::Add( const std::string &typeExpression )
497{
498    DWORD dwProcType = (DWORD)typeExpression[2];
499    const std::string &paramStr = typeExpression.substr( 3 );
500
501    Procedure::Kind kind = Procedure::Sub;
502    if( dwProcType == ESC_FUNCTION ){
503        kind = Procedure::Function;
504    }
505
506    ProcPointer *pProcPointer = new ProcPointer( kind );
507
508    //buffer[0]は'('となっている
509    extern int cp;
510    pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp );
511
512    this->push_back( pProcPointer );
513
514    return (int)this->size()-1;
515}
516
517void ProcPointers::Clear()
518{
519    ProcPointers &procPointers = *this;
520    BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
521        delete pProcPointer;
522    }
523    this->clear();
524}
Note: See TracBrowser for help on using the repository browser.