source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp @ 571

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

・LexicalAnalyzer::AnalyzeParameterの第二パラメータをstringからStringsに変更した。
・UserProc::SetParamsAndReturnTypeメソッド内で行っているパラメータ解析処理をLexicalAnalyzer::AnalyzeParameterメソッドを使用したコードに書き直した。

File size: 10.2 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5bool LexicalAnalyzer::AnalyzeParameter( Parameters &params, const Jenga::Common::Strings &parameterStrings, int nowLine )
6{
7    int i2,i3,sw;
8    char temporary[8192],temp2[VN_SIZE];
9
10    //パラメータ
11    BOOST_FOREACH( const std::string &paramStr, parameterStrings )
12    {
13        int i = 0;
14
15        if( paramStr[i] == '\0' )
16        {
17            break;
18        }
19
20        //ByRef
21        bool isRef;
22        if(paramStr[i]==1&&paramStr[i+1]==ESC_BYVAL){
23            isRef = false;
24            i+=2;
25        }
26        else if(paramStr[i]==1&&paramStr[i+1]==ESC_BYREF){
27            isRef = true;
28            i+=2;
29        }
30        else isRef = false;
31
32        //パラメータ名
33        bool isArray = false;
34        Subscripts subscripts;
35        char name[VN_SIZE];
36        sw=0;
37        for(i2=0;;i++,i2++){
38            if(paramStr[i]=='('){
39                if(!sw) sw=1;
40
41                i3=GetStringInPare(name+i2,paramStr.c_str()+i);
42                i2+=i3-1;
43                i+=i3-1;
44                continue;
45            }
46            if(paramStr[i]=='['){
47                if(!sw) sw=1;
48
49                i3=GetStringInBracket(name+i2,paramStr.c_str()+i);
50                i2+=i3-1;
51                i+=i3-1;
52                continue;
53            }
54            if(!IsVariableChar(paramStr[i])){
55                name[i2]=0;
56                break;
57            }
58            name[i2]=paramStr[i];
59        }
60        if(sw){
61            //配列パラメータ
62            if( isRef == false )
63            {
64                compiler.errorMessenger.Output(29,NULL,nowLine);
65            }
66            isArray = true;
67
68            if((name[i2-2]=='('&&name[i2-1]==')')||
69                (name[i2-2]=='['&&name[i2-1]==']'))
70            {
71                subscripts.push_back( LONG_MAX );
72
73                name[i2-2]=0;
74            }
75            else{
76                GetArrange(name,temp2,subscripts);
77                lstrcpy(name,temp2);
78            }
79
80            i2=lstrlen(name);
81        }
82
83        Type type( DEF_NON );
84        char initValue[8192] = "";
85        if( paramStr[i] == '=' ){
86            i++;
87            i = GetOneParameter( paramStr.c_str(), i, initValue );
88
89            // TODO: エラー用 fix me!!!
90            //cp = nowLine;
91
92            NumOpe_GetType( initValue, GetStringTypeInfo(), type );
93           
94            if( IS_LITERAL(type.GetIndex()) )
95            {
96                type.SetIndex( -1 );
97            }
98        }
99        else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
100            // As指定
101            i+=2;
102
103            i2=0;
104            while(paramStr[i]=='*'){
105                temporary[i2]=paramStr[i];
106                i++;
107                i2++;
108            }
109            for(;;i++,i2++){
110                if(!IsVariableChar(paramStr[i])){
111                    if(paramStr[i]==1&&(paramStr[i+1]==ESC_FUNCTION||paramStr[i+1]==ESC_SUB)){
112                        temporary[i2++]=paramStr[i++];
113                        temporary[i2]=paramStr[i];
114                        continue;
115                    }
116                    temporary[i2]=0;
117                    break;
118                }
119                temporary[i2]=paramStr[i];
120            }
121
122            compiler.StringToType( temporary, type );
123
124            if( type.IsNull() ){
125                compiler.errorMessenger.Output(3,temporary,nowLine);
126                type.SetBasicType( DEF_PTR_VOID );
127            }
128
129            if( type.IsObject() ){
130                if( type.GetClass().IsBlittableType() ){
131                    // Blittable型のときは基本型として扱う
132                    type = type.GetClass().GetBlittableType();
133                }
134            }
135        }
136        else{
137            type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
138            compiler.errorMessenger.Output(-103,temporary,nowLine);
139        }
140
141        Parameter *pParam = new Parameter( name, type, isRef, initValue );
142        if( isArray ){
143            pParam->SetArray( subscripts );
144        }
145
146        //パラメータを追加
147        params.push_back( pParam );
148    }
149
150    return true;
151}
152
153UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
154{
155    int i2,i3;
156    char temporary[8192];
157
158    int i=1;
159
160    Procedure::Kind kind = Procedure::Sub;
161    bool isMacro = false;
162    if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
163    if(buffer[i]==ESC_MACRO){
164        isMacro = true;
165    }
166
167    i++;
168
169    bool isCdecl = false;
170    bool isExport = false;
171    while(1){
172        if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
173            isCdecl = true;
174
175            i+=2;
176        }
177        else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
178            isExport = true;
179
180            i+=2;
181        }
182        else break;
183    }
184
185    i2=0;
186    if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
187        if(!pobj_c){
188            compiler.errorMessenger.Output(126,NULL,nowLine);
189            return 0;
190        }
191
192        //オペレータの場合
193        temporary[i2++]=buffer[i++];
194        temporary[i2++]=buffer[i++];
195
196        int iCalcId;
197        if(buffer[i]=='='&&buffer[i+1]=='='){
198            iCalcId=CALC_EQUAL;
199            i3=2;
200        }
201        else if(buffer[i]=='='){
202            iCalcId=CALC_SUBSITUATION;
203            i3=1;
204        }
205        else if(buffer[i]=='('){
206            iCalcId=CALC_AS;
207            i3=0;
208        }
209        else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
210            iCalcId=CALC_ARRAY_SET;
211            i3=3;
212        }
213        else if(buffer[i]=='['&&buffer[i+1]==']'){
214            iCalcId=CALC_ARRAY_GET;
215            i3=2;
216        }
217        else{
218            iCalcId=GetCalcId(buffer+i,&i3);
219            i3++;
220        }
221        if(!iCalcId){
222            compiler.errorMessenger.Output(1,NULL,nowLine);
223            return 0;
224        }
225        temporary[i2++]=iCalcId;
226        temporary[i2]=0;
227
228        i+=i3;
229    }
230    else{
231        if(pobj_c){
232            //クラスメンバの場合、デストラクタには~が付くことを考慮
233            if(buffer[i]=='~'){
234                temporary[i2]='~';
235                i++;
236                i2++;
237            }
238        }
239
240        for(;;i++,i2++){
241            if(!IsVariableChar(buffer[i])){
242                temporary[i2]=0;
243                break;
244            }
245            temporary[i2]=buffer[i];
246        }
247
248        char parentName[VN_SIZE], memberName[VN_SIZE];
249        ReferenceKind refKind;
250        if( SplitMemberName( temporary, parentName, memberName, refKind ) )
251        {
252            if( pobj_c )
253            {
254                if( interfaceName )
255                {
256                    lstrcpy( interfaceName, parentName );
257                }
258                else
259                {
260                    compiler.errorMessenger.OutputFatalError();
261                    return NULL;
262                }
263
264                char dummyMemberName[VN_SIZE];
265                if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
266                {
267                    compiler.errorMessenger.Output(69,temporary,nowLine);
268                    return NULL;
269                }
270            }
271            else
272            {
273                compiler.errorMessenger.Output(68,temporary,nowLine);
274                return NULL;
275            }
276
277            lstrcpy( temporary, memberName );
278        }
279    }
280
281    if( isMacro ){
282        //大文字に変換
283        CharUpper(temporary);
284    }
285
286    if(!pobj_c){
287        //クラスメンバ以外の場合のみ
288        //重複チェック
289
290        if(GetDeclareHash(temporary)){
291            compiler.errorMessenger.Output(15,temporary,nowLine);
292            return 0;
293        }
294    }
295
296    UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
297    pUserProc->SetParentClass( pobj_c );
298
299    // 親インターフェイスをセット
300    if( interfaceName && interfaceName[0] )
301    {
302        ::Interface *pTargetInterface = NULL;
303        BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
304        {
305            if( pInterface->GetClass().GetName() == interfaceName )
306            {
307                pTargetInterface = pInterface;
308                break;
309            }
310        }
311        pUserProc->SetInterface( pTargetInterface );
312    }
313
314    if(isExport){
315        pUserProc->Using();
316    }
317
318    // パラメータを解析
319    // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
320    pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
321
322    pUserProc->_paramStr = buffer + i;
323
324    return pUserProc;
325}
326
327void LexicalAnalyzer::CollectProcedures( const char *source, UserProcs &userProcs, DllProcs &dllProcs )
328{
329    extern HANDLE hHeap;
330    int i,i2,i3;
331    char temporary[8192];
332
333    // 名前空間管理
334    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
335    namespaceScopes.clear();
336
337    // Importsされた名前空間の管理
338    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
339    importedNamespaces.clear();
340
341    i=-1;
342    while(1){
343        i++;
344
345        if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
346            /*  Class ~ End Class
347                Interface ~ End Interface
348                を飛び越す           */
349            i3=GetEndXXXCommand(source[i+1]);
350            for(i+=2,i2=0;;i++,i2++){
351                if(source[i]=='\0') break;
352                if(source[i]==1&&source[i+1]==(char)i3){
353                    i++;
354                    break;
355                }
356            }
357            if(source[i]=='\0') break;
358            continue;
359        }
360
361        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
362            for(i+=2,i2=0;;i2++,i++){
363                if( IsCommandDelimitation( source[i] ) ){
364                    temporary[i2]=0;
365                    break;
366                }
367                temporary[i2]=source[i];
368            }
369            namespaceScopes.push_back( temporary );
370
371            continue;
372        }
373        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
374            if( namespaceScopes.size() <= 0 ){
375                compiler.errorMessenger.Output(12, "End Namespace", i );
376            }
377            else{
378                namespaceScopes.pop_back();
379            }
380
381            i += 2;
382            continue;
383        }
384        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
385            for(i+=2,i2=0;;i2++,i++){
386                if( IsCommandDelimitation( source[i] ) ){
387                    temporary[i2]=0;
388                    break;
389                }
390                temporary[i2]=source[i];
391            }
392            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
393            {
394                compiler.errorMessenger.Output(64,temporary,cp );
395            }
396
397            continue;
398        }
399        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
400            importedNamespaces.clear();
401            continue;
402        }
403
404        if(source[i]==1&&source[i+1]==ESC_DECLARE){
405            for(i+=2,i2=0;;i2++,i++){
406                if(source[i]=='\n'){
407                    temporary[i2]=0;
408                    break;
409                }
410                temporary[i2]=source[i];
411                if(source[i]=='\0') break;
412            }
413            dllProcs.Add(namespaceScopes,temporary,i);
414
415            continue;
416        }
417        if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
418            char statementChar = source[i+1];
419
420            for(i2=0;;i2++,i++){
421                if(IsCommandDelimitation(source[i])){
422                    temporary[i2]=0;
423                    break;
424                }
425                temporary[i2]=source[i];
426                if(source[i]=='\0') break;
427            }
428
429            UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
430            userProcs.Insert( pUserProc, i );
431
432            /*  Sub ~ End Sub
433                Function ~ End Function
434                Macro ~ End Macro
435                を飛び越す           */
436            char endStatementChar = GetEndXXXCommand( statementChar );
437            for(i2=0;;i++,i2++){
438                if( source[i] == '\0' ) break;
439                if( source[i] == 1 && source[i+1] == endStatementChar ){
440                    i++;
441                    break;
442                }
443            }
444            if(source[i]=='\0') break;
445            continue;
446        }
447
448        //次の行
449        for(;;i++){
450            if(IsCommandDelimitation(source[i])) break;
451        }
452        if(source[i]=='\0') break;
453    }
454
455    ////////////
456    // 特殊関数
457    ////////////
458    namespaceScopes.clear();
459    importedNamespaces.clear();
460
461    compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
462    sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
463    UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
464    userProcs.Insert( pUserProc, i );
465}
Note: See TracBrowser for help on using the repository browser.