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

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

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

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