source: dev/BasicCompiler_Common/Subroutine.cpp@ 16

Last change on this file since 16 was 5, checked in by dai_9181, 18 years ago
File size: 30.7 KB
RevLine 
[4]1#include "../BasicCompiler_Common/common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
[5]6#include "../BasicCompiler32/opcode.h"
[4]7#endif
8
9//コンパイル中の関数情報
10SUBINFO *pCompilingSubInfo;
11
12int GetCallProcName(char *buffer,char *name){
13 int i2,i3,IsStr=0;
14
15 for(i2=0;;i2++){
16 if(buffer[i2]=='\"') IsStr^=1;
17 if(IsDBCSLeadByte(buffer[i2])){
18 name[i2]=buffer[i2];
19 i2++;
20 name[i2]=buffer[i2];
21 continue;
22 }
23 if(buffer[i2]=='['&&IsStr==0){
24 i3=GetStringInBracket(name+i2,buffer+i2);
25 i2+=i3-1;
26 continue;
27 }
28 if(buffer[i2]=='('&&IsStr==0){
29 name[i2]=0;
30 break;
31 }
32 if(buffer[i2]=='='&&IsStr==0){
33 name[i2]=0;
34 break;
35 }
36
37 name[i2]=buffer[i2];
38 if(buffer[i2]=='\0') break;
39 }
40 return i2;
41}
42
43int GetProc(char *name,void **ppInfo){
44
45 //ユーザー定義関数
46 *ppInfo=(void *)GetSubHash(name);
47 if(*ppInfo) return PROC_DEFAULT;
48
49 //DLL関数
50 *ppInfo=(void *)GetDeclareHash(name);
51 if(*ppInfo) return PROC_DLL;
52
53 //コンパイラ埋め込み型
54 *ppInfo=(void *)(_int64)GetFunctionFromName(name);
55 if(*ppInfo) return PROC_BUILTIN;
56
57 //関数ポインタ
58 int type;
59 LONG_PTR lpIndex;
60 type=GetVarType(name,&lpIndex,0);
61 if(type==DEF_PTR_PROC) return PROC_PTR;
62
63 return 0;
64}
65
66void GetObjectName(char *name,char *ObjectName,int *pRefType){
67 int i4;
68 for(i4=lstrlen(name)-1;i4>=0;i4--){
69 if(name[i4]=='.'||(name[i4]==1&&name[i4+1]==ESC_PSMEM))
70 break;
71 }
72 if(i4==-1) ObjectName[0]=0;
73 else{
74 //参照タイプを判別
75 if(name[i4]=='.') *pRefType=DEF_OBJECT;
76 else *pRefType=DEF_PTR_OBJECT;
77
78 if(i4==0) GetWithName(ObjectName);
79 else{
80 memcpy(ObjectName,name,i4);
81 ObjectName[i4]=0;
82 }
83 }
84}
85int GetReturnTypeOfProc(int idProc,void *pInfo,char *name,char *Parameter,LONG_PTR *plpRetIndex){
86 int ret_type;
87
88 if(idProc==PROC_DEFAULT){
89 /////////////////////
90 // ユーザー定義関数
91 /////////////////////
92
93 SUBINFO *psi;
94 psi=(SUBINFO *)pInfo;
95
96 //GetSubHash内でエラー提示が行われた場合
97 if(psi==(SUBINFO *)-1) return -1;
98
99
100 //オブジェクト名を取得
101 char ObjectName[VN_SIZE];
102 int RefType;
103 GetObjectName(name,ObjectName,&RefType);
104
105
106 ////////////////////////
107 // オーバーロードを解決
108 ////////////////////////
109
110 SUBINFO **ppsi;
111 int num;
112 ppsi=GetOverloadSubHash(name,&num);
113 if(num){
114 //オーバーロードを解決
115 psi=OverloadSolutionWithStrParam(name,ppsi,num,Parameter,ObjectName,NULL);
116 HeapDefaultFree(ppsi);
117
118 if(!psi) return 0;
119 }
120
121
122 ret_type=psi->ReturnType;
123 *plpRetIndex=psi->u.ReturnIndex;
124 }
125 else if(idProc==PROC_DLL){
126 /////////////////////////
127 // DLL関数
128 /////////////////////////
129 DECLAREINFO *pdi;
130 pdi=(DECLAREINFO *)pInfo;
131
132 ret_type=pdi->ReturnType;
133 *plpRetIndex=pdi->u.ReturnIndex;
134 }
135 else if(idProc==PROC_BUILTIN){
136 /////////////////////////
137 // 組み込み関数
138 /////////////////////////
139 int FuncId;
140 FuncId=(int)(_int64)pInfo;
141
142 ret_type=GetFunctionType(FuncId);
143 *plpRetIndex=-1;
144 }
145 else if(idProc==PROC_PTR){
146 /////////////////
147 // 関数ポインタ
148 /////////////////
149
150 LONG_PTR lpIndex;
151 GetVarType(name,&lpIndex,0);
152
153 extern PROCPTRINFO *pProcPtrInfo;
154 ret_type=pProcPtrInfo[lpIndex].ReturnType;
155 *plpRetIndex=pProcPtrInfo[lpIndex].u.ReturnIndex;
156 }
157
158 return ret_type;
159}
160BOOL GetReturnTypeOfPropertyMethod(char *variable,char *RightSide,TYPEINFO *pRetTypeInfo){
161 //プロパティ用のメソッドを呼び出す
162
163 //配列要素を取得
164 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
165 GetArrayElement(variable,VarName,ArrayElements);
166
167 //オブジェクト名を取得
168 char ObjectName[VN_SIZE];
169 int RefType;
170 GetObjectName(VarName,ObjectName,&RefType);
171
172 //オーバーロード用の関数リストを作成
173 SUBINFO **ppsi;
174 int num;
175 ppsi=GetOverloadSubHash(VarName,&num);
176 if(num==0){
177 return 0;
178 }
179
180 //パラメータを整備
181 char *Parameter;
182 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(RightSide)+32);
183 lstrcpy(Parameter,ArrayElements);
184 if(RightSide){
185 if(Parameter[0]&&RightSide[0]) lstrcat(Parameter,",");
186 lstrcat(Parameter,RightSide);
187 }
188
189 //オーバーロードを解決
190 SUBINFO *psi;
191 psi=OverloadSolutionWithStrParam(VarName,ppsi,num,Parameter,ObjectName,NULL);
192 HeapDefaultFree(ppsi);
193
194 if(psi){
195 if(pRetTypeInfo){
196 pRetTypeInfo->type=psi->ReturnType;
197 pRetTypeInfo->u.lpIndex=psi->u.ReturnIndex;
198 }
199 }
200
201 return 1;
202}
203
204void AddDeclareData(char *buffer,int NowLine){
205 extern HANDLE hHeap;
206 int i,i2,i3,i4,sw,IsFunction;
207 char temporary[VN_SIZE];
208
209 i=0;
210
211 DWORD dwType;
212 BOOL bCdecl=0;
213
214 //Static/Dynamic
215 if(buffer[i]==ESC_STATIC){
216 dwType=DECLARE_STATIC;
217 i++;
218 }
219 else dwType=DECLARE_DYNAMIC;
220
221 //Sub/Function
222 if(buffer[i]==ESC_SUB) IsFunction=0;
223 else if(buffer[i]==ESC_FUNCTION) IsFunction=1;
224 else{
225 SetError(1,NULL,NowLine);
226 return;
227 }
228 i++;
229
230 //プロシージャ名
231 for(i2=0;;i++,i2++){
232 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
233 bCdecl=1;
234
235 i+=2;
236 temporary[i2]=0;
237 break;
238 }
239 if(buffer[i]==','){
240 temporary[i2]=0;
241 break;
242 }
243 if(buffer[i]=='\0'){
244 SetError(1,NULL,NowLine);
245 return;
246 }
247 temporary[i2]=buffer[i];
248 }
249
250 //ユーザー定義関数との重複チェック
251 if(GetSubHash(temporary)){
252 SetError(15,temporary,NowLine);
253 return;
254 }
255
256
257 /////////////////////////////////
258 // 格納位置を計算してpciにセット
259 /////////////////////////////////
260
261 //ハッシュ値を取得
262 int key;
263 key=hash_default(temporary);
264
265 extern DECLAREINFO **ppDeclareHash;
266 DECLAREINFO *pdi;
267 if(ppDeclareHash[key]){
268 pdi=ppDeclareHash[key];
269 while(1){
270 if(lstrcmpi(pdi->name,temporary)==0){
271 //重複エラー
272 SetError(15,temporary,NowLine);
273 return;
274 }
275
276 if(pdi->pNextData==0){
277 pdi->pNextData=(DECLAREINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(DECLAREINFO));
278 break;
279 }
280 pdi=pdi->pNextData;
281 }
282 pdi=pdi->pNextData;
283 }
284 else{
285 ppDeclareHash[key]=(DECLAREINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(DECLAREINFO));
286 pdi=ppDeclareHash[key];
287 }
288
289 pdi->dwType=dwType;
290 pdi->bCdecl=bCdecl;
291
292 pdi->name=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
293 lstrcpy(pdi->name,temporary);
294 i++;
295
296 //ライブラリ
297 if(buffer[i]!='\"'){
298 SetError(1,NULL,NowLine);
299 return;
300 }
301 for(i++,i2=0;;i++,i2++){
302 if(buffer[i]=='\"'){
303 temporary[i2]=0;
304 break;
305 }
306 if(buffer[i]=='\0'){
307 SetError(1,NULL,NowLine);
308 return;
309 }
310 temporary[i2]=buffer[i];
311 }
312 CharUpper(temporary);
313 if(!strstr(temporary,".")){
314 if(pdi->dwType==DECLARE_STATIC) lstrcat(temporary,".LIB");
315 else{
316 lstrcat(temporary,".DLL");
317 if(lstrlen(temporary)>=16){
318 SetError(7,NULL,NowLine);
319 return;
320 }
321 }
322 }
323 pdi->file=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
324 lstrcpy(pdi->file,temporary);
325 i++;
326
327 if(buffer[i]==','){
328 i++;
329 if(buffer[i]!='\"'){
330 SetError(1,NULL,NowLine);
331 return;
332 }
333 for(i++,i2=0;;i++,i2++){
334 if(buffer[i]=='\"'){
335 temporary[i2]=0;
336 break;
337 }
338 if(buffer[i]=='\0'){
339 SetError(1,NULL,NowLine);
340 return;
341 }
342 temporary[i2]=buffer[i];
343 }
344 pdi->alias=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
345 lstrcpy(pdi->alias,temporary);
346 i++;
347 }
348 else{
349 pdi->alias=(char *)HeapAlloc(hHeap,0,lstrlen(pdi->name)+1);
350 lstrcpy(pdi->alias,pdi->name);
351 }
352
353 //パラメータの始めのカッコ
354 if(buffer[i]!='('){
355 SetError(1,NULL,NowLine);
356 return;
357 }
358 i++;
359
360 pdi->pParmInfo=(PARAMETER_INFO *)HeapAlloc(hHeap,0,1);
361
362 //各パラメータ
363 for(i3=0;;i3++){
364 if(buffer[i]==')') break;
365
366 pdi->pParmInfo=(PARAMETER_INFO *)HeapReAlloc(hHeap,0,pdi->pParmInfo,(i3+1)*sizeof(PARAMETER_INFO));
367
368 //ByVal
369 if(buffer[i]==1&&buffer[i+1]==ESC_BYVAL){
370 pdi->pParmInfo[i3].bByVal=1;
371 i+=2;
372 }
373 else if(buffer[i]==1&&buffer[i+1]==ESC_BYREF){
374 pdi->pParmInfo[i3].bByVal=0;
375 i+=2;
376 }
377 else pdi->pParmInfo[i3].bByVal=1;
378
379 //変数名は無視(temporaryの変数名は型宣言文字判断のため)
380 sw=0;
381 for(i2=0;;i++,i2++){
382 if(buffer[i]=='('){
383 if(!sw) sw=1;
384
385 i4=GetStringInPare(temporary+i2,buffer+i);
386 i2+=i4-1;
387 i+=i4-1;
388 continue;
389 }
390 if(buffer[i]=='['){
391 if(!sw) sw=1;
392
393 i4=GetStringInBracket(temporary+i2,buffer+i);
394 i2+=i4-1;
395 i+=i4-1;
396 continue;
397 }
398 if(!IsVariableChar(buffer[i])){
399 temporary[i2]=0;
400 break;
401 }
402 temporary[i2]=buffer[i];
403 }
404 if(lstrcmp(temporary,"...")==0) pdi->pParmInfo[i3].type=DEF_ELLIPSE;
405 else{
406 //型
407 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
408 i+=2;
409 for(i2=0;;i++,i2++){
410 if(!(IsVariableChar(buffer[i])||buffer[i]=='*')){
411 temporary[i2]=0;
412 break;
413 }
414 temporary[i2]=buffer[i];
415 }
416 pdi->pParmInfo[i3].type=GetTypeFixed(temporary,&pdi->pParmInfo[i3].u.index);
417 }
418 else{
419 pdi->pParmInfo[i3].type=GetTypeFromSimpleName(temporary);
420 SetError(-103,temporary,NowLine);
421 }
422
423 if(sw){
424 //配列ポインタを引き渡すとき
425 pdi->pParmInfo[i3].type=GetPtrType(pdi->pParmInfo[i3].type,pdi->pParmInfo[i3].u.index);
426 }
427 }
428
429 //名前はダミー(使用しないため)
430 pdi->pParmInfo[i3].name="";
431
432 //構造体の場合はエラーチェック
433 if(pdi->pParmInfo[i3].type==-1) SetError(3,temporary,NowLine);
434 if(pdi->pParmInfo[i3].type==DEF_OBJECT){
435 if(pdi->pParmInfo[i3].bByVal) pdi->pParmInfo[i3].type=DEF_LONG;//SetError(28,temporary,NowLine);
436 }
437
438 //構造体アドレスの空白部
439 while(buffer[i]==' ') i++;
440
441 if(buffer[i]==','){
442 i++;
443 continue;
444 }
445 else if(buffer[i]==')') continue;
446 else{
447 SetError(1,NULL,NowLine);
448 break;
449 }
450 }
451 pdi->ParmNum=i3;
452
453 //戻り値
454 i++;
455 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
456 if(IsFunction==0) SetError(1,NULL,NowLine);
457 i+=2;
458 pdi->ReturnType=GetTypeFixed(buffer+i,&pdi->u.ReturnIndex);
459 if(pdi->ReturnType==-1) SetError(3,buffer+i,NowLine);
460 if(pdi->ReturnType==DEF_OBJECT) SetError(40,NULL,NowLine);
461 }
462 else if(buffer[i]) SetError(1,NULL,NowLine);
463 else pdi->ReturnType=-1;
464
465 pdi->pos=NowLine;
466}
467
468BOOL CompareParameter(PARAMETER_INFO *ppi1,int pi_num1,PARAMETER_INFO *ppi2,int pi_num2){
469 if(pi_num1!=pi_num2) return 1;
470
471 int i;
472 for(i=0;i<pi_num1;i++){
473 if(ppi1[i].type!=ppi2[i].type){
474
475 if(ppi1[i].bByVal==0&&ppi1[i].type==DEF_ANY&&
476 ppi2[i].bByVal==1&&IsPtrType(ppi2[i].type)||
477 ppi1[i].bByVal==1&&IsPtrType(ppi1[i].type)&&
478 ppi2[i].bByVal==0&&ppi2[i].type==DEF_ANY){
479 /* ByRef var As Any
480
481 var As VoidPtr
482 は同等
483 */
484 continue;
485 }
486
487 return 1;
488 }
489 else{
490 if(NATURAL_TYPE(ppi1[i].type)==DEF_OBJECT){
491 if(ppi1[i].u.index!=ppi2[i].u.index) return 1;
492 }
493 }
494 }
495
496 return 0;
497}
498SUBINFO *AddSubData(char *buffer,int NowLine,BOOL bVirtual,CClass *pobj_c,BOOL bStatic){
499 int i,i2,i3,sw;
500 DWORD dwType;
501 char temporary[8192],temp2[VN_SIZE];
502
503 i=1;
504 if(buffer[i]==ESC_SUB) dwType=SUBTYPE_SUB;
505 else if(buffer[i]==ESC_FUNCTION) dwType=SUBTYPE_FUNCTION;
506 else if(buffer[i]==ESC_MACRO) dwType=SUBTYPE_MACRO;
507
508 i++;
509
510 BOOL bExport=0,bCdecl=0;
511 while(1){
512 if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&&bExport==0){
513 bExport=1;
514
515 i+=2;
516 }
517 else if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&&bCdecl==0){
518 bCdecl=1;
519
520 i+=2;
521 }
522 else break;
523 }
524
525 i2=0;
526 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
527 if(!pobj_c){
528 SetError(126,NULL,NowLine);
529 return 0;
530 }
531
532 //オペレータの場合
533 temporary[i2++]=buffer[i++];
534 temporary[i2++]=buffer[i++];
535
536 int iCalcId;
537 if(buffer[i]=='='&&buffer[i+1]=='='){
538 iCalcId=CALC_EQUAL;
539 i3=2;
540 }
541 else if(buffer[i]=='='){
542 iCalcId=CALC_SUBSITUATION;
543 i3=1;
544 }
545 else if(buffer[i]=='('){
546 iCalcId=CALC_AS;
547 i3=0;
548 }
549 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
550 iCalcId=CALC_ARRAY_SET;
551 i3=3;
552 }
553 else if(buffer[i]=='['&&buffer[i+1]==']'){
554 iCalcId=CALC_ARRAY_GET;
555 i3=2;
556 }
557 else{
558 iCalcId=GetCalcId(buffer+i,&i3);
559 i3++;
560 }
561 if(!iCalcId){
562 SetError(1,NULL,NowLine);
563 return 0;
564 }
565 temporary[i2++]=iCalcId;
566 temporary[i2]=0;
567
568 i+=i3;
569 }
570 else{
571 if(pobj_c){
572 //クラスメンバの場合、デストラクタには~が付くことを考慮
573 if(buffer[i]=='~'){
574 temporary[i2]='~';
575 i++;
576 i2++;
577 }
578 }
579
580 for(;;i++,i2++){
581 if(!IsVariableChar(buffer[i])){
582 temporary[i2]=0;
583 break;
584 }
585 temporary[i2]=buffer[i];
586 }
587 }
588
589 if(dwType==SUBTYPE_MACRO){
590 //大文字に変換
591 CharUpper(temporary);
592
593 //マクロ関数の場合は名前リストに追加
594 extern char **ppMacroNames;
595 extern int MacroNum;
596 ppMacroNames=(char **)HeapReAlloc(hHeap,0,ppMacroNames,(MacroNum+1)*sizeof(char *));
597 ppMacroNames[MacroNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
598 lstrcpy(ppMacroNames[MacroNum],temporary);
599 MacroNum++;
600 }
601
602 if(!(pobj_c&&bStatic==0)){
603 //クラスメンバ以外の場合のみ
604 //重複チェック
605
606 if(GetDeclareHash(temporary)){
607 SetError(15,temporary,NowLine);
608 return 0;
609 }
610 }
611
612 extern int SubNum;
613 SubNum++;
614
615 SUBINFO *psi;
616 psi=(SUBINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(SUBINFO));
617
618 //クラス名
619 psi->pobj_ParentClass=pobj_c;
620
621 //ID
[5]622 static int id_base=0;
[4]623 psi->id=(id_base++);
624
625 //関数名
626 psi->name=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
627 lstrcpy(psi->name,temporary);
628
629 //ソースコードの位置
630 psi->address=NowLine;
631
632 psi->bExport=bExport;
633 psi->bCdecl=bCdecl;
634 psi->bVirtual=bVirtual;
635 if(bExport) psi->bUse=1;
636 else psi->bUse=0;
637 psi->bCompile=0;
638 psi->bSystem=0;
639
640 psi->dwType=dwType;
641
642
643 if(psi->dwType==SUBTYPE_FUNCTION){
644 ///////////////////
645 // 戻り値を取得
646 ///////////////////
647
648 if(pobj_c){
649 if(lstrcmp(psi->name,pobj_c->name)==0||
650 psi->name[0]=='~'){
651 //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
652 SetError(115,NULL,NowLine);
653 }
654 }
655
656
657 i2=lstrlen(buffer)-2;
658
659 int sw_as=0;
660 for(;i2>0;i2--){
661 if(buffer[i2]==')') break;
662 if(buffer[i2]==1&&buffer[i2+1]==ESC_AS){
663 i2+=2;
664 i3=0;
665 while(buffer[i2]=='*') temporary[i3++]=buffer[i2++];
666 for(;;i2++,i3++){
667 if(!IsVariableChar(buffer[i2])){
668 temporary[i3]=0;
669 break;
670 }
671 temporary[i3]=buffer[i2];
672 }
673 psi->ReturnType=GetTypeFixed(temporary,&psi->u.ReturnIndex);
674 if(psi->ReturnType==-1) SetError(3,temporary,NowLine);
675
676 sw_as=1;
677 break;
678 }
679 }
680
681 if(!sw_as){
682 SetError(-104,psi->name,NowLine);
683
684 psi->ReturnType=DEF_DOUBLE;
685 }
686 }
687 else{
688 //戻り値なしのSub定義
689 psi->ReturnType=-1;
690 psi->u.ReturnIndex=-1;
691 }
692
693
694
695 psi->pParmInfo=(PARAMETER_INFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(PARAMETER_INFO)*2);
696 psi->ParmNum=0;
697
698 if(pobj_c&&bStatic==0){
699 //オブジェクトメンバの場合は、第一パラメータをThisポインタ引き渡し用として利用
700 psi->pParmInfo[psi->ParmNum].name=(char *)HeapAlloc(hHeap,0,lstrlen("_System_LocalThis")+1);
701 lstrcpy(psi->pParmInfo[psi->ParmNum].name,"_System_LocalThis");
702 psi->pParmInfo[psi->ParmNum].type=DEF_PTR_VOID;
703 psi->pParmInfo[psi->ParmNum].u.index=-1;
704 psi->pParmInfo[psi->ParmNum].bByVal=1;
705 psi->pParmInfo[psi->ParmNum].bArray=0;
706 psi->pParmInfo[psi->ParmNum].SubScripts[0]=-1;
707
708 psi->ParmNum++;
709 }
710
711 //パラメータ
712 if(buffer[i]!='('){
713 SetError(1,NULL,NowLine);
714 return 0;
715 }
716 i++;
717 if(buffer[i]!=')'&&pobj_c){
718 //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
719 if(psi->name[0]=='~'){
720 SetError(114,NULL,NowLine);
721 i=JumpStringInPare(buffer,i);
722 }
723 }
724 while(1){
725 if(buffer[i]==')') break;
726
727 psi->pParmInfo=(PARAMETER_INFO *)HeapReAlloc(hHeap,0,psi->pParmInfo,(psi->ParmNum+1)*sizeof(PARAMETER_INFO));
728
729 //ByVal
730 if(buffer[i]==1&&buffer[i+1]==ESC_BYVAL){
731 psi->pParmInfo[psi->ParmNum].bByVal=1;
732 i+=2;
733 }
734 else if(buffer[i]==1&&buffer[i+1]==ESC_BYREF){
735 psi->pParmInfo[psi->ParmNum].bByVal=0;
736 i+=2;
737 }
738 else psi->pParmInfo[psi->ParmNum].bByVal=1;
739
740 //パラメータ名
741 sw=0;
742 for(i2=0;;i++,i2++){
743 if(buffer[i]=='('){
744 if(!sw) sw=1;
745
746 i3=GetStringInPare(temporary+i2,buffer+i);
747 i2+=i3-1;
748 i+=i3-1;
749 continue;
750 }
751 if(buffer[i]=='['){
752 if(!sw) sw=1;
753
754 i3=GetStringInBracket(temporary+i2,buffer+i);
755 i2+=i3-1;
756 i+=i3-1;
757 continue;
758 }
759 if(!IsVariableChar(buffer[i])){
760 temporary[i2]=0;
761 break;
762 }
763 temporary[i2]=buffer[i];
764 }
765 if(sw){
766 //配列パラメータ
767 if(psi->pParmInfo[psi->ParmNum].bByVal) SetError(29,NULL,NowLine);
768 psi->pParmInfo[psi->ParmNum].bArray=1;
769
770 if((temporary[i2-2]=='('&&temporary[i2-1]==')')||
771 (temporary[i2-2]=='['&&temporary[i2-1]==']')){
772 psi->pParmInfo[psi->ParmNum].SubScripts[0]=LONG_MAX;
773 psi->pParmInfo[psi->ParmNum].SubScripts[1]=-1;
774
775 temporary[i2-2]=0;
776 }
777 else{
778 GetArrange(temporary,temp2,psi->pParmInfo[psi->ParmNum].SubScripts);
779 lstrcpy(temporary,temp2);
780 }
781
782 i2=lstrlen(temporary);
783 }
784 else{
785 psi->pParmInfo[psi->ParmNum].bArray=0;
786 psi->pParmInfo[psi->ParmNum].SubScripts[0]=-1;
787 }
788 psi->pParmInfo[psi->ParmNum].name=(char *)HeapAlloc(hHeap,0,i2+1);
789 lstrcpy(psi->pParmInfo[psi->ParmNum].name,temporary);
790
791 //型
792 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
793 i+=2;
794
795 i2=0;
796 while(buffer[i]=='*'){
797 temporary[i2]=buffer[i];
798 i++;
799 i2++;
800 }
801 for(;;i++,i2++){
802 if(!IsVariableChar(buffer[i])){
803 if(buffer[i]==1&&(buffer[i+1]==ESC_FUNCTION||buffer[i+1]==ESC_SUB)){
804 temporary[i2++]=buffer[i++];
805 temporary[i2]=buffer[i];
806 continue;
807 }
808 temporary[i2]=0;
809 break;
810 }
811 temporary[i2]=buffer[i];
812 }
813
814 psi->pParmInfo[psi->ParmNum].type=
815 GetTypeFixed(temporary,&psi->pParmInfo[psi->ParmNum].u.index);
816
817 if(temporary[0]=='*'&&
818 temporary[1]==1&&
819 (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){
820 if(buffer[i]!='('){
821 SetError(10,temporary,NowLine);
822 return 0;
823 }
824 i3=GetStringInPare(temporary+i2,buffer+i);
825 i+=i3;
826 i2+=i3;
827
828 if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){
829 temporary[i2++]=buffer[i++];
830 temporary[i2++]=buffer[i++];
831 for(;;i++,i2++){
832 if(!IsVariableChar(buffer[i])){
833 temporary[i2]=0;
834 break;
835 }
836 temporary[i2]=buffer[i];
837 }
838 }
839 }
840 else{
841 //TypeDefをする前のベース型を取得
842 GetOriginalTypeName(temporary);
843 }
844
845 if(psi->pParmInfo[psi->ParmNum].type==-1){
846 SetError(3,temporary,NowLine);
847 psi->pParmInfo[psi->ParmNum].type=DEF_PTR_VOID;
848 }
849
850 /*未完成(構造体パラメータを値参照として渡してよいものか!?)
851 if(psi->pParmInfo[psi->ParmNum].type==DEF_OBJECT){
852 if(psi->pParmInfo[psi->ParmNum].bByVal) SetError(28,temporary,NowLine);
853 }*/
854 }
855 else{
856 psi->pParmInfo[psi->ParmNum].type=GetTypeFromSimpleName(temporary);
857 SetError(-103,temporary,NowLine);
858 }
859
860 if(psi->pParmInfo[psi->ParmNum].type==DEF_PTR_PROC){
861 //関数ポインタの場合
862 psi->pParmInfo[psi->ParmNum].u.index=AddProcPtrInfo(temporary+3,temporary[2]);
863 }
864
865 //パラメータの数を更新
866 psi->ParmNum++;
867
868 if(buffer[i]==','){
869 i++;
870 continue;
871 }
872 else if(buffer[i]==')') continue;
873 else{
874 SetError(1,NULL,NowLine);
875 return 0;
876 }
877 }
878 psi->SecondParmNum=psi->ParmNum;
879 i++;
880 if(buffer[i]=='('){
881 i++;
882 while(1){
883 if(buffer[i]==')') break;
884
885 psi->pParmInfo=(PARAMETER_INFO *)HeapReAlloc(hHeap,0,psi->pParmInfo,(psi->ParmNum+1)*sizeof(PARAMETER_INFO));
886
887 //ByVal
888 if(buffer[i]==1&&buffer[i+1]==ESC_BYVAL){
889 psi->pParmInfo[psi->ParmNum].bByVal=1;
890 i+=2;
891 }
892 else if(buffer[i]==1&&buffer[i+1]==ESC_BYREF){
893 psi->pParmInfo[psi->ParmNum].bByVal=0;
894 i+=2;
895 }
896 else psi->pParmInfo[psi->ParmNum].bByVal=1;
897
898 //パラメータ名
899 sw=0;
900 for(i2=0;;i++,i2++){
901 if(buffer[i]=='('){
902 if(!sw) sw=1;
903
904 i3=GetStringInPare(temporary+i2,buffer+i);
905 i2+=i3-1;
906 i+=i3-1;
907 continue;
908 }
909 if(buffer[i]=='['){
910 if(!sw) sw=1;
911
912 i3=GetStringInBracket(temporary+i2,buffer+i);
913 i2+=i3-1;
914 i+=i3-1;
915 continue;
916 }
917 if(!IsVariableChar(buffer[i])){
918 temporary[i2]=0;
919 break;
920 }
921 temporary[i2]=buffer[i];
922 }
923 if(sw){
924 //配列パラメータ
925 if(psi->pParmInfo[psi->ParmNum].bByVal) SetError(29,NULL,NowLine);
926 psi->pParmInfo[psi->ParmNum].bArray=1;
927
928 if((temporary[i2-2]=='('&&temporary[i2-1]==')')||
929 (temporary[i2-2]=='['&&temporary[i2-1]==']')){
930 psi->pParmInfo[psi->ParmNum].SubScripts[0]=LONG_MAX;
931 psi->pParmInfo[psi->ParmNum].SubScripts[1]=-1;
932
933 temporary[i2-2]=0;
934 }
935 else{
936 GetArrange(temporary,temp2,psi->pParmInfo[psi->ParmNum].SubScripts);
937 lstrcpy(temporary,temp2);
938 }
939
940 i2=lstrlen(temporary);
941 }
942 else{
943 psi->pParmInfo[psi->ParmNum].bArray=0;
944 psi->pParmInfo[psi->ParmNum].SubScripts[0]=-1;
945 }
946 psi->pParmInfo[psi->ParmNum].name=(char *)HeapAlloc(hHeap,0,i2+1);
947 lstrcpy(psi->pParmInfo[psi->ParmNum].name,temporary);
948
949 //型
950 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
951 i+=2;
952 i2=0;
953 while(buffer[i]=='*'){
954 temporary[i2]=buffer[i];
955 i++;
956 i2++;
957 }
958 for(;;i++,i2++){
959 if(!IsVariableChar(buffer[i])){
960 temporary[i2]=0;
961 break;
962 }
963 temporary[i2]=buffer[i];
964 }
965 psi->pParmInfo[psi->ParmNum].type=
966 GetTypeFixed(temporary,&psi->pParmInfo[psi->ParmNum].u.index);
967 if(psi->pParmInfo[psi->ParmNum].type==-1) SetError(3,temporary,NowLine);
968 }
969 else{
970 psi->pParmInfo[psi->ParmNum].type=GetTypeFromSimpleName(temporary);
971 SetError(-103,temporary,NowLine);
972 }
973
974 psi->ParmNum++;
975
976 if(buffer[i]==','){
977 i++;
978 continue;
979 }
980 else if(buffer[i]==')') continue;
981 else{
982 SetError(1,NULL,NowLine);
983 return 0;
984 }
985 }
986 i++;
987 }
988
989 if(psi->ReturnType==DEF_OBJECT){
990 //オブジェクト インスタンスを戻り値として持つ場合
991 //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
992
993 psi->RealParmNum=psi->ParmNum+1;
994 psi->RealSecondParmNum=psi->SecondParmNum+1;
995
996 psi->pRealParmInfo=(PARAMETER_INFO *)HeapAlloc(hHeap,0,(psi->RealParmNum+1)*sizeof(PARAMETER_INFO));
997
998 i=0;
999 if(pobj_c&&bStatic==0){
1000 psi->pRealParmInfo[0]=psi->pParmInfo[0];
1001 i++;
1002 }
1003
1004 if(psi->name[0]==1&&psi->name[1]==ESC_OPERATOR)
1005 psi->pRealParmInfo[i].name="_System_ReturnValue";
1006 else psi->pRealParmInfo[i].name=psi->name;
1007 psi->pRealParmInfo[i].type=DEF_OBJECT;
1008 psi->pRealParmInfo[i].u.index=psi->u.ReturnIndex;
1009 psi->pRealParmInfo[i].bByVal=0;
1010 psi->pRealParmInfo[i].bArray=0;
1011 psi->pRealParmInfo[i].SubScripts[0]=-1;
1012 i++;
1013
1014 for(;i<psi->RealParmNum;i++){
1015 psi->pRealParmInfo[i]=psi->pParmInfo[i-1];
1016 }
1017 }
1018 else{
1019 psi->pRealParmInfo=psi->pParmInfo;
1020 psi->RealParmNum=psi->ParmNum;
1021 psi->RealSecondParmNum=psi->SecondParmNum;
1022 }
1023
1024
1025 /////////////////////////////////
1026 // ハッシュデータに追加
1027 /////////////////////////////////
1028
1029 int key;
1030 key=hash_default(psi->name);
1031
1032 extern SUBINFO **ppSubHash;
1033 if(ppSubHash[key]){
1034 SUBINFO *psi2;
1035 psi2=ppSubHash[key];
1036 while(1){
1037 if(pobj_c==psi2->pobj_ParentClass){
1038 //重複エラーチェックを行う
1039 if(lstrcmp(psi2->name,psi->name)==0){
1040 if(CompareParameter(psi2->pParmInfo,psi2->ParmNum,psi->pParmInfo,psi->ParmNum)==0){
1041 SetError(15,psi->name,NowLine);
1042 return 0;
1043 }
1044 }
1045 }
1046
1047 if(psi2->pNextData==0) break;
1048 psi2=psi2->pNextData;
1049 }
1050 psi2->pNextData=psi;
1051 }
1052 else{
1053 ppSubHash[key]=psi;
1054 }
1055
1056 return psi;
1057}
1058
1059void GetSubInfo(void){ //サブルーチン情報を取得
1060 extern HANDLE hHeap;
1061 extern char *basbuf;
1062 int i,i2,i3;
1063 char temporary[8192];
1064
1065 //Declare(DLL関数)情報を初期化
1066 extern DECLAREINFO **ppDeclareHash;
1067 ppDeclareHash=(DECLAREINFO **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_HASH*sizeof(DECLAREINFO *));
1068
1069 //サブルーチン(ユーザー定義)情報を初期化
1070 extern SUBINFO **ppSubHash;
1071 extern int SubNum;
1072 ppSubHash=(SUBINFO **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_HASH*sizeof(SUBINFO *));
1073 SubNum=0;
1074
1075 //マクロ関数の名前リストを初期化
1076 extern char **ppMacroNames;
1077 extern int MacroNum;
1078 ppMacroNames=(char **)HeapAlloc(hHeap,0,1);
1079 MacroNum=0;
1080
1081 i=-1;
1082 while(1){
1083 i++;
1084
1085 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_INTERFACE)){
1086 /* Class ~ End Class
1087 Interface ~ End Interface
1088 を飛び越す */
1089 i3=GetEndXXXCommand(basbuf[i+1]);
1090 for(i+=2,i2=0;;i++,i2++){
1091 if(basbuf[i]=='\0') break;
1092 if(basbuf[i]==1&&basbuf[i+1]==(char)i3){
1093 i++;
1094 break;
1095 }
1096 }
1097 if(basbuf[i]=='\0') break;
1098 continue;
1099 }
1100
1101 if(basbuf[i]==1&&basbuf[i+1]==ESC_DECLARE){
1102 for(i+=2,i2=0;;i2++,i++){
1103 if(basbuf[i]=='\n'){
1104 temporary[i2]=0;
1105 break;
1106 }
1107 temporary[i2]=basbuf[i];
1108 if(basbuf[i]=='\0') break;
1109 }
1110 AddDeclareData(temporary,i);
1111
1112 continue;
1113 }
1114 if(basbuf[i]==1&&(basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION||basbuf[i+1]==ESC_MACRO)){
1115 for(i2=0;;i2++,i++){
1116 if(IsCommandDelimitation(basbuf[i])){
1117 temporary[i2]=0;
1118 break;
1119 }
1120 temporary[i2]=basbuf[i];
1121 if(basbuf[i]=='\0') break;
1122 }
1123 AddSubData(temporary,i,0,0);
1124
1125 continue;
1126 }
1127
1128 //次の行
1129 for(;;i++){
1130 if(IsCommandDelimitation(basbuf[i])) break;
1131 }
1132 if(basbuf[i]=='\0') break;
1133 }
1134
1135 ////////////
1136 // 特殊関数
1137 ////////////
1138
1139 sprintf(temporary,"%c%c_allrem()",1,ESC_SUB);
1140 AddSubData(temporary,0,0,0);
1141
1142 sprintf(temporary,"%c%c_aullrem()",1,ESC_SUB);
1143 AddSubData(temporary,0,0,0);
1144
1145 sprintf(temporary,"%c%c_allmul()",1,ESC_SUB);
1146 AddSubData(temporary,0,0,0);
1147
1148 sprintf(temporary,"%c%c_alldiv()",1,ESC_SUB);
1149 AddSubData(temporary,0,0,0);
1150
1151 sprintf(temporary,"%c%c_aulldiv()",1,ESC_SUB);
1152 AddSubData(temporary,0,0,0);
1153
1154 sprintf(temporary,"%c%c_allshl()",1,ESC_SUB);
1155 AddSubData(temporary,0,0,0);
1156
1157 sprintf(temporary,"%c%c_allshr()",1,ESC_SUB);
1158 AddSubData(temporary,0,0,0);
1159
1160 sprintf(temporary,"%c%c_aullshr()",1,ESC_SUB);
1161 AddSubData(temporary,0,0,0);
1162
1163 sprintf(temporary,"%c%c_System_InitStaticLocalVariables()",1,ESC_SUB);
1164 AddSubData(temporary,0,0,0);
1165}
1166void Delete_si(SUBINFO *psi){
1167 int i2;
1168
1169 for(i2=0;i2<psi->ParmNum;i2++){
1170 HeapDefaultFree(psi->pParmInfo[i2].name);
1171 }
1172 if(psi->pRealParmInfo!=psi->pParmInfo) HeapDefaultFree(psi->pRealParmInfo);
1173 if(psi->pParmInfo) HeapDefaultFree(psi->pParmInfo);
1174 psi->pRealParmInfo=0;
1175 psi->pParmInfo=0;
1176
1177 if(psi->pNextData) Delete_si(psi->pNextData);
1178
1179 HeapDefaultFree(psi->name);
1180 HeapDefaultFree(psi);
1181}
1182void DeleteSubInfo(SUBINFO **ppSubHash,char **ppMacroNames,int MacroNum){ //サブルーチン情報のメモリ解放
1183 int i;
1184 for(i=0;i<MAX_HASH;i++){
1185 if(!ppSubHash[i]) continue;
1186
1187 Delete_si(ppSubHash[i]);
1188 }
1189 HeapDefaultFree(ppSubHash);
1190
1191 //マクロの名前リスト
1192 if(ppMacroNames){
1193 for(i=0;i<MacroNum;i++){
1194 HeapDefaultFree(ppMacroNames[i]);
1195 }
1196 HeapDefaultFree(ppMacroNames);
1197 }
1198}
1199void Delete_di(DECLAREINFO *pdi){
1200 if(pdi->pParmInfo) HeapDefaultFree(pdi->pParmInfo);
1201
1202 HeapDefaultFree(pdi->name);
1203 if(pdi->file) HeapDefaultFree(pdi->file);
1204 if(pdi->alias) HeapDefaultFree(pdi->alias);
1205
1206 if(pdi->pNextData) Delete_di(pdi->pNextData);
1207
1208 HeapDefaultFree(pdi);
1209}
1210void DeleteDeclareInfo(void){
1211 //DLL情報を解放
1212 extern DECLAREINFO **ppDeclareHash;
1213 int i;
1214 for(i=0;i<MAX_HASH;i++){
1215 if(!ppDeclareHash[i]) continue;
1216
1217 Delete_di(ppDeclareHash[i]);
1218 }
1219 HeapDefaultFree(ppDeclareHash);
1220}
1221
1222
1223
1224///////////////////////
1225// 関数ポインタの管理
1226///////////////////////
1227
1228int AddProcPtrInfo(char *buffer,DWORD dwProcType){
1229 extern HANDLE hHeap;
1230 extern int cp;
1231 extern PROCPTRINFO *pProcPtrInfo;
1232 extern int ProcPtrInfoNum;
1233 int i,i2,i3,sw;
1234 PROCPTRINFO *pi;
1235 char temporary[VN_SIZE],temp2[VN_SIZE];
1236
1237 pProcPtrInfo=(PROCPTRINFO *)HeapReAlloc(hHeap,0,pProcPtrInfo,(ProcPtrInfoNum+1)*sizeof(PROCPTRINFO));
1238 pi=&pProcPtrInfo[ProcPtrInfoNum];
1239 ProcPtrInfoNum++;
1240
1241 pi->pParmInfo=(PARAMETER_INFO *)HeapAlloc(hHeap,0,1);
1242 pi->ParmNum=0;
1243
1244 //buffer[0]は'('となっている
1245 i=1;
1246
1247 while(1){
1248 if(buffer[i]==')') break;
1249
1250 pi->pParmInfo=(PARAMETER_INFO *)HeapReAlloc(hHeap,0,pi->pParmInfo,(pi->ParmNum+1)*sizeof(PARAMETER_INFO));
1251
1252 //ByVal
1253 if(buffer[i]==1&&buffer[i+1]==ESC_BYVAL){
1254 pi->pParmInfo[pi->ParmNum].bByVal=1;
1255 i+=2;
1256 }
1257 else if(buffer[i]==1&&buffer[i+1]==ESC_BYREF){
1258 pi->pParmInfo[pi->ParmNum].bByVal=0;
1259 i+=2;
1260 }
1261 else pi->pParmInfo[pi->ParmNum].bByVal=1;
1262
1263 //パラメータ名
1264 sw=0;
1265 for(i2=0;;i++,i2++){
1266 if(buffer[i]=='('){
1267 if(!sw) sw=1;
1268
1269 i3=GetStringInPare(temporary+i2,buffer+i);
1270 i2+=i3-1;
1271 i+=i3-1;
1272 continue;
1273 }
1274 if(buffer[i]=='['){
1275 if(!sw) sw=1;
1276
1277 i3=GetStringInBracket(temporary+i2,buffer+i);
1278 i2+=i3-1;
1279 i+=i3-1;
1280 continue;
1281 }
1282 if(!IsVariableChar(buffer[i])){
1283 temporary[i2]=0;
1284 break;
1285 }
1286 temporary[i2]=buffer[i];
1287 }
1288 pi->pParmInfo[pi->ParmNum].name=0;
1289
1290 if(sw){
1291 //配列パラメータ
1292 if(pi->pParmInfo[pi->ParmNum].bByVal) SetError(29,NULL,cp);
1293 pi->pParmInfo[pi->ParmNum].bArray=1;
1294
1295 if((temporary[i2-2]=='('&&temporary[i2-1]==')')||
1296 (temporary[i2-2]=='['&&temporary[i2-1]==']')){
1297 pi->pParmInfo[pi->ParmNum].SubScripts[0]=LONG_MAX;
1298 pi->pParmInfo[pi->ParmNum].SubScripts[1]=-1;
1299
1300 temporary[i2-2]=0;
1301 }
1302 else{
1303 GetArrange(temporary,temp2,pi->pParmInfo[pi->ParmNum].SubScripts);
1304 lstrcpy(temporary,temp2);
1305 }
1306
1307 i2=lstrlen(temporary);
1308 }
1309 else{
1310 pi->pParmInfo[pi->ParmNum].bArray=0;
1311 pi->pParmInfo[pi->ParmNum].SubScripts[0]=-1;
1312 }
1313
1314 //型
1315 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
1316 i+=2;
1317
1318 i2=0;
1319 while(buffer[i]=='*'){
1320 temporary[i2]=buffer[i];
1321 i++;
1322 i2++;
1323 }
1324 for(;;i++,i2++){
1325 if(!IsVariableChar(buffer[i])){
1326 temporary[i2]=0;
1327 break;
1328 }
1329 temporary[i2]=buffer[i];
1330 }
1331
1332 pi->pParmInfo[pi->ParmNum].type=
1333 GetTypeFixed(temporary,&pi->pParmInfo[pi->ParmNum].u.index);
1334 if(pi->pParmInfo[pi->ParmNum].type==-1){
1335 SetError(3,temporary,cp);
1336 pi->pParmInfo[pi->ParmNum].type=DEF_PTR_VOID;
1337 }
1338 if(pi->pParmInfo[pi->ParmNum].type==DEF_OBJECT){
1339 if(pi->pParmInfo[pi->ParmNum].bByVal) SetError(28,temporary,cp);
1340 }
1341 }
1342 else{
1343 pi->pParmInfo[pi->ParmNum].type=GetTypeFromSimpleName(temporary);
1344 SetError(-103,temporary,cp);
1345 }
1346
1347 pi->ParmNum++;
1348
1349 if(buffer[i]==','){
1350 i++;
1351 continue;
1352 }
1353 else if(buffer[i]==')') continue;
1354 else{
1355 SetError(1,NULL,cp);
1356 return 0;
1357 }
1358 }
1359 i++;
1360
1361 //戻り値
1362 if(dwProcType==ESC_FUNCTION){
1363 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
1364 i+=2;
1365 i2=0;
1366 if(buffer[i]=='*') temporary[i2++]=buffer[i++];
1367 for(;;i++,i2++){
1368 if(!IsVariableChar(buffer[i])){
1369 temporary[i2]=0;
1370 break;
1371 }
1372 temporary[i2]=buffer[i];
1373 }
1374 pi->ReturnType=GetTypeFixed(temporary,&pi->u.ReturnIndex);
1375 if(pi->ReturnType==-1) SetError(3,temporary,cp);
1376 if(pi->ReturnType==DEF_OBJECT) SetError(40,NULL,cp);
1377 }
1378 else pi->ReturnType=DEF_DOUBLE;
1379 }
1380 else pi->ReturnType=-1;
1381
1382 return ProcPtrInfoNum-1;
1383}
1384void DeleteProcPtrInfo(void){
1385 extern PROCPTRINFO *pProcPtrInfo;
1386 extern int ProcPtrInfoNum;
1387 int i;
1388
1389 for(i=0;i<ProcPtrInfoNum;i++){
1390 HeapDefaultFree(pProcPtrInfo[i].pParmInfo);
1391 }
1392
1393 HeapDefaultFree(pProcPtrInfo);
1394}
Note: See TracBrowser for help on using the repository browser.