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

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

LexicalAnalyzer周りの修正

File size: 6.2 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5void LexicalAnalyzer::AddConstEnum( Consts &consts, const NamespaceScopes &namespaceScopes, const char *buffer )
6{
7 extern int cp;
8 int i=0,i2;
9
10 if(!(buffer[i]==1&&buffer[i+1]==ESC_ENUM)) return;
11 i+=2;
12
13 //列挙体の名前を取得
14 char temporary[VN_SIZE];
15 for(i2=0;;i++,i2++){
16 if(IsCommandDelimitation(buffer[i])){
17 temporary[i2]=0;
18 break;
19 }
20 if(!IsVariableChar(buffer[i])){
21 compiler.errorMessenger.Output(1,NULL,i);
22 break;
23 }
24 temporary[i2]=buffer[i];
25 }
26
27 if(buffer[i]=='\0'){
28 compiler.errorMessenger.Output(22,"Enum",cp);
29 return;
30 }
31
32 int NextValue=0;
33 while(1){
34 i++;
35
36 if(buffer[i]==1&&buffer[i+1]==ESC_ENDENUM) break;
37
38 for(i2=0;;i2++,i++){
39 if(IsCommandDelimitation(buffer[i])){
40 temporary[i2]=0;
41 break;
42 }
43 if(buffer[i]=='='){
44 temporary[i2]=0;
45 break;
46 }
47 temporary[i2]=buffer[i];
48 }
49 if(temporary[0]=='\0'){
50 if(buffer[i]=='\0'){
51 compiler.errorMessenger.Output(22,"Enum",cp);
52 break;
53 }
54 continue;
55 }
56
57 if(buffer[i]!='='){
58 NextValue++;
59 }
60 else{
61 char temp2[VN_SIZE];
62 for(i++,i2=0;;i2++,i++){
63 if(IsCommandDelimitation(buffer[i])){
64 temp2[i2]=0;
65 break;
66 }
67 temp2[i2]=buffer[i];
68 }
69
70 _int64 i64data;
71 StaticCalculation(true, temp2,DEF_LONG,&i64data,Type());
72 NextValue=(int)i64data;
73 }
74
75 //定数を追加
76 consts.Add( Symbol( namespaceScopes, temporary ), NextValue);
77 }
78}
79
80void LexicalAnalyzer::CollectConsts( const char *source, Consts &consts, ConstMacros &constMacros )
81{
82 ////////////////////////////////////////////
83 // Const命令の情報を取得
84 ////////////////////////////////////////////
85
86 int i2;
87
88 // 名前空間管理
89 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
90 namespaceScopes.clear();
91
92 for (int i = 0; ; ++i)
93 {
94 if( source[i] == '\0' ) break;
95
96 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
97 i+=2;
98 char const* p = &source[i];
99 while (!IsCommandDelimitation(source[i]))
100 {
101 ++i;
102 }
103 namespaceScopes.push_back(std::string(p, &source[i]));
104
105 continue;
106 }
107 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
108 if( namespaceScopes.size() <= 0 ){
109 compiler.errorMessenger.Output(12, "End Namespace", i );
110 }
111 else{
112 namespaceScopes.pop_back();
113 }
114
115 i += 2;
116 continue;
117 }
118
119 if( source[i] == 1 ){
120 if(source[i]==1&&source[i+1]==ESC_CONST){
121 i+=2;
122
123 extern int cp;
124 cp=i; //エラー用
125
126
127 if(source[i]==1&&source[i+1]==ESC_ENUM){
128 AddConstEnum( consts, namespaceScopes, source+i);
129 continue;
130 }
131
132 char const* beginTemp = &source[i];
133 char const* endTemp = &source[i];
134
135 for(i2=0;;i++,i2++){
136 if(source[i]=='\"'){
137 for(i++,i2++;;i++,i2++){
138 if(source[i]=='\"') break;
139 }
140 continue;
141 }
142 if(IsCommandDelimitation(source[i])){
143 endTemp = beginTemp + i2;
144 break;
145 }
146 }
147
148 //名前を取得
149 char const* nameEnd;
150 for(i2=0;;i2++){
151 if(beginTemp[i2]=='\0'){
152 compiler.errorMessenger.Output(10,"Const",cp);
153 return;
154 }
155 if(beginTemp[i2]=='='||beginTemp[i2]=='('){
156 nameEnd = beginTemp + i2;
157 break;
158 }
159 }
160 std::string name(beginTemp, nameEnd);
161
162 //重複チェック
163 if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExistDuplicationKeyName( name )
164 || compiler.GetObjectModule().meta.GetGlobalConsts().IsExistDuplicationKeyName( name ) )
165 {
166 compiler.errorMessenger.Output(15, name, cp);
167 return;
168 }
169
170 if( beginTemp[i2] == '=' )
171 {
172 // 定数
173 std::string expression(beginTemp + i2 + 1, endTemp);
174
175 _int64 i64data;
176 Type resultType;
177 if( StaticCalculation(false, expression.c_str(), 0, &i64data, resultType) )
178 {
179 consts.Add( Symbol( namespaceScopes, name ), i64data, resultType );
180 }
181 }
182 else
183 {
184 // 定数マクロ
185 std::string params(beginTemp + i2, endTemp);
186 if( !constMacros.Add( Symbol( namespaceScopes, name ), params.c_str() ) )
187 {
188 compiler.errorMessenger.Output( 1, NULL, i );
189 }
190 }
191
192 if(source[i]=='\0') break;
193 }
194 else{
195 int result = JumpStatement( source, i );
196 if( result == -1 ){
197 //エラー
198 return;
199 }
200 else if( result == 1 ){
201 //ジャンプした場合
202 i--;
203 }
204 }
205 }
206 }
207}
208
209bool LexicalAnalyzer::ConstMacroToExpression( const ConstMacro &constMacro, const char *parameterStr, char *dest, std::size_t destSize )
210{
211 std::string s;
212 auto ret = ConstMacroToExpression(constMacro, parameterStr, s);
213 strcpy_s(dest, destSize, s.c_str());
214 return ret;
215}
216
217bool LexicalAnalyzer::ConstMacroToExpression( const ConstMacro &constMacro, const char *parameterStr, std::string& dest )
218{
219 int i2,i3;
220 char temporary[VN_SIZE];
221 std::vector<std::string> Parms;
222 dest.reserve(8192);
223 i2=0;
224 while(1){
225 i2=GetOneParameter(parameterStr,i2,temporary);
226
227 Parms.push_back(temporary);
228
229 if(parameterStr[i2]=='\0') break;
230 }
231 if( Parms.size() != constMacro.GetParameters().size() ){
232 extern int cp;
233 compiler.errorMessenger.Output(10,constMacro.GetName().c_str(),cp);
234 dest = '0';
235 return true;
236 }
237
238 i2=0;
239 while(1){
240
241 //数式内の項を取得
242 for(i3=0;;i2++,i3++){
243 if(!IsVariableChar( constMacro.GetExpression()[i2] )){
244 temporary[i3]=0;
245 break;
246 }
247 temporary[i3] = constMacro.GetExpression()[i2];
248 }
249
250 //パラメータと照合する
251 for( i3=0; i3<(int)constMacro.GetParameters().size(); i3++ ){
252 if( constMacro.GetParameters()[i3] == temporary ) break;
253 }
254
255 if( i3 == (int)constMacro.GetParameters().size() ){
256 //パラメータでないとき
257 dest += temporary;
258 }
259 else{
260 //パラメータのとき
261 dest += Parms[i3];
262 }
263
264 //演算子をコピー
265 for(;;i2++){
266 if( constMacro.GetExpression()[i2] == 1 ){
267 dest += constMacro.GetExpression()[i2++];
268 dest += constMacro.GetExpression()[i2];
269 continue;
270 }
271 if(IsVariableTopChar( constMacro.GetExpression()[i2] )) break;
272 dest += constMacro.GetExpression()[i2];
273 if( constMacro.GetExpression()[i2] == '\0' ) break;
274 }
275
276 if( constMacro.GetExpression()[i2] == '\0' ) break;
277 }
278
279 return true;
280}
Note: See TracBrowser for help on using the repository browser.