source: dev/trunk/abdev/BasicCompiler_Common/Enum.cpp@ 406

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

Enumを大改修。Enumメンバ初期値にリテラル、定数、Enumメンバを指定できるようにした。また、エラー行数を正確に表示可能にした。

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