source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Delegate.cpp@ 713

Last change on this file since 713 was 708, checked in by dai_9181, 16 years ago
  • #184への対応。ByRef引数を持つデリゲートを宣言するとコンパイルできないバグを修正。
  • オーバーロード用のパラメータ比較にByRef/ByValの相違を考慮するようにした。
File size: 7.4 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5void LexicalAnalyzer::CollectDelegates( const char *source, Delegates &delegates )
6{
7 int i2;
8 char temporary[VN_SIZE];
9
10 // 名前空間管理
11 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
12 namespaceScopes.clear();
13
14 // Imports情報のクリア
15 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
16
17 int length = lstrlen( source );
18 for( int i=0; i<length; i++ )
19 {
20 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
21 for(i+=2,i2=0;;i2++,i++){
22 if( IsCommandDelimitation( source[i] ) ){
23 temporary[i2]=0;
24 break;
25 }
26 temporary[i2]=source[i];
27 }
28 namespaceScopes.push_back( temporary );
29
30 continue;
31 }
32 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
33 if( namespaceScopes.size() <= 0 ){
34 compiler.errorMessenger.Output(12, "End Namespace", i );
35 }
36 else{
37 namespaceScopes.pop_back();
38 }
39
40 i += 2;
41 continue;
42 }
43 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
44 for(i+=2,i2=0;;i2++,i++){
45 if( IsCommandDelimitation( source[i] ) ){
46 temporary[i2]=0;
47 break;
48 }
49 temporary[i2]=source[i];
50 }
51 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
52 {
53 compiler.errorMessenger.Output(64,temporary,i );
54 }
55
56 continue;
57 }
58 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED )
59 {
60 // Imports情報のクリア
61 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
62 continue;
63 }
64
65 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
66 {
67 int nowLine = i;
68
69 i += 2;
70 if( !( source[i] == 1 && ( source[i+1] == ESC_SUB || source[i+1] == ESC_FUNCTION ) ) )
71 {
72 compiler.errorMessenger.Output(1,NULL,i);
73 continue;
74 }
75
76 Procedure::Kind procKind = Procedure::Sub;
77 if( source[i+1] == ESC_FUNCTION )
78 {
79 procKind = Procedure::Function;
80 }
81 i += 2;
82
83 // 名前
84 char name[VN_SIZE];
85 GetIdentifierToken( name, source, i );
86
87 if( source[i] != '(' )
88 {
89 compiler.errorMessenger.Output(1,NULL,nowLine);
90 continue;
91 }
92
93 // パラメータ文字列
94 char paramStr[8192];
95 i += GetStringInPare( paramStr, source + i, true );
96
97 // 戻り値の型の文字列
98 char returnTypeName[VN_SIZE] = "";
99 if( source[i] == 1 && source[i+1] == ESC_AS )
100 {
101 i += 2;
102 GetCommandToken( returnTypeName, source, i );
103
104 if( procKind != Procedure::Function )
105 {
106 compiler.errorMessenger.Output(38,name,nowLine);
107 }
108 }
109 else
110 {
111 if( procKind == Procedure::Function )
112 {
113 compiler.errorMessenger.Output(-104,name,nowLine);
114 lstrcpy( returnTypeName, "Double" );
115 }
116 }
117
118 delegates.Put( new Delegate( Symbol( namespaceScopes, name ), compiler.GetNamespaceSupporter().GetImportedNamespaces(), procKind, paramStr, returnTypeName, nowLine ) );
119 }
120 }
121}
122
123std::string LexicalAnalyzer::GenerateDelegatesSourceCode( const Delegates &delegates )
124{
125 std::string destSource = "";
126
127 Jenga::Common::SourceTemplate sourceTemplate( ActiveBasic::Common::Environment::GetAbdevSystemDirPath() + "\\templates\\delegate_class.tab" );
128
129 delegates.Iterator_Reset();
130 while( delegates.Iterator_HasNext() )
131 {
132 const Delegate &dg = *delegates.Iterator_GetNext();
133
134 if( dg.IsExternal() )
135 {
136 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
137 continue;
138 }
139
140 std::map<std::string,std::string> values;
141
142 if( dg.GetNamespaceScopes().size() )
143 {
144 std::string namespaceScopesCommandStr = "";
145 std::string endNamespaceScopesCommandStr = "";
146 BOOST_FOREACH( const std::string &namespaceStr, dg.GetNamespaceScopes() )
147 {
148 if( namespaceScopesCommandStr.size() )
149 {
150 namespaceScopesCommandStr += ":";
151 endNamespaceScopesCommandStr += ":";
152 }
153 namespaceScopesCommandStr += "Namespace " + namespaceStr;
154 endNamespaceScopesCommandStr += "End Namespace";
155 }
156
157 values.insert( std::map<std::string,std::string>::value_type(
158 "#namespace_begin#",
159 namespaceScopesCommandStr
160 ) );
161 values.insert( std::map<std::string,std::string>::value_type(
162 "#namespace_end#",
163 endNamespaceScopesCommandStr
164 ) );
165 }
166 else
167 {
168 values.insert( std::map<std::string,std::string>::value_type( "#namespace_begin#", "" ) );
169 values.insert( std::map<std::string,std::string>::value_type( "#namespace_end#", "" ) );
170 }
171
172 values.insert( std::map<std::string,std::string>::value_type( "#name#", dg.GetName() ) );
173
174 if( dg.IsFunction() )
175 {
176 values.insert( std::map<std::string,std::string>::value_type(
177 "#call_method_begin#",
178 (std::string)"Function Call(" + dg.GetParamStr() + ") As " + dg.GetReturnTypeName()
179 ) );
180
181 values.insert( std::map<std::string,std::string>::value_type(
182 "#call_method_end#",
183 "End Function"
184 ) );
185
186 values.insert( std::map<std::string,std::string>::value_type( "#result#", "Call=" ) );
187 }
188 else
189 {
190 values.insert( std::map<std::string,std::string>::value_type(
191 "#call_method_begin#",
192 (std::string)"Sub Call(" + dg.GetParamStr() + ")"
193 ) );
194
195 values.insert( std::map<std::string,std::string>::value_type(
196 "#call_method_end#",
197 "End Sub"
198 ) );
199
200 values.insert( std::map<std::string,std::string>::value_type( "#result#", "" ) );
201 }
202
203 // 呼び出し側の実引数文字列を作成
204 Jenga::Common::Strings paramVarNames;
205 LexicalAnalyzer::ExtractParameterVarNames( dg.GetParamStr().c_str(), paramVarNames, dg.GetSourceIndex() );
206 std::string tempParamStrForCall;
207 BOOST_FOREACH( const std::string &varName, paramVarNames )
208 {
209 if( !tempParamStrForCall.empty() )
210 {
211 tempParamStrForCall += ",";
212 }
213 tempParamStrForCall += varName;
214 }
215 values.insert( std::map<std::string,std::string>::value_type( "#params#", tempParamStrForCall ) );
216
217 destSource += sourceTemplate.GetResult( values );
218 }
219/*
220 std::ofstream ofs( ( Jenga::Common::Environment::GetAppDir() + "\\generated_delegate_code.log" ).c_str() );
221 ofs << destSource;
222 ofs.close();
223 */
224
225 return destSource;
226}
227
228void LexicalAnalyzer::RefleshDelegateParameterAndReturnType( Delegate &dg )
229{
230 if( dg.IsExternal() )
231 {
232 // 外部参照の場合はリフレッシュが不要
233 return;
234 }
235
236 compiler.GetNamespaceSupporter().SetImportedNamespaces( dg.GetImportedNamespaces() );
237 compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( dg.GetNamespaceScopes() );
238
239 // パラメータを解析
240 Jenga::Common::Strings parameterStrings;
241 SplitParameter( dg.GetParamStr(), parameterStrings );
242 ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( dg.GetParameters(), parameterStrings, dg.GetSourceIndex() );
243
244 // 動的パラメータを作る
245 dg.GetDynamicParams() = dg.GetParameters();
246 dg.GetDynamicParams().insert( dg.GetDynamicParams().begin(), new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
247
248 if( dg.IsFunction() )
249 {
250 // 戻り値を取得
251 Type returnType;
252 if( !compiler.StringToType( dg.GetReturnTypeName(), returnType ) )
253 {
254 compiler.errorMessenger.Output(3,dg.GetReturnTypeName(),dg.GetSourceIndex());
255 }
256 else
257 {
258 dg.SetReturnType( returnType );
259 }
260 }
261}
262
263void LexicalAnalyzer::RefleshDelegatesParameterAndReturnType( Delegates &delegates )
264{
265 delegates.Iterator_Reset();
266 while( delegates.Iterator_HasNext() )
267 {
268 Delegate &dg = *delegates.Iterator_GetNext();
269 RefleshDelegateParameterAndReturnType( dg );
270 }
271}
Note: See TracBrowser for help on using the repository browser.