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

Last change on this file since 483 was 465, checked in by dai_9181, 17 years ago

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

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 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 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 << endl;
233#endif
234
235 return buffer;
236}
Note: See TracBrowser for help on using the repository browser.