source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Enum.cpp @ 523

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

ヘッダファイルを整理中

File size: 5.7 KB
Line 
1#include "stdafx.h"
2
3void EnumInfo::Collect( const char *buffer,int nowLine)
4{
5    this->members.clear();
6
7    int i=nowLine,i2;
8
9    if(!(buffer[i]==1&&buffer[i+1]==ESC_ENUM)) return;
10    i+=2;
11
12    //列挙体の名前を取得
13    char temporary[VN_SIZE];
14    for(i2=0;;i++,i2++){
15        if(IsCommandDelimitation(buffer[i])){
16            temporary[i2]=0;
17            break;
18        }
19        if(!IsVariableChar(buffer[i])){
20            compiler.errorMessenger.Output(1,NULL,i);
21            break;
22        }
23        temporary[i2]=buffer[i];
24    }
25
26    if(buffer[i]=='\0'){
27        compiler.errorMessenger.Output(22,"Enum",nowLine);
28        return;
29    }
30
31    int currentValue = 0;
32    bool isUseCurrentValue = true;
33    std::string currentValueStr;
34    std::string lastMemberName;
35    char temp2[VN_SIZE];
36    while(1){
37        i++;
38
39        if(buffer[i]==1&&buffer[i+1]==ESC_ENDENUM) break;
40
41        for(i2=0;;i2++,i++){
42            if(IsCommandDelimitation(buffer[i])){
43                temporary[i2]=0;
44                break;
45            }
46            if(buffer[i]=='='){
47                temporary[i2]=0;
48                break;
49            }
50            temporary[i2]=buffer[i];
51        }
52        if(temporary[0]=='\0'){
53            if(buffer[i]=='\0'){
54                compiler.errorMessenger.Output(22,"Enum",nowLine);
55                break;
56            }
57            continue;
58        }
59
60        if( buffer[i] != '=' )
61        {
62            if( isUseCurrentValue )
63            {
64                currentValue++;
65
66                sprintf( temp2, "%d", currentValue );
67                currentValueStr = temp2;
68            }
69            else
70            {
71                currentValueStr = lastMemberName + "+1";
72            }
73        }
74        else
75        {
76            i++;
77            GetCommandToken( temp2, buffer, i );
78
79            _int64 i64data;
80            if( StaticCalculation( false, temp2, 0, &i64data, Type() ) )
81            {
82                currentValue = static_cast<int>(i64data);
83
84                sprintf( temp2, "%d", currentValue );
85                currentValueStr = temp2;
86            }
87            else
88            {
89                // 取得できなかった(なんらかの識別子を含む可能性あり)
90                isUseCurrentValue = false;
91
92                currentValueStr = temp2;
93            }
94        }
95
96        //メンバを追加
97        this->members.push_back( EnumMember( temporary, currentValueStr, i ) );
98
99        lastMemberName = temporary;
100    }
101}
102
103
104void EnumInfoCollection::InitEnum(void)
105{
106    this->clear();
107
108    const char *source = compiler.GetObjectModule().GetCurrentSource().GetBuffer();
109
110    // 名前空間管理
111    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
112    namespaceScopes.clear();
113
114    int i2;
115    char temporary[VN_SIZE];
116    for(int i=0;;i++){
117        if(source[i]=='\0') break;
118
119        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
120            for(i+=2,i2=0;;i2++,i++){
121                if( IsCommandDelimitation( source[i] ) ){
122                    temporary[i2]=0;
123                    break;
124                }
125                temporary[i2]=source[i];
126            }
127            namespaceScopes.push_back( temporary );
128
129            continue;
130        }
131        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
132            if( namespaceScopes.size() <= 0 ){
133                compiler.errorMessenger.Output(12, "End Namespace", i );
134            }
135            else{
136                namespaceScopes.pop_back();
137            }
138
139            i += 2;
140            continue;
141        }
142
143        if(source[i]==1&&source[i+1]==ESC_ENUM){
144            if(i>=2){
145                if(source[i-2]==1&&source[i-1]==ESC_CONST) continue;
146            }
147
148            i2 = i + 2;
149            GetCommandToken( temporary, source, i2 );
150
151            // 追加
152            this->push_back( EnumInfo( namespaceScopes, temporary ) );
153
154            // 収集
155            this->back().Collect( source, i );
156        }
157    }
158}
159
160char *EnumInfoCollection::GenerateSourceCode(void){
161    char *buffer;
162    int MaxSize,length;
163    MaxSize=65535;
164    buffer=(char *)HeapAlloc(hHeap,0,MaxSize+65535);
165    length=0;
166
167    buffer[0]=0;
168
169    const EnumInfoCollection &thisEnumInfoCollection = *this;
170    BOOST_FOREACH( const EnumInfo &enumInfo, thisEnumInfoCollection )
171    {
172        BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){
173            sprintf(buffer+length,"Namespace %s\n",namespaceStr.c_str());
174            length+=lstrlen(buffer+length);
175        }
176
177        sprintf(buffer+length,"Class Enum %s\n",enumInfo.GetName().c_str());
178        length+=lstrlen(buffer+length);
179        sprintf(buffer+length,"\tInherits EnumBase<%s>\n",enumInfo.GetName().c_str());
180        length+=lstrlen(buffer+length);
181        sprintf(buffer+length,"\tSub %s(value As Long,lpszName As LPSTR)\n",enumInfo.GetName().c_str());
182        length+=lstrlen(buffer+length);
183        lstrcpy(buffer+length,"\t\tEnumBase(value,lpszName)\n");
184        length+=lstrlen(buffer+length);
185        lstrcpy(buffer+length,"\tEnd Sub\n");
186        length+=lstrlen(buffer+length);
187        lstrcpy(buffer+length,"Public\n");
188        length+=lstrlen(buffer+length);
189        sprintf(buffer+length,"\tSub %s()\n",enumInfo.GetName().c_str());
190        length+=lstrlen(buffer+length);
191        if( enumInfo.GetMembers().size()){
192            sprintf(buffer+length,"\t\tEnumBase(%s)\n",
193                enumInfo.GetMembers().begin()->GetName().c_str() );
194            length+=lstrlen(buffer+length);
195        }
196        lstrcpy(buffer+length,"\tEnd Sub\n");
197        length+=lstrlen(buffer+length);
198        sprintf(buffer+length,"\tSub ~%s()\n",enumInfo.GetName().c_str());
199        length+=lstrlen(buffer+length);
200        lstrcpy(buffer+length,"\tEnd Sub\n");
201        length+=lstrlen(buffer+length);
202
203        BOOST_FOREACH( const EnumMember &member, enumInfo.GetMembers() )
204        {
205            sprintf(buffer+length,"\tStatic %s As %s((%s) As Long,\"%s\")\n",
206                member.GetName().c_str(),
207                enumInfo.GetName().c_str(),
208                member.GetValueStr().c_str(),
209                member.GetName().c_str());
210            length+=lstrlen(buffer+length);
211        }
212
213        lstrcpy(buffer+length,"End Class\n");
214        length+=lstrlen(buffer+length);
215
216        BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){
217            lstrcpy( buffer+length, "End Namespace\n" );
218            length+=lstrlen(buffer+length);
219        }
220
221
222        //バッファ領域が足りなくなった場合はバッファを増量する
223        if(length>MaxSize){
224            MaxSize+=65535;
225            buffer=(char *)HeapReAlloc(hHeap,0,buffer,MaxSize+65535);
226        }
227    }
228
229#ifdef _DEBUG
230    // ログを生成
231    Jenga::Common::Logger logger( Jenga::Common::Environment::GetAppDir() + "\\enum_generated.log", false );
232    logger << buffer << std::endl;
233#endif
234
235    return buffer;
236}
Note: See TracBrowser for help on using the repository browser.