source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp@ 571

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

・LexicalAnalyzer::AnalyzeParameterの第二パラメータをstringからStringsに変更した。
・UserProc::SetParamsAndReturnTypeメソッド内で行っているパラメータ解析処理をLexicalAnalyzer::AnalyzeParameterメソッドを使用したコードに書き直した。

File size: 10.2 KB
RevLine 
[546]1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
[571]5bool LexicalAnalyzer::AnalyzeParameter( Parameters &params, const Jenga::Common::Strings &parameterStrings, int nowLine )
[568]6{
7 int i2,i3,sw;
8 char temporary[8192],temp2[VN_SIZE];
9
10 //パラメータ
[571]11 BOOST_FOREACH( const std::string &paramStr, parameterStrings )
12 {
13 int i = 0;
14
15 if( paramStr[i] == '\0' )
[568]16 {
17 break;
18 }
19
20 //ByRef
21 bool isRef;
[571]22 if(paramStr[i]==1&&paramStr[i+1]==ESC_BYVAL){
[568]23 isRef = false;
24 i+=2;
25 }
[571]26 else if(paramStr[i]==1&&paramStr[i+1]==ESC_BYREF){
[568]27 isRef = true;
28 i+=2;
29 }
30 else isRef = false;
31
32 //パラメータ名
33 bool isArray = false;
34 Subscripts subscripts;
35 char name[VN_SIZE];
36 sw=0;
37 for(i2=0;;i++,i2++){
[571]38 if(paramStr[i]=='('){
[568]39 if(!sw) sw=1;
40
[571]41 i3=GetStringInPare(name+i2,paramStr.c_str()+i);
[568]42 i2+=i3-1;
43 i+=i3-1;
44 continue;
45 }
[571]46 if(paramStr[i]=='['){
[568]47 if(!sw) sw=1;
48
[571]49 i3=GetStringInBracket(name+i2,paramStr.c_str()+i);
[568]50 i2+=i3-1;
51 i+=i3-1;
52 continue;
53 }
[571]54 if(!IsVariableChar(paramStr[i])){
[568]55 name[i2]=0;
56 break;
57 }
[571]58 name[i2]=paramStr[i];
[568]59 }
60 if(sw){
61 //配列パラメータ
62 if( isRef == false )
63 {
64 compiler.errorMessenger.Output(29,NULL,nowLine);
65 }
66 isArray = true;
67
68 if((name[i2-2]=='('&&name[i2-1]==')')||
69 (name[i2-2]=='['&&name[i2-1]==']'))
70 {
71 subscripts.push_back( LONG_MAX );
72
73 name[i2-2]=0;
74 }
75 else{
76 GetArrange(name,temp2,subscripts);
77 lstrcpy(name,temp2);
78 }
79
80 i2=lstrlen(name);
81 }
82
83 Type type( DEF_NON );
84 char initValue[8192] = "";
[571]85 if( paramStr[i] == '=' ){
[568]86 i++;
[571]87 i = GetOneParameter( paramStr.c_str(), i, initValue );
[568]88
89 // TODO: エラー用 fix me!!!
90 //cp = nowLine;
91
92 NumOpe_GetType( initValue, GetStringTypeInfo(), type );
93
94 if( IS_LITERAL(type.GetIndex()) )
95 {
96 type.SetIndex( -1 );
97 }
98 }
[571]99 else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
[568]100 // As指定
101 i+=2;
102
103 i2=0;
[571]104 while(paramStr[i]=='*'){
105 temporary[i2]=paramStr[i];
[568]106 i++;
107 i2++;
108 }
109 for(;;i++,i2++){
[571]110 if(!IsVariableChar(paramStr[i])){
111 if(paramStr[i]==1&&(paramStr[i+1]==ESC_FUNCTION||paramStr[i+1]==ESC_SUB)){
112 temporary[i2++]=paramStr[i++];
113 temporary[i2]=paramStr[i];
[568]114 continue;
115 }
116 temporary[i2]=0;
117 break;
118 }
[571]119 temporary[i2]=paramStr[i];
[568]120 }
121
122 compiler.StringToType( temporary, type );
123
124 if( type.IsNull() ){
125 compiler.errorMessenger.Output(3,temporary,nowLine);
126 type.SetBasicType( DEF_PTR_VOID );
127 }
128
129 if( type.IsObject() ){
130 if( type.GetClass().IsBlittableType() ){
131 // Blittable型のときは基本型として扱う
132 type = type.GetClass().GetBlittableType();
133 }
134 }
135 }
136 else{
137 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
138 compiler.errorMessenger.Output(-103,temporary,nowLine);
139 }
140
141 Parameter *pParam = new Parameter( name, type, isRef, initValue );
142 if( isArray ){
143 pParam->SetArray( subscripts );
144 }
145
146 //パラメータを追加
147 params.push_back( pParam );
148 }
149
150 return true;
151}
152
[546]153UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
154{
155 int i2,i3;
156 char temporary[8192];
157
158 int i=1;
159
160 Procedure::Kind kind = Procedure::Sub;
161 bool isMacro = false;
162 if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
163 if(buffer[i]==ESC_MACRO){
164 isMacro = true;
165 }
166
167 i++;
168
169 bool isCdecl = false;
170 bool isExport = false;
171 while(1){
172 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
173 isCdecl = true;
174
175 i+=2;
176 }
177 else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
178 isExport = true;
179
180 i+=2;
181 }
182 else break;
183 }
184
185 i2=0;
186 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
187 if(!pobj_c){
188 compiler.errorMessenger.Output(126,NULL,nowLine);
189 return 0;
190 }
191
192 //オペレータの場合
193 temporary[i2++]=buffer[i++];
194 temporary[i2++]=buffer[i++];
195
196 int iCalcId;
197 if(buffer[i]=='='&&buffer[i+1]=='='){
198 iCalcId=CALC_EQUAL;
199 i3=2;
200 }
201 else if(buffer[i]=='='){
202 iCalcId=CALC_SUBSITUATION;
203 i3=1;
204 }
205 else if(buffer[i]=='('){
206 iCalcId=CALC_AS;
207 i3=0;
208 }
209 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
210 iCalcId=CALC_ARRAY_SET;
211 i3=3;
212 }
213 else if(buffer[i]=='['&&buffer[i+1]==']'){
214 iCalcId=CALC_ARRAY_GET;
215 i3=2;
216 }
217 else{
218 iCalcId=GetCalcId(buffer+i,&i3);
219 i3++;
220 }
221 if(!iCalcId){
222 compiler.errorMessenger.Output(1,NULL,nowLine);
223 return 0;
224 }
225 temporary[i2++]=iCalcId;
226 temporary[i2]=0;
227
228 i+=i3;
229 }
230 else{
231 if(pobj_c){
232 //クラスメンバの場合、デストラクタには~が付くことを考慮
233 if(buffer[i]=='~'){
234 temporary[i2]='~';
235 i++;
236 i2++;
237 }
238 }
239
240 for(;;i++,i2++){
241 if(!IsVariableChar(buffer[i])){
242 temporary[i2]=0;
243 break;
244 }
245 temporary[i2]=buffer[i];
246 }
247
248 char parentName[VN_SIZE], memberName[VN_SIZE];
249 ReferenceKind refKind;
250 if( SplitMemberName( temporary, parentName, memberName, refKind ) )
251 {
252 if( pobj_c )
253 {
254 if( interfaceName )
255 {
256 lstrcpy( interfaceName, parentName );
257 }
258 else
259 {
260 compiler.errorMessenger.OutputFatalError();
261 return NULL;
262 }
263
264 char dummyMemberName[VN_SIZE];
265 if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
266 {
267 compiler.errorMessenger.Output(69,temporary,nowLine);
268 return NULL;
269 }
270 }
271 else
272 {
273 compiler.errorMessenger.Output(68,temporary,nowLine);
274 return NULL;
275 }
276
277 lstrcpy( temporary, memberName );
278 }
279 }
280
281 if( isMacro ){
282 //大文字に変換
283 CharUpper(temporary);
284 }
285
286 if(!pobj_c){
287 //クラスメンバ以外の場合のみ
288 //重複チェック
289
290 if(GetDeclareHash(temporary)){
291 compiler.errorMessenger.Output(15,temporary,nowLine);
292 return 0;
293 }
294 }
295
296 UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
297 pUserProc->SetParentClass( pobj_c );
298
299 // 親インターフェイスをセット
300 if( interfaceName && interfaceName[0] )
301 {
302 ::Interface *pTargetInterface = NULL;
303 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
304 {
305 if( pInterface->GetClass().GetName() == interfaceName )
306 {
307 pTargetInterface = pInterface;
308 break;
309 }
310 }
311 pUserProc->SetInterface( pTargetInterface );
312 }
313
314 if(isExport){
315 pUserProc->Using();
316 }
317
318 // パラメータを解析
319 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
320 pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
321
322 pUserProc->_paramStr = buffer + i;
323
324 return pUserProc;
325}
326
[552]327void LexicalAnalyzer::CollectProcedures( const char *source, UserProcs &userProcs, DllProcs &dllProcs )
[546]328{
329 extern HANDLE hHeap;
330 int i,i2,i3;
331 char temporary[8192];
332
333 // 名前空間管理
334 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
335 namespaceScopes.clear();
336
337 // Importsされた名前空間の管理
338 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
339 importedNamespaces.clear();
340
341 i=-1;
342 while(1){
343 i++;
344
345 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
346 /* Class ~ End Class
347 Interface ~ End Interface
348 を飛び越す */
349 i3=GetEndXXXCommand(source[i+1]);
350 for(i+=2,i2=0;;i++,i2++){
351 if(source[i]=='\0') break;
352 if(source[i]==1&&source[i+1]==(char)i3){
353 i++;
354 break;
355 }
356 }
357 if(source[i]=='\0') break;
358 continue;
359 }
360
361 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
362 for(i+=2,i2=0;;i2++,i++){
363 if( IsCommandDelimitation( source[i] ) ){
364 temporary[i2]=0;
365 break;
366 }
367 temporary[i2]=source[i];
368 }
369 namespaceScopes.push_back( temporary );
370
371 continue;
372 }
373 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
374 if( namespaceScopes.size() <= 0 ){
375 compiler.errorMessenger.Output(12, "End Namespace", i );
376 }
377 else{
378 namespaceScopes.pop_back();
379 }
380
381 i += 2;
382 continue;
383 }
384 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
385 for(i+=2,i2=0;;i2++,i++){
386 if( IsCommandDelimitation( source[i] ) ){
387 temporary[i2]=0;
388 break;
389 }
390 temporary[i2]=source[i];
391 }
392 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
393 {
394 compiler.errorMessenger.Output(64,temporary,cp );
395 }
396
397 continue;
398 }
399 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
400 importedNamespaces.clear();
401 continue;
402 }
403
404 if(source[i]==1&&source[i+1]==ESC_DECLARE){
405 for(i+=2,i2=0;;i2++,i++){
406 if(source[i]=='\n'){
407 temporary[i2]=0;
408 break;
409 }
410 temporary[i2]=source[i];
411 if(source[i]=='\0') break;
412 }
413 dllProcs.Add(namespaceScopes,temporary,i);
414
415 continue;
416 }
417 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
418 char statementChar = source[i+1];
419
420 for(i2=0;;i2++,i++){
421 if(IsCommandDelimitation(source[i])){
422 temporary[i2]=0;
423 break;
424 }
425 temporary[i2]=source[i];
426 if(source[i]=='\0') break;
427 }
428
429 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
430 userProcs.Insert( pUserProc, i );
431
432 /* Sub ~ End Sub
433 Function ~ End Function
434 Macro ~ End Macro
435 を飛び越す */
436 char endStatementChar = GetEndXXXCommand( statementChar );
437 for(i2=0;;i++,i2++){
438 if( source[i] == '\0' ) break;
439 if( source[i] == 1 && source[i+1] == endStatementChar ){
440 i++;
441 break;
442 }
443 }
444 if(source[i]=='\0') break;
445 continue;
446 }
447
448 //次の行
449 for(;;i++){
450 if(IsCommandDelimitation(source[i])) break;
451 }
452 if(source[i]=='\0') break;
453 }
454
455 ////////////
456 // 特殊関数
457 ////////////
458 namespaceScopes.clear();
459 importedNamespaces.clear();
460
461 compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
462 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
463 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
464 userProcs.Insert( pUserProc, i );
465}
Note: See TracBrowser for help on using the repository browser.