source: dev/BasicCompiler_Common/ParamImpl.cpp@ 77

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

デフォルトパラメータに対応。

File size: 6.5 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
9ParamImpl::ParamImpl(const char *buffer):
10 returnType()
11{
12 ///////////////////////////
13 // パラメータ文字列を整理
14 ///////////////////////////
15
16 extern HANDLE hHeap;
17 int i,i2,i3;
18 char temporary[VN_SIZE];
19
20 i=0;
21 ParmsNum=0;
22 while(1){
23 if(buffer[i]=='\0') break;
24
25 for(i2=0;;i2++,i++){
26 if(buffer[i]=='\"'){
27 temporary[i2]=buffer[i];
28 for(i++,i2++;;i++,i2++){
29 temporary[i2]=buffer[i];
30 if(buffer[i]=='\"') break;
31 }
32 continue;
33 }
34
35 if(buffer[i]=='('){
36 i3=GetStringInPare(temporary+i2,buffer+i);
37 i2+=i3-1;
38 i+=i3-1;
39 continue;
40 }
41 if(buffer[i]=='['){
42 i3=GetStringInBracket(temporary+i2,buffer+i);
43 i2+=i3-1;
44 i+=i3-1;
45 continue;
46 }
47
48 if(buffer[i]==','||buffer[i]=='\0'){
49 temporary[i2]=0;
50 break;
51 }
52 temporary[i2]=buffer[i];
53 }
54
55 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
56 lstrcpy(Parms[ParmsNum],temporary);
57 ParmsNum++;
58
59 types.push_back( Type() );
60
61 if(buffer[i]==',') i++;
62 }
63}
64ParamImpl::ParamImpl(const Parameters &params):
65 returnType()
66{
67 ParmsNum = 0;
68 foreach( Parameter *pParam, params ){
69 Parms[ParmsNum]=0;
70 ParmsNum++;
71
72 types.push_back( *pParam );
73 }
74}
75ParamImpl::~ParamImpl(){
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 ParamImpl::SetReturnType( const Type &returnType ){
87 this->returnType = returnType;
88}
89
90bool ParamImpl::_overload_check( int level, const Parameters &targetParms, const Type &targetResultType ){
91 //パラメータを識別してオーバーロードを解決
92
93 //パラメータの個数が不一致の場合
94 int max = (int)targetParms.size();
95
96 if( ParmsNum > max ){
97 // 実引数が駆り引数より多いとき
98 // ※無条件で不一致
99 return false;
100 }
101
102 Type argType;
103 for(int i=0;i<max;i++){
104 Parameter &param = *targetParms[i];
105
106 if( i >= ParmsNum ){
107 // 引数が多いとき
108 if( param.GetInitValue().size() > 0 ){
109 // 初期値が指定されているパラメータを考慮
110 return true;
111 }
112 else{
113 return false;
114 }
115 }
116
117 if(Parms[i]){
118 Type nullParam( DEF_NON );
119
120 NumOpe_GetType(Parms[i],
121 (level==OVERLOAD_LEVEL0)? nullParam : param,
122 argType);
123 }
124 else{
125 argType = types[i];
126 }
127
128 if(argType.GetBasicType()!=param.GetBasicType()){
129 if(level==OVERLOAD_LEVEL1 || level == OVERLOAD_LEVEL0){
130 return false;
131 }
132 else if(level==OVERLOAD_LEVEL2){
133 if(!(
134 IsWholeNumberType(argType.GetBasicType())&&IsWholeNumberType(param.GetBasicType())||
135 IsRealNumberType(argType.GetBasicType())&&IsRealNumberType(param.GetBasicType())
136 )){
137 return false;
138 }
139 }
140 else if(level==OVERLOAD_LEVEL3){
141 if(argType.GetBasicType()==DEF_OBJECT||param.GetBasicType()==DEF_OBJECT) return false;
142 }
143 }
144 else{
145 if(NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
146 if(argType.GetIndex()!=param.GetIndex()){
147 return false;
148 }
149 }
150 }
151 }
152
153 if( !targetResultType.IsNull() ){
154 //戻り値も比較対象にする
155 if( !returnType.Equals( targetResultType ) ){
156 return false;
157 }
158 }
159
160 return true;
161}
162
163UserProc *ParamImpl::OverloadSolutionWithReturnType( const char *name, std::vector<UserProc *> &subs ){
164 int sw=0;
165 UserProc *pUserProc = NULL;
166
167 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
168 foreach( UserProc *pTempUserProc, subs ){
169
170 //エラーチェック
171 if(_overload_check( level, pTempUserProc->Params(), pTempUserProc->ReturnType() )){
172 if(sw){
173 SetError(52,name,cp);
174 return 0;
175 }
176 sw=1;
177
178 pUserProc = pTempUserProc;
179 break;
180 }
181 }
182
183 if( sw ) break;
184 }
185
186 if(!sw){
187 SetError(52,name,cp);
188 return 0;
189 }
190
191 return pUserProc;
192}
193UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<UserProc *> &subs ){
194 int sw=0;
195 UserProc *pUserProc;
196 pUserProc=0;
197
198 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
199
200 foreach( UserProc *pTempUserProc, subs ){
201
202 //エラーチェック
203 if(_overload_check( level, pTempUserProc->Params(), Type() )){
204 if(sw){
205 return OverloadSolutionWithReturnType(name,subs);
206 }
207 sw=1;
208
209 pUserProc = pTempUserProc;
210 }
211 }
212
213 if( sw ) break;
214 }
215
216 if(!sw){
217 foreach( UserProc *pTempUserProc, subs ){
218
219 //エラーチェック
220 if(pTempUserProc->Params().size()==this->ParmsNum){
221 if(sw){
222 sw=0;
223 break;
224 }
225 sw=1;
226
227 pUserProc=pTempUserProc;
228 }
229 }
230 }
231
232 if(!sw){
233 SetError(52,name,cp);
234 return 0;
235 }
236
237 return pUserProc;
238}
239
240void ParamImpl::ApplyDefaultParameters( const Parameters &params ){
241 if( ParmsNum == (int)params.size() ){
242 // デフォルト引数の適用が不必要なとき
243 return;
244 }
245
246 while( ParmsNum < (int)params.size() ){
247 Parameter &param = *params[ParmsNum];
248
249 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,param.GetInitValue().size() + 1 );
250 lstrcpy(Parms[ParmsNum],param.GetInitValue().c_str() );
251 ParmsNum++;
252 }
253}
254
255bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
256 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
257
258 if(ParmsNum>(int)params.size()){
259 if(params[params.size()-1]->GetBasicType()!=DEF_ELLIPSE){
260 //パラメータが多すぎるとき
261 SetError(10,procName,cp);
262 return false;
263 }
264 }
265 else if(ParmsNum<(int)params.size()){
266 if(ParmsNum<SecondParmNum){
267 if(params[ParmsNum]->GetBasicType()==DEF_ELLIPSE){
268 return true;
269 }
270
271 //パラメータが少なすぎるとき
272 SetError(10,procName,cp);
273 return false;
274 }
275
276 //省略パラメータに "0" を指定する
277 for(;ParmsNum < (int)params.size();ParmsNum++){
278 extern HANDLE hHeap;
279 char temporary[64];
280 if(params[ParmsNum]->IsRef() == false) lstrcpy(temporary,"0");
281 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
282 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
283 lstrcpy(Parms[ParmsNum],temporary);
284 }
285 }
286
287 return true;
288}
289
290void ParamImpl::MacroParameterSupport( const Parameters &params ){
291 for(int i=0;i<ParmsNum;i++){
292 if(Parms[i][0]=='\0'){
293 extern HANDLE hHeap;
294 char temporary[64];
295 if( params[i]->IsRef() == false ) lstrcpy(temporary,"0");
296 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
297 HeapDefaultFree(Parms[i]);
298 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
299 lstrcpy(Parms[i],temporary);
300 }
301 }
302}
Note: See TracBrowser for help on using the repository browser.