source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Delegate.cpp@ 803

Last change on this file since 803 was 803, checked in by イグトランス (egtra), 13 years ago

Hashmapの実装にunorderedを用いるよう変更

File size: 7.2 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 foreach (auto pDelegate, delegates)
130 {
131 const Delegate &dg = *pDelegate;
132
133 if( dg.IsExternal() )
134 {
135 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
136 continue;
137 }
138
139 std::map<std::string,std::string> values;
140
141 if( dg.GetNamespaceScopes().size() )
142 {
143 std::string namespaceScopesCommandStr;
144 std::string endNamespaceScopesCommandStr;
145 foreach( const std::string &namespaceStr, dg.GetNamespaceScopes() )
146 {
147 if( namespaceScopesCommandStr.size() )
148 {
149 namespaceScopesCommandStr += ':';
150 endNamespaceScopesCommandStr += ':';
151 }
152 namespaceScopesCommandStr += "Namespace " + namespaceStr;
153 endNamespaceScopesCommandStr += "End Namespace";
154 }
155
156 values.insert( std::map<std::string,std::string>::value_type(
157 "#namespace_begin#",
158 namespaceScopesCommandStr
159 ) );
160 values.insert( std::map<std::string,std::string>::value_type(
161 "#namespace_end#",
162 endNamespaceScopesCommandStr
163 ) );
164 }
165 else
166 {
167 values.insert( std::map<std::string,std::string>::value_type( "#namespace_begin#", "" ) );
168 values.insert( std::map<std::string,std::string>::value_type( "#namespace_end#", "" ) );
169 }
170
171 values.insert( std::map<std::string,std::string>::value_type( "#name#", dg.GetName() ) );
172
173 if( dg.IsFunction() )
174 {
175 values.insert( std::map<std::string,std::string>::value_type(
176 "#call_method_begin#",
177 (std::string)"Function Call(" + dg.GetParamStr() + ") As " + dg.GetReturnTypeName()
178 ) );
179
180 values.insert( std::map<std::string,std::string>::value_type(
181 "#call_method_end#",
182 "End Function"
183 ) );
184
185 values.insert( std::map<std::string,std::string>::value_type( "#result#", "Call=" ) );
186 }
187 else
188 {
189 values.insert( std::map<std::string,std::string>::value_type(
190 "#call_method_begin#",
191 (std::string)"Sub Call(" + dg.GetParamStr() + ")"
192 ) );
193
194 values.insert( std::map<std::string,std::string>::value_type(
195 "#call_method_end#",
196 "End Sub"
197 ) );
198
199 values.insert( std::map<std::string,std::string>::value_type( "#result#", "" ) );
200 }
201
202 // 呼び出し側の実引数文字列を作成
203 Jenga::Common::Strings paramVarNames;
204 LexicalAnalyzer::ExtractParameterVarNames( dg.GetParamStr().c_str(), paramVarNames, dg.GetSourceIndex() );
205 std::string tempParamStrForCall;
206 foreach( const std::string &varName, paramVarNames )
207 {
208 if( !tempParamStrForCall.empty() )
209 {
210 tempParamStrForCall += ",";
211 }
212 tempParamStrForCall += varName;
213 }
214 values.insert( std::map<std::string,std::string>::value_type( "#params#", tempParamStrForCall ) );
215
216 destSource += sourceTemplate.GetResult( values );
217 }
218/*
219 std::ofstream ofs( ( Jenga::Common::Environment::GetAppDir() + "\\generated_delegate_code.log" ).c_str() );
220 ofs << destSource;
221 ofs.close();
222 */
223
224 return destSource;
225}
226
227void LexicalAnalyzer::RefleshDelegateParameterAndReturnType( Delegate &dg )
228{
229 if( dg.IsExternal() )
230 {
231 // 外部参照の場合はリフレッシュが不要
232 return;
233 }
234
235 compiler.GetNamespaceSupporter().SetImportedNamespaces( dg.GetImportedNamespaces() );
236 compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( dg.GetNamespaceScopes() );
237
238 // パラメータを解析
239 Jenga::Common::Strings parameterStrings;
240 SplitParameter( dg.GetParamStr(), parameterStrings );
241 ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( dg.GetParameters(), parameterStrings, dg.GetSourceIndex() );
242
243 // 動的パラメータを作る
244 dg.GetDynamicParams() = dg.GetParameters();
245 dg.GetDynamicParams().insert( dg.GetDynamicParams().begin(), new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
246
247 if( dg.IsFunction() )
248 {
249 // 戻り値を取得
250 Type returnType;
251 if( !compiler.StringToType( dg.GetReturnTypeName(), returnType ) )
252 {
253 compiler.errorMessenger.Output(3,dg.GetReturnTypeName(),dg.GetSourceIndex());
254 }
255 else
256 {
257 dg.SetReturnType( returnType );
258 }
259 }
260}
261
262void LexicalAnalyzer::RefleshDelegatesParameterAndReturnType( Delegates &delegates )
263{
264 foreach (auto *pDelegate, delegates)
265 {
266 RefleshDelegateParameterAndReturnType(*pDelegate);
267 }
268}
Note: See TracBrowser for help on using the repository browser.