source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Procedure.cpp@ 572

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

ParseDllProc/SetParamsAndReturnTypeForUserProcを実装。

File size: 11.4 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4#include <Procedure.h>
5
6#include "../common.h"
7#ifdef _AMD64_
8#include "../../compiler_x64/opcode.h"
9#else
10#include "../../compiler_x86/opcode.h"
11#endif
12
13using namespace ActiveBasic::Compiler;
14
15
16bool UserProc::IsEqualForOverride( const Types &actualTypeParametersForThisProc, const UserProc *pUserProc ) const
17{
18 if( this->GetName() == pUserProc->GetName() // 名前空間及び名前が等しい
19 && this->Params().Equals( actualTypeParametersForThisProc, pUserProc->Params() ) ) // パラメータが等しい
20 {
21 if( this->returnType.Equals( pUserProc->returnType ) )
22 {
23 // 戻り値が等しい
24 return true;
25 }
26 else if( this->returnType.IsCovariant( pUserProc->returnType ) )
27 {
28 // 戻り値が共変
29 return true;
30 }
31 else if( this->returnType.IsTypeParameter() )
32 {
33 // 型パラメータだったとき
34
35 if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].Equals( pUserProc->returnType ) )
36 {
37 // 戻り値が等しい
38 return true;
39 }
40 else if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].IsCovariant( pUserProc->returnType ) )
41 {
42 // 戻り値が共変
43 return true;
44 }
45 }
46 }
47 return false;
48}
49
50
51std::string UserProc::GetFullName() const
52{
53 if( HasParentClass() ){
54 return GetParentClass().GetName() + "." + GetName();
55 }
56
57 return GetName();
58}
59bool UserProc::IsCastOperator() const
60{
61 if( GetName()[0] == 1 && GetName()[1] == ESC_OPERATOR && GetName()[2] == CALC_AS )
62 {
63 return true;
64 }
65 return false;
66}
67const NamespaceScopes &UserProc::GetNamespaceScopes() const
68{
69 if( HasParentClass() ){
70 return GetParentClassPtr()->GetNamespaceScopes();
71 }
72 return Symbol::GetNamespaceScopes();
73}
74const NamespaceScopesCollection &UserProc::GetImportedNamespaces() const
75{
76 if( pParentClass )
77 {
78 return pParentClass->GetImportedNamespaces();
79 }
80 return importedNamespaces;
81}
82bool UserProc::IsVirtual() const
83{
84 if( pMethod == NULL ){
85 return false;
86 }
87 return ( pMethod->IsVirtual() != 0 );
88}
89const CMethod &UserProc::GetMethod() const
90{
91 if( !HasParentClass() )
92 {
93 Jenga::Throw( "グローバル関数に対してUserProc::GetMethodメソッドが呼ばれた" );
94 }
95 return *pMethod;
96}
97
98const UserProc *UserProc::pGlobalProc = NULL;
99
100
101bool UserProcs::Insert( UserProc *pUserProc, int nowLine )
102{
103 /////////////////////////////////
104 // ハッシュデータに追加
105 /////////////////////////////////
106
107 if( !Put( pUserProc ) )
108 {
109 // 重複しているため、失敗
110 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
111 return false;
112 }
113
114 return true;
115}
116
117void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector<const UserProc *> &subs )
118{
119 ///////////////////////////
120 // グローバル関数を検索
121 ///////////////////////////
122
123 // ハッシュ値を取得
124 UserProc *pUserProc = GetHashArrayElement( simpleName );
125 while(pUserProc){
126 if( pUserProc->IsGlobalProcedure() ){
127 if( pUserProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( localName ) ) ){
128 subs.push_back( pUserProc );
129 }
130 }
131
132 pUserProc=pUserProc->GetChainNext();
133 }
134}
135
136bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
137 int i = 0;
138 int i2,i3,sw;
139 char temporary[8192],temp2[VN_SIZE];
140
141 //ソースコードの位置
142 this->codePos = nowLine;
143
144 //パラメータ
145 if(sourceOfParams[i]!='('){
146 compiler.errorMessenger.Output(1,NULL,nowLine);
147 return 0;
148 }
149 i++;
150
151 while(1){
152 if(sourceOfParams[i]==')') break;
153
154 //ByRef
155 bool isRef;
156 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
157 isRef = false;
158 i+=2;
159 }
160 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
161 isRef = true;
162 i+=2;
163 }
164 else isRef = false;
165
166 //パラメータ名
167 bool isArray = false;
168 Subscripts subscripts;
169 char name[VN_SIZE];
170 sw=0;
171 for(i2=0;;i++,i2++){
172 if(sourceOfParams[i]=='('){
173 if(!sw) sw=1;
174
175 i3=GetStringInPare(name+i2,sourceOfParams+i);
176 i2+=i3-1;
177 i+=i3-1;
178 continue;
179 }
180 if(sourceOfParams[i]=='['){
181 if(!sw) sw=1;
182
183 i3=GetStringInBracket(name+i2,sourceOfParams+i);
184 i2+=i3-1;
185 i+=i3-1;
186 continue;
187 }
188 if(!IsVariableChar(sourceOfParams[i])){
189 name[i2]=0;
190 break;
191 }
192 name[i2]=sourceOfParams[i];
193 }
194 if(sw){
195 //配列パラメータ
196 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
197 isArray = true;
198
199 if((name[i2-2]=='('&&name[i2-1]==')')||
200 (name[i2-2]=='['&&name[i2-1]==']'))
201 {
202 subscripts.push_back( LONG_MAX );
203
204 name[i2-2]=0;
205 }
206 else{
207 GetArrange(name,temp2,subscripts);
208 lstrcpy(name,temp2);
209 }
210
211 i2=lstrlen(name);
212 }
213
214 //型
215 Type type( DEF_NON );
216 if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE );
217 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
218 i+=2;
219
220 i2=0;
221 while(sourceOfParams[i]=='*'){
222 temporary[i2]=sourceOfParams[i];
223 i++;
224 i2++;
225 }
226 for(;;i++,i2++){
227 if(!IsVariableChar(sourceOfParams[i])){
228 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
229 temporary[i2++]=sourceOfParams[i++];
230 temporary[i2]=sourceOfParams[i];
231 continue;
232 }
233 temporary[i2]=0;
234 break;
235 }
236 temporary[i2]=sourceOfParams[i];
237 }
238
239 compiler.StringToType( temporary, type );
240
241 if( type.IsNull() ){
242 compiler.errorMessenger.Output(3,temporary,nowLine);
243 type.SetBasicType( DEF_PTR_VOID );
244 }
245 }
246 else{
247 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
248 compiler.errorMessenger.Output(-103,temporary,nowLine);
249 }
250
251 Parameter *pParam = new Parameter( name, type, isRef );
252 if( isArray ){
253 pParam->SetArray( subscripts );
254 }
255
256 //パラメータを追加
257 this->GetParameters().push_back( pParam );
258
259 if(sourceOfParams[i]==','){
260 i++;
261 continue;
262 }
263 else if(sourceOfParams[i]==')') continue;
264 else{
265 compiler.errorMessenger.Output(1,NULL,nowLine);
266 break;
267 }
268 }
269 i++;
270
271 if(sourceOfParams[i]){
272 ///////////////////
273 // 戻り値を取得
274 ///////////////////
275
276 i2=lstrlen(sourceOfParams)-2;
277
278 int sw_as=0;
279 for(;i2>0;i2--){
280 if(sourceOfParams[i2]==')') break;
281
282 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
283 i2+=2;
284 i3=0;
285 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
286 for(;;i2++,i3++){
287 if(!IsVariableChar(sourceOfParams[i2])){
288 temporary[i3]=0;
289 break;
290 }
291 temporary[i3]=sourceOfParams[i2];
292 }
293 compiler.StringToType( temporary, this->returnType );
294 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
295
296 sw_as=1;
297 break;
298 }
299 }
300 }
301 else{
302 //戻り値なしのSub定義
303 this->returnType.SetNull();
304 }
305
306 return true;
307}
308
309bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
310 int i = 0;
311 int i2,i3,sw;
312 char temporary[8192],temp2[VN_SIZE];
313
314 //ソースコードの位置
315 this->codePos = nowLine;
316
317 //パラメータ
318 if(sourceOfParams[i]!='('){
319 compiler.errorMessenger.Output(1,NULL,nowLine);
320 return 0;
321 }
322 i++;
323 while(1){
324 if(sourceOfParams[i]==')') break;
325
326 //ByRef
327 bool isRef;
328 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
329 isRef = false;
330 i+=2;
331 }
332 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
333 isRef = true;
334 i+=2;
335 }
336 else isRef = false;
337
338 //パラメータ名
339 bool isArray = false;
340 Subscripts subscripts;
341 char name[VN_SIZE];
342 sw=0;
343 for(i2=0;;i++,i2++){
344 if(sourceOfParams[i]=='('){
345 if(!sw) sw=1;
346
347 i3=GetStringInPare(name+i2,sourceOfParams+i);
348 i2+=i3-1;
349 i+=i3-1;
350 continue;
351 }
352 if(sourceOfParams[i]=='['){
353 if(!sw) sw=1;
354
355 i3=GetStringInBracket(name+i2,sourceOfParams+i);
356 i2+=i3-1;
357 i+=i3-1;
358 continue;
359 }
360 if(!IsVariableChar(sourceOfParams[i])){
361 name[i2]=0;
362 break;
363 }
364 name[i2]=sourceOfParams[i];
365 }
366 if(sw){
367 //配列パラメータ
368 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
369 isArray = true;
370
371 if((name[i2-2]=='('&&name[i2-1]==')')||
372 (name[i2-2]=='['&&name[i2-1]==']'))
373 {
374 subscripts.push_back( LONG_MAX );
375
376 name[i2-2]=0;
377 }
378 else{
379 GetArrange(name,temp2,subscripts);
380 lstrcpy(name,temp2);
381 }
382
383 i2=lstrlen(name);
384 }
385
386 //型
387 Type type( DEF_NON );
388 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
389 i+=2;
390
391 i2=0;
392 while(sourceOfParams[i]=='*'){
393 temporary[i2]=sourceOfParams[i];
394 i++;
395 i2++;
396 }
397 for(;;i++,i2++){
398 if(!IsVariableChar(sourceOfParams[i])){
399 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
400 temporary[i2++]=sourceOfParams[i++];
401 temporary[i2]=sourceOfParams[i];
402 continue;
403 }
404 temporary[i2]=0;
405 break;
406 }
407 temporary[i2]=sourceOfParams[i];
408 }
409
410 compiler.StringToType( temporary, type );
411
412 if( type.IsNull() ){
413 compiler.errorMessenger.Output(3,temporary,nowLine);
414 type.SetBasicType( DEF_PTR_VOID );
415 }
416 }
417 else{
418 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
419 compiler.errorMessenger.Output(-103,temporary,nowLine);
420 }
421
422 Parameter *pParam = new Parameter( name, type, isRef );
423 if( isArray ){
424 pParam->SetArray( subscripts );
425 }
426
427 //パラメータを追加
428 this->GetParameters().push_back( pParam );
429
430 if(sourceOfParams[i]==','){
431 i++;
432 continue;
433 }
434 else if(sourceOfParams[i]==')') continue;
435 else{
436 compiler.errorMessenger.Output(1,NULL,nowLine);
437 break;
438 }
439 }
440 i++;
441
442 if(sourceOfParams[i]){
443 ///////////////////
444 // 戻り値を取得
445 ///////////////////
446
447 i2=lstrlen(sourceOfParams)-2;
448
449 int sw_as=0;
450 for(;i2>0;i2--){
451 if(sourceOfParams[i2]==')') break;
452
453 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
454 i2+=2;
455 i3=0;
456 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
457 for(;;i2++,i3++){
458 if(!IsVariableChar(sourceOfParams[i2])){
459 temporary[i3]=0;
460 break;
461 }
462 temporary[i3]=sourceOfParams[i2];
463 }
464 compiler.StringToType( temporary, this->returnType );
465 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
466
467 sw_as=1;
468 break;
469 }
470 }
471 }
472 else{
473 //戻り値なしのSub定義
474 this->returnType.SetNull();
475 }
476
477 //戻り値のエラーチェック
478 if( IsFunction() ){
479 // Function定義
480
481 if( this->ReturnType().IsNull() ){
482 // 戻り値がない
483 compiler.errorMessenger.Output(26,this->GetName(),nowLine);
484 }
485 }
486 else{
487 if( !this->ReturnType().IsNull() ){
488 // Sub定義なのに、戻り値がある
489 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
490 }
491 }
492
493 return true;
494}
495
496int ProcPointers::Add( const std::string &typeExpression )
497{
498 DWORD dwProcType = (DWORD)typeExpression[2];
499 const std::string &paramStr = typeExpression.substr( 3 );
500
501 Procedure::Kind kind = Procedure::Sub;
502 if( dwProcType == ESC_FUNCTION ){
503 kind = Procedure::Function;
504 }
505
506 ProcPointer *pProcPointer = new ProcPointer( kind );
507
508 //buffer[0]は'('となっている
509 extern int cp;
510 pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp );
511
512 this->push_back( pProcPointer );
513
514 return (int)this->size()-1;
515}
516
517void ProcPointers::Clear()
518{
519 ProcPointers &procPointers = *this;
520 BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
521 delete pProcPointer;
522 }
523 this->clear();
524}
Note: See TracBrowser for help on using the repository browser.