source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Enum.cpp

Last change on this file was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 4.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 std::string buffer;
160 buffer.reserve(65536);
161
162 foreach( const EnumInfo &enumInfo, enums )
163 {
164 foreach( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){
165 buffer.append("Namespace ").append(namespaceStr) += '\n';
166 }
167
168 buffer.append("Class Enum ").append(enumInfo.GetName()) += '\n';
169 buffer.append("\tInherits EnumBase<").append(enumInfo.GetName()).append(">\n");
170 buffer.append("\tSub ").append(enumInfo.GetName()).append("(value As Long,lpszName As LPCTSTR)\n");
171 buffer.append("\t\tEnumBase(value,lpszName)\n"
172 "\tEnd Sub\n"
173 "Public\n");
174 buffer.append("\tSub ").append(enumInfo.GetName()).append("()\n");
175 if( !enumInfo.GetMembers().empty() ){
176 buffer.append("\t\tEnumBase(").append(enumInfo.GetMembers().front().GetName())
177 .append(")\n");
178 }
179 buffer.append("\tEnd Sub\n");
180
181 foreach( const EnumMember &member, enumInfo.GetMembers() )
182 {
183 buffer.append("\tStatic ")
184 .append(member.GetName()).append(" As ")
185 .append(enumInfo.GetName()).append("((")
186 .append(member.GetValueStr()).append(") As Long,\"")
187 .append(member.GetName()).append("\")\n");
188 }
189
190 buffer.append("End Class\n");
191
192 foreach( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){
193 buffer.append("End Namespace\n");
194 }
195 }
196
197#ifdef _DEBUG
198 // ログを生成
199 Jenga::Common::Logger logger( Jenga::Common::Environment::GetAppDir() + "\\enum_generated.log", false );
200 logger << buffer << std::endl;
201#endif
202 return buffer;
203}
Note: See TracBrowser for help on using the repository browser.