source: dev/trunk/abdev/BasicCompiler_Common/ParamImpl.cpp@ 365

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

Throw→Catch間のパラメータ引渡しに対応。
グローバル領域でのTryスコープを可能にした。これで例外処理機構実装完了。
エディタの補間機能にTry/Catch/Finally/EndTryを追加。

File size: 8.5 KB
Line 
1#include "stdafx.h"
2
3#include <Program.h>
4
5#include "common.h"
6
7#ifdef _AMD64_
8#include "../BasicCompiler64/opcode.h"
9#else
10#include "../BasicCompiler32/opcode.h"
11#endif
12
13#define OVERLOAD_MIN_LEVEL 0
14#define OVERLOAD_MAX_LEVEL 6
15#define OVERLOAD_LEVEL0 0 // 型調整なし。厳密に等しい
16#define OVERLOAD_LEVEL1 1 // 型調整なし。レベル1以上はオブジェクトの場合は派生関係を考慮
17#define OVERLOAD_LEVEL2 2 // 型調整なし。整数型/実数型レベルでの同一性チェック(サイズ照合あり)
18#define OVERLOAD_LEVEL3 3 // 型調整なし。整数型/実数型レベルでの同一性チェック
19#define OVERLOAD_LEVEL4 4 // 型調整あり。厳密に等しい
20#define OVERLOAD_LEVEL5 5 // 型調整あり。整数型/実数型レベルでの同一性チェック
21#define OVERLOAD_LEVEL6 6 // 型調整あり。数値型/クラス型レベルでの同一性チェック
22
23ParamImpl::ParamImpl(const char *buffer):
24 returnType()
25{
26 ///////////////////////////
27 // パラメータ文字列を整理
28 ///////////////////////////
29
30 extern HANDLE hHeap;
31 int i,i2,i3;
32 char temporary[VN_SIZE];
33
34 i=0;
35 ParmsNum=0;
36 while(1){
37 if(buffer[i]=='\0') break;
38
39 for(i2=0;;i2++,i++){
40 if(buffer[i]=='\"'){
41 temporary[i2]=buffer[i];
42 for(i++,i2++;;i++,i2++){
43 temporary[i2]=buffer[i];
44 if( buffer[i] == '\0' )
45 {
46 SetError();
47 break;
48 }
49 if(buffer[i]=='\"') break;
50 }
51 continue;
52 }
53
54 if(buffer[i]=='('){
55 i3=GetStringInPare(temporary+i2,buffer+i);
56 i2+=i3-1;
57 i+=i3-1;
58 continue;
59 }
60 if(buffer[i]=='['){
61 i3=GetStringInBracket(temporary+i2,buffer+i);
62 i2+=i3-1;
63 i+=i3-1;
64 continue;
65 }
66
67 if(buffer[i]==','||buffer[i]=='\0'){
68 temporary[i2]=0;
69 break;
70 }
71 temporary[i2]=buffer[i];
72 }
73
74 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
75 lstrcpy(Parms[ParmsNum],temporary);
76 ParmsNum++;
77
78 types.push_back( Type() );
79
80 if(buffer[i]==',') i++;
81 }
82}
83ParamImpl::ParamImpl(const Parameters &params):
84 returnType()
85{
86 ParmsNum = 0;
87 BOOST_FOREACH( Parameter *pParam, params ){
88 Parms[ParmsNum]=0;
89 ParmsNum++;
90
91 types.push_back( *pParam );
92 }
93}
94ParamImpl::~ParamImpl(){
95 int i2;
96
97 //パラメータ文字列を解放
98 for(i2=0;i2<ParmsNum;i2++){
99 if(Parms[i2]==(char *)-1) continue;
100
101 if(Parms[i2]) HeapDefaultFree(Parms[i2]);
102 }
103}
104
105void ParamImpl::SetReturnType( const Type &returnType ){
106 this->returnType = returnType;
107}
108
109bool ParamImpl::EvaluateOverloadScore( int level, const Parameters &targetParms, const Type &targetResultType, bool &isErrored ){
110 //パラメータを識別してオーバーロードを解決
111
112 isErrored = false;
113
114 //パラメータの個数が不一致の場合
115 int max = (int)targetParms.size();
116
117 if( ParmsNum > max ){
118 // 実引数が駆り引数より多いとき
119 // ※無条件で不一致
120 return false;
121 }
122
123 Type argType;
124 for(int i=0;i<max;i++){
125 Parameter &param = *targetParms[i];
126
127 if( i >= ParmsNum ){
128 // 引数が多いとき
129 if( param.GetInitValue().size() > 0 ){
130 // 初期値が指定されているパラメータを考慮
131 return true;
132 }
133 else{
134 return false;
135 }
136 }
137
138 if(Parms[i]){
139 Type nullParam( DEF_NON );
140
141 if( !NumOpe_GetType(Parms[i],
142 ( level <= OVERLOAD_LEVEL3 )? nullParam : param,
143 argType) )
144 {
145 isErrored = true;
146 return false;
147 }
148 }
149 else{
150 argType = types[i];
151 }
152
153 if(argType.GetBasicType()!=param.GetBasicType()){
154 if( level == OVERLOAD_LEVEL0 || level == OVERLOAD_LEVEL1 || level==OVERLOAD_LEVEL4 ){
155 return false;
156 }
157 else if( level == OVERLOAD_LEVEL2 ){
158 if( !(argType.IsWhole() && param.IsWhole() && argType.GetBasicSize() == param.GetBasicSize() ) ){
159 // サイズ違い
160 return false;
161 }
162 }
163 else if( level == OVERLOAD_LEVEL3 || level==OVERLOAD_LEVEL5){
164 if(!(
165 argType.IsWhole()&&param.IsWhole()||
166 argType.IsReal()&&param.IsReal()
167 )){
168 return false;
169 }
170 if( argType.IsPointer() || param.IsPointer() )
171 {
172 // ポインタ型の不整合は認めない
173 return false;
174 }
175 }
176 else if(level==OVERLOAD_LEVEL6){
177 if(argType.IsObject()||param.IsObject()) return false;
178 }
179 }
180 else{
181 if( NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
182 if(argType.GetIndex()!=param.GetIndex()){
183 return false;
184 }
185 }
186 else if( NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT ){
187 if( level == OVERLOAD_LEVEL0 ){
188 if( !param.GetClass().IsEquals( &argType.GetClass() ) ){
189 return false;
190 }
191 }
192 else{
193 if( !param.GetClass().IsEqualsOrSubClass( &argType.GetClass() ) ){
194 return false;
195 }
196 }
197 }
198 }
199 }
200
201 if( !targetResultType.IsNull() ){
202 //戻り値も比較対象にする
203 if( !returnType.Equals( targetResultType ) ){
204 return false;
205 }
206 }
207
208 return true;
209}
210
211const UserProc *ParamImpl::_OverloadSolution( const char *name, std::vector<const UserProc *> &subs, bool isEnabledReturnType ){
212 const UserProc *pUserProc = NULL;
213
214 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ )
215 {
216 BOOST_FOREACH( const UserProc *pTempUserProc, subs )
217 {
218 bool isErrored = false;
219 bool isHit = false;
220 isHit = EvaluateOverloadScore( level, pTempUserProc->Params(), isEnabledReturnType?pTempUserProc->ReturnType():Type(), isErrored );
221 if( isErrored )
222 {
223 // 照合中にエラーが起きた場合
224 return NULL;
225 }
226
227 if( isHit )
228 {
229 trace_for_overload( "レベル" << level << " ○適合..." << pTempUserProc->_paramStr );
230
231 if( pUserProc ){
232 if( isEnabledReturnType ){
233 SetError(52,name,cp);
234 return NULL;
235 }
236 else{
237 // 戻り値も比較するモードにして再びオーバーロード解決を試みる
238
239 trace_for_overload( "戻り値も比較するモードに切り替えてオーバーロード解決を試みる" );
240
241 return OverloadSolution(name,subs, true);
242 }
243 }
244
245 pUserProc = pTempUserProc;
246 }
247 else
248 {
249 trace_for_overload( "レベル" << level << " ×不適合..." << pTempUserProc->_paramStr );
250 }
251 }
252
253 if( pUserProc ) break;
254 }
255
256 if( !pUserProc ){
257 BOOST_FOREACH( const UserProc *pTempUserProc, subs )
258 {
259 //エラーチェック
260 if(pTempUserProc->Params().size()==this->ParmsNum)
261 {
262 if( pUserProc )
263 {
264 SetError(52,name,cp);
265 return NULL;
266 }
267
268 pUserProc=pTempUserProc;
269 }
270 }
271 }
272
273 if( !pUserProc )
274 {
275 SetError();
276 }
277
278 return pUserProc;
279}
280const UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<const UserProc *> &subs, bool isEnabledReturnType ){
281 trace_for_overload( "" );
282 trace_for_overload( "■■■■■■■■■■■■■■■■■■" );
283 trace_for_overload( "■■■ オーバーロード解決(" << name << ")" );
284
285 const UserProc *result = _OverloadSolution( name, subs, isEnabledReturnType );
286
287 trace_for_overload( "■■■ ここまで" );
288 trace_for_overload( "■■■■■■■■■■■■■■■■■■" );
289 trace_for_overload( "" );
290
291 return result;
292}
293
294void ParamImpl::ApplyDefaultParameters( const Parameters &params ){
295 if( ParmsNum == (int)params.size() ){
296 // デフォルト引数の適用が不必要なとき
297 return;
298 }
299
300 while( ParmsNum < (int)params.size() ){
301 Parameter &param = *params[ParmsNum];
302
303 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,param.GetInitValue().size() + 1 );
304 lstrcpy(Parms[ParmsNum],param.GetInitValue().c_str() );
305 ParmsNum++;
306 }
307}
308
309bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
310 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
311
312 if(ParmsNum>(int)params.size()){
313 if( params.size() == 0 || params[params.size()-1]->GetBasicType()!=DEF_ELLIPSE ){
314 //パラメータが多すぎるとき
315 SetError(10,procName,cp);
316 return false;
317 }
318 }
319 else if(ParmsNum<(int)params.size()){
320 if(ParmsNum<SecondParmNum){
321 if(params[ParmsNum]->GetBasicType()==DEF_ELLIPSE){
322 return true;
323 }
324
325 //パラメータが少なすぎるとき
326 SetError(10,procName,cp);
327 return false;
328 }
329
330 //省略パラメータに "0" を指定する
331 for(;ParmsNum < (int)params.size();ParmsNum++){
332 extern HANDLE hHeap;
333 char temporary[64];
334 if(params[ParmsNum]->IsRef() == false) lstrcpy(temporary,"0");
335 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
336 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
337 lstrcpy(Parms[ParmsNum],temporary);
338 }
339 }
340
341 return true;
342}
343
344void ParamImpl::MacroParameterSupport( const Parameters &params ){
345 for(int i=0;i<ParmsNum;i++){
346 if(Parms[i][0]=='\0'){
347 extern HANDLE hHeap;
348 char temporary[64];
349 if( params[i]->IsRef() == false ) lstrcpy(temporary,"0");
350 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
351 HeapDefaultFree(Parms[i]);
352 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
353 lstrcpy(Parms[i],temporary);
354 }
355 }
356}
Note: See TracBrowser for help on using the repository browser.