source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Enum.cpp@ 648

Last change on this file since 648 was 547, checked in by dai_9181, 16 years ago

Enum収集をLexicalAnalyzerクラスに実装しなおした。

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