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

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

Parameters::Analyze → LexicalAnalyzer::AnalyzeParameter

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