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
RevLine 
[52]1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
[75]9ParamImpl::ParamImpl(const char *buffer):
10 returnType()
11{
[52]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
[75]59 types.push_back( Type() );
60
[52]61 if(buffer[i]==',') i++;
62 }
63}
[75]64ParamImpl::ParamImpl(const Parameters &params):
65 returnType()
66{
67 ParmsNum = 0;
68 foreach( Parameter *pParam, params ){
69 Parms[ParmsNum]=0;
70 ParmsNum++;
[52]71
[75]72 types.push_back( *pParam );
[73]73 }
74}
[71]75ParamImpl::~ParamImpl(){
[52]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
[75]86void ParamImpl::SetReturnType( const Type &returnType ){
87 this->returnType = returnType;
[52]88}
89
[75]90bool ParamImpl::_overload_check( int level, const Parameters &targetParms, const Type &targetResultType ){
[52]91 //パラメータを識別してオーバーロードを解決
92
93 //パラメータの個数が不一致の場合
[75]94 int max = (int)targetParms.size();
[77]95
96 if( ParmsNum > max ){
97 // 実引数が駆り引数より多いとき
98 // ※無条件で不一致
[75]99 return false;
100 }
[52]101
[73]102 Type argType;
103 for(int i=0;i<max;i++){
[75]104 Parameter &param = *targetParms[i];
[73]105
[77]106 if( i >= ParmsNum ){
107 // 引数が多いとき
108 if( param.GetInitValue().size() > 0 ){
109 // 初期値が指定されているパラメータを考慮
110 return true;
111 }
112 else{
113 return false;
114 }
115 }
116
[52]117 if(Parms[i]){
[73]118 Type nullParam( DEF_NON );
119
120 NumOpe_GetType(Parms[i],
[75]121 (level==OVERLOAD_LEVEL0)? nullParam : param,
[73]122 argType);
[52]123 }
124 else{
[75]125 argType = types[i];
[52]126 }
127
[73]128 if(argType.GetBasicType()!=param.GetBasicType()){
[75]129 if(level==OVERLOAD_LEVEL1 || level == OVERLOAD_LEVEL0){
130 return false;
[52]131 }
[75]132 else if(level==OVERLOAD_LEVEL2){
[52]133 if(!(
[73]134 IsWholeNumberType(argType.GetBasicType())&&IsWholeNumberType(param.GetBasicType())||
135 IsRealNumberType(argType.GetBasicType())&&IsRealNumberType(param.GetBasicType())
[75]136 )){
137 return false;
138 }
[52]139 }
[75]140 else if(level==OVERLOAD_LEVEL3){
[77]141 if(argType.GetBasicType()==DEF_OBJECT||param.GetBasicType()==DEF_OBJECT) return false;
[52]142 }
143 }
144 else{
[73]145 if(NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
[75]146 if(argType.GetIndex()!=param.GetIndex()){
147 return false;
148 }
[52]149 }
150 }
151 }
152
[75]153 if( !targetResultType.IsNull() ){
[52]154 //戻り値も比較対象にする
[75]155 if( !returnType.Equals( targetResultType ) ){
156 return false;
[52]157 }
158 }
159
[75]160 return true;
[52]161}
162
[75]163UserProc *ParamImpl::OverloadSolutionWithReturnType( const char *name, std::vector<UserProc *> &subs ){
[52]164 int sw=0;
[75]165 UserProc *pUserProc = NULL;
[52]166
[64]167 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
[75]168 foreach( UserProc *pTempUserProc, subs ){
[52]169
170 //エラーチェック
[75]171 if(_overload_check( level, pTempUserProc->Params(), pTempUserProc->ReturnType() )){
[52]172 if(sw){
173 SetError(52,name,cp);
174 return 0;
175 }
176 sw=1;
[64]177
[75]178 pUserProc = pTempUserProc;
[52]179 break;
180 }
181 }
182
[64]183 if( sw ) break;
[52]184 }
185
186 if(!sw){
187 SetError(52,name,cp);
188 return 0;
189 }
190
[75]191 return pUserProc;
[52]192}
[75]193UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<UserProc *> &subs ){
[52]194 int sw=0;
[75]195 UserProc *pUserProc;
196 pUserProc=0;
[52]197
[64]198 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
[52]199
[75]200 foreach( UserProc *pTempUserProc, subs ){
[52]201
202 //エラーチェック
[75]203 if(_overload_check( level, pTempUserProc->Params(), Type() )){
[52]204 if(sw){
205 return OverloadSolutionWithReturnType(name,subs);
206 }
207 sw=1;
[64]208
[75]209 pUserProc = pTempUserProc;
[52]210 }
211 }
212
[64]213 if( sw ) break;
[52]214 }
215
216 if(!sw){
[75]217 foreach( UserProc *pTempUserProc, subs ){
[52]218
219 //エラーチェック
[75]220 if(pTempUserProc->Params().size()==this->ParmsNum){
[52]221 if(sw){
222 sw=0;
223 break;
224 }
225 sw=1;
226
[75]227 pUserProc=pTempUserProc;
[52]228 }
229 }
230 }
231
232 if(!sw){
233 SetError(52,name,cp);
234 return 0;
235 }
236
[75]237 return pUserProc;
[52]238}
239
[77]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
[75]255bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
256 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
[52]257
[73]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 }
[52]270
[73]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.