source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Delegate.cpp@ 448

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

・デリゲートの共変戻り値、反変引数に対応した。
・core.libで定義されたデリゲートがアプリケーションプロジェクトで利用できないバグを修正。

File size: 6.3 KB
Line 
1#include "stdafx.h"
2
3#include <Delegate.h>
4
5void Delegate::RefleshParameterAndReturnType()
6{
7 // パラメータを解析
8 params.Analyze( paramStr.c_str(), sourceIndex );
9
10 // 動的パラメータを作る
11 dynamicParams = params;
12 dynamicParams.insert( dynamicParams.begin(), new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
13
14 if( IsFunction() )
15 {
16 // 戻り値を取得
17 if( !compiler.StringToType( returnTypeName, returnType ) )
18 {
19 SetError(3,returnTypeName,sourceIndex);
20 }
21 }
22}
23
24bool Delegate::IsSimilar( const Delegate &dgt ) const
25{
26 if( this->Params().Equals( dgt.Params(), true ) ) // パラメータが等しい、もしくは反変
27 {
28 if( this->returnType.Equals( dgt.returnType ) )
29 {
30 // 戻り値が等しい
31 return true;
32 }
33 else if( this->returnType.IsCovariant( dgt.returnType ) )
34 {
35 // 戻り値が共変
36 return true;
37 }
38 }
39 return false;
40}
41
42void Delegates::Collect( const BasicSource &source )
43{
44 int i2;
45 char temporary[VN_SIZE];
46
47 // 名前空間管理
48 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
49 namespaceScopes.clear();
50
51 // Importsされた名前空間の管理
52 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
53 importedNamespaces.clear();
54
55 for( int i=0; i<source.GetLength(); i++ )
56 {
57 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
58 for(i+=2,i2=0;;i2++,i++){
59 if( IsCommandDelimitation( source[i] ) ){
60 temporary[i2]=0;
61 break;
62 }
63 temporary[i2]=source[i];
64 }
65 namespaceScopes.push_back( temporary );
66
67 continue;
68 }
69 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
70 if( namespaceScopes.size() <= 0 ){
71 SetError(12, "End Namespace", i );
72 }
73 else{
74 namespaceScopes.pop_back();
75 }
76
77 i += 2;
78 continue;
79 }
80 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
81 for(i+=2,i2=0;;i2++,i++){
82 if( IsCommandDelimitation( source[i] ) ){
83 temporary[i2]=0;
84 break;
85 }
86 temporary[i2]=source[i];
87 }
88 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
89 {
90 SetError(64,temporary,i );
91 }
92
93 continue;
94 }
95 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
96 importedNamespaces.clear();
97 continue;
98 }
99
100 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
101 {
102 int nowLine = i;
103
104 i += 2;
105 if( !( source[i] == 1 && ( source[i+1] == ESC_SUB || source[i+1] == ESC_FUNCTION ) ) )
106 {
107 SetError(1,NULL,i);
108 continue;
109 }
110
111 Procedure::Kind procKind = Procedure::Sub;
112 if( source[i+1] == ESC_FUNCTION )
113 {
114 procKind = Procedure::Function;
115 }
116 i += 2;
117
118 // 名前
119 char name[VN_SIZE];
120 GetIdentifierToken( name, source.GetBuffer(), i );
121
122 if( source[i] != '(' )
123 {
124 SetError(1,NULL,nowLine);
125 continue;
126 }
127
128 // パラメータ文字列
129 char paramStr[8192];
130 i += GetStringInPare( paramStr, source.GetBuffer() + i, true );
131
132 // 戻り値の型の文字列
133 char returnTypeName[VN_SIZE] = "";
134 if( source[i] == 1 && source[i+1] == ESC_AS )
135 {
136 i += 2;
137 GetCommandToken( returnTypeName, source.GetBuffer(), i );
138
139 if( procKind != Procedure::Function )
140 {
141 SetError(38,name,nowLine);
142 }
143 }
144 else
145 {
146 if( procKind == Procedure::Function )
147 {
148 SetError(-104,name,nowLine);
149 lstrcpy( returnTypeName, "Double" );
150 }
151 }
152
153 this->Put( new Delegate( namespaceScopes, name, procKind, paramStr, returnTypeName, nowLine ) );
154 }
155 }
156}
157
158void Delegates::GenerateSourceCode( std::string &destSource )
159{
160 destSource = "";
161
162 SourceTemplate sourceTemplate( "\\SubOperation\\templates\\delegate_class.tab" );
163
164 this->Iterator_Reset();
165 while( this->Iterator_HasNext() )
166 {
167 const Delegate &dg = *this->Iterator_GetNext();
168
169 if( !dg.isTargetObjectModule )
170 {
171 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
172 continue;
173 }
174
175 std::map<std::string,std::string> values;
176
177 if( dg.GetNamespaceScopes().size() )
178 {
179 std::string namespaceScopesCommandStr = "";
180 std::string endNamespaceScopesCommandStr = "";
181 BOOST_FOREACH( const std::string &namespaceStr, dg.GetNamespaceScopes() )
182 {
183 if( namespaceScopesCommandStr.size() )
184 {
185 namespaceScopesCommandStr += ":";
186 endNamespaceScopesCommandStr += ":";
187 }
188 namespaceScopesCommandStr += "Namespace " + namespaceStr;
189 endNamespaceScopesCommandStr += "End Namespace";
190 }
191
192 values.insert( std::map<std::string,std::string>::value_type(
193 "#namespace_begin#",
194 namespaceScopesCommandStr
195 ) );
196 values.insert( std::map<std::string,std::string>::value_type(
197 "#namespace_end#",
198 endNamespaceScopesCommandStr
199 ) );
200 }
201 else
202 {
203 values.insert( std::map<std::string,std::string>::value_type( "#namespace_begin#", "" ) );
204 values.insert( std::map<std::string,std::string>::value_type( "#namespace_end#", "" ) );
205 }
206
207 values.insert( std::map<std::string,std::string>::value_type( "#name#", dg.GetName() ) );
208
209 if( dg.IsFunction() )
210 {
211 values.insert( std::map<std::string,std::string>::value_type(
212 "#call_method_begin#",
213 (string)"Function Call(" + dg.paramStr + ") As " + dg.returnTypeName
214 ) );
215
216 values.insert( std::map<std::string,std::string>::value_type(
217 "#call_method_end#",
218 "End Function"
219 ) );
220
221 values.insert( std::map<std::string,std::string>::value_type( "#result#", "Call=" ) );
222 }
223 else
224 {
225 values.insert( std::map<std::string,std::string>::value_type(
226 "#call_method_begin#",
227 (string)"Sub Call(" + dg.paramStr + ")"
228 ) );
229
230 values.insert( std::map<std::string,std::string>::value_type(
231 "#call_method_end#",
232 "End Sub"
233 ) );
234
235 values.insert( std::map<std::string,std::string>::value_type( "#result#", "" ) );
236 }
237
238 values.insert( std::map<std::string,std::string>::value_type( "#params#", dg.paramStr ) );
239
240 destSource += sourceTemplate.GetResult( values );
241 }
242/*
243 ofstream ofs( ( Jenga::Common::Environment::GetAppDir() + "\\generated_delegate_code.log" ).c_str() );
244 ofs << destSource;
245 ofs.close();
246 */
247}
248
249void Delegates::RefleshParameterAndReturnType()
250{
251 this->Iterator_Reset();
252 while( this->Iterator_HasNext() )
253 {
254 Delegate &dg = *this->Iterator_GetNext();
255 dg.RefleshParameterAndReturnType();
256 }
257}
Note: See TracBrowser for help on using the repository browser.