source: dev/BasicCompiler_Common/Parameter.cpp@ 52

Last change on this file since 52 was 52, checked in by dai_9181, 17 years ago
File size: 6.6 KB
Line 
1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9CParameter::CParameter(const char *buffer){
10 ///////////////////////////
11 // パラメータ文字列を整理
12 ///////////////////////////
13
14 extern HANDLE hHeap;
15 int i,i2,i3;
16 char temporary[VN_SIZE];
17
18 i=0;
19 ParmsNum=0;
20 while(1){
21 if(buffer[i]=='\0') break;
22
23 for(i2=0;;i2++,i++){
24 if(buffer[i]=='\"'){
25 temporary[i2]=buffer[i];
26 for(i++,i2++;;i++,i2++){
27 temporary[i2]=buffer[i];
28 if(buffer[i]=='\"') break;
29 }
30 continue;
31 }
32
33 if(buffer[i]=='('){
34 i3=GetStringInPare(temporary+i2,buffer+i);
35 i2+=i3-1;
36 i+=i3-1;
37 continue;
38 }
39 if(buffer[i]=='['){
40 i3=GetStringInBracket(temporary+i2,buffer+i);
41 i2+=i3-1;
42 i+=i3-1;
43 continue;
44 }
45
46 if(buffer[i]==','||buffer[i]=='\0'){
47 temporary[i2]=0;
48 break;
49 }
50 temporary[i2]=buffer[i];
51 }
52
53 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
54 lstrcpy(Parms[ParmsNum],temporary);
55 ParmsNum++;
56
57 if(buffer[i]==',') i++;
58 }
59
60 ReturnTypeInfo.type=0;
61 ReturnTypeInfo.u.lpIndex=0;
62}
63CParameter::CParameter(const PARAMETER_INFO *pParamInfo,const int ParmNum){
64 int i;
65 for(i=0;i<ParmNum;i++){
66 Parms[i]=0;
67 types[i].type=pParamInfo[i].type;
68 types[i].u.lpIndex=pParamInfo[i].u.index;
69 }
70 this->ParmsNum=ParmNum;
71
72 ReturnTypeInfo.type=0;
73 ReturnTypeInfo.u.lpIndex=0;
74}
75CParameter::~CParameter(){
76 int i2;
77
78 //パラメータ文字列を解放
79 for(i2=0;i2<ParmsNum;i2++){
80 if(Parms[i2]==(char *)-1) continue;
81
82 if(Parms[i2]) HeapDefaultFree(Parms[i2]);
83 }
84}
85
86void CParameter::SetReturnType(TYPEINFO *pTypeInfo){
87 ReturnTypeInfo=*pTypeInfo;
88}
89
90BOOL CParameter::_overload_check(PARAMETER_INFO *ppi,int pi_num,TYPEINFO *pReturnTypeInfo,int overload_level){
91 //パラメータを識別してオーバーロードを解決
92
93 //パラメータの個数が不一致の場合
94 if(pi_num!=ParmsNum) return 0;
95
96 int i,type;
97 LONG_PTR lpIndex;
98 for(i=0;i<pi_num;i++){
99 if(Parms[i]){
100 TYPEINFO BaseType={ppi[i].type,ppi[i].u.index};
101 type=NumOpe_GetType(Parms[i],&BaseType,&lpIndex);
102 }
103 else{
104 type=types[i].type;
105 lpIndex=types[i].u.lpIndex;
106 }
107
108 if(type!=ppi[i].type){
109 if(overload_level==OVERLOAD_LEVEL1){
110 return 0;
111 }
112 else if(overload_level==OVERLOAD_LEVEL2){
113 if(!(
114 IsWholeNumberType(type)&&IsWholeNumberType(ppi[i].type)||
115 IsRealNumberType(type)&&IsRealNumberType(ppi[i].type)
116 )) return 0;
117 }
118 else if(overload_level==OVERLOAD_LEVEL3){
119 if(type==DEF_OBJECT||ppi[i].type==DEF_OBJECT) return 0;
120 }
121 }
122 else{
123 if(NATURAL_TYPE(type)==DEF_OBJECT){
124 if(lpIndex!=ppi[i].u.index) return 0;
125 }
126 }
127 }
128
129 if(pReturnTypeInfo){
130 //戻り値も比較対象にする
131 if(ReturnTypeInfo.type==pReturnTypeInfo->type){
132 if(NATURAL_TYPE(ReturnTypeInfo.type)==DEF_OBJECT){
133 if(ReturnTypeInfo.u.lpIndex != pReturnTypeInfo->u.lpIndex) return 0;
134 }
135 }
136 else return 0;
137 }
138
139 return 1;
140}
141
142SUBINFO *CParameter::OverloadSolutionWithReturnType( const char *name, std::vector<SUBINFO *> &subs ){
143 int sw=0;
144 SUBINFO *psi;
145 psi=0;
146
147 foreach( psi, subs ){
148
149 TYPEINFO ReturnTypeInfo;
150 ReturnTypeInfo.type=psi->ReturnType;
151 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
152
153 //エラーチェック
154 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL1)){
155 if(sw){
156 SetError(52,name,cp);
157 return 0;
158 }
159 sw=1;
160 break;
161 }
162 }
163
164 if(!sw){
165 foreach( psi, subs ){
166
167 TYPEINFO ReturnTypeInfo;
168 ReturnTypeInfo.type=psi->ReturnType;
169 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
170
171 //エラーチェック
172 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL2)){
173 if(sw){
174 SetError(52,name,cp);
175 return 0;
176 }
177 sw=1;
178 break;
179 }
180 }
181 }
182
183 if(!sw){
184 foreach( psi, subs ){
185
186 TYPEINFO ReturnTypeInfo;
187 ReturnTypeInfo.type=psi->ReturnType;
188 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
189
190 //エラーチェック
191 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL3)){
192 if(sw){
193 SetError(52,name,cp);
194 return 0;
195 }
196 sw=1;
197 break;
198 }
199 }
200 }
201
202 if(!sw){
203 SetError(52,name,cp);
204 return 0;
205 }
206
207 return psi;
208}
209SUBINFO *CParameter::OverloadSolution( const char *name, std::vector<SUBINFO *> &subs ){
210 int sw=0;
211 SUBINFO *psi;
212 psi=0;
213
214 foreach( psi, subs ){
215
216 //エラーチェック
217 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL1)){
218 if(sw){
219 return OverloadSolutionWithReturnType(name,subs);
220 }
221 sw=1;
222 break;
223 }
224 }
225
226 if(!sw){
227 foreach( psi, subs ){
228
229 //エラーチェック
230 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL2)){
231 if(sw){
232 return OverloadSolutionWithReturnType(name,subs);
233 }
234 sw=1;
235 break;
236 }
237 }
238 }
239
240 if(!sw){
241 foreach( psi, subs ){
242
243 //エラーチェック
244 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL3)){
245 if(sw){
246 return OverloadSolutionWithReturnType(name,subs);
247 }
248 sw=1;
249 break;
250 }
251 }
252 }
253
254 if(!sw){
255 SUBINFO *temp_psi;
256 foreach( temp_psi, subs ){
257
258 //エラーチェック
259 if(temp_psi->ParmNum==this->ParmsNum){
260 if(sw){
261 sw=0;
262 break;
263 }
264 sw=1;
265
266 psi=temp_psi;
267 }
268 }
269 }
270
271 if(!sw){
272 SetError(52,name,cp);
273 return 0;
274 }
275
276 return psi;
277}
278
279BOOL CParameter::ErrorCheck(const char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
280 if(ParmsNum>pi_num){
281 if(ppi[pi_num-1].type!=DEF_ELLIPSE){
282 //パラメータが多すぎるとき
283 SetError(10,FuncName,cp);
284 return 0;
285 }
286 }
287 else if(ParmsNum<pi_num){
288 if(ParmsNum<SecondParmNum){
289 if(ppi[ParmsNum].type==DEF_ELLIPSE){
290 return 1;
291 }
292
293 //パラメータが少なすぎるとき
294 SetError(10,FuncName,cp);
295 return 0;
296 }
297
298 //省略パラメータに "0" を指定する
299 for(;ParmsNum < pi_num;ParmsNum++){
300 extern HANDLE hHeap;
301 char temporary[64];
302 if(ppi[ParmsNum].bByVal) lstrcpy(temporary,"0");
303 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
304 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
305 lstrcpy(Parms[ParmsNum],temporary);
306 }
307 }
308
309 return 1;
310}
311
312void CParameter::MacroParameterSupport(PARAMETER_INFO *ppi){
313 int i;
314 for(i=0;i<ParmsNum;i++){
315 if(Parms[i][0]=='\0'){
316 extern HANDLE hHeap;
317 char temporary[64];
318 if(ppi[i].bByVal) lstrcpy(temporary,"0");
319 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
320 HeapDefaultFree(Parms[i]);
321 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
322 lstrcpy(Parms[i],temporary);
323 }
324 }
325}
Note: See TracBrowser for help on using the repository browser.