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

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

#179への対応。外部libで定義済みのデリゲートを再利用すると、パラメータ不一致エラーが出力させてしまう不具合を修正。

File size: 7.0 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 values.insert( std::map<std::string,std::string>::value_type( "#params#", dg.GetParamStr() ) );
204
205 destSource += sourceTemplate.GetResult( values );
206 }
207/*
208 std::ofstream ofs( ( Jenga::Common::Environment::GetAppDir() + "\\generated_delegate_code.log" ).c_str() );
209 ofs << destSource;
210 ofs.close();
211 */
212
213 return destSource;
214}
215
216void LexicalAnalyzer::RefleshDelegateParameterAndReturnType( Delegate &dg )
217{
218 if( dg.IsExternal() )
219 {
220 // 外部参照の場合はリフレッシュが不要
221 return;
222 }
223
224 compiler.GetNamespaceSupporter().SetImportedNamespaces( dg.GetImportedNamespaces() );
225 compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( dg.GetNamespaceScopes() );
226
227 // パラメータを解析
228 Jenga::Common::Strings parameterStrings;
229 SplitParameter( dg.GetParamStr(), parameterStrings );
230 ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( dg.GetParameters(), parameterStrings, dg.GetSourceIndex() );
231
232 // 動的パラメータを作る
233 dg.GetDynamicParams() = dg.GetParameters();
234 dg.GetDynamicParams().insert( dg.GetDynamicParams().begin(), new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
235
236 if( dg.IsFunction() )
237 {
238 // 戻り値を取得
239 Type returnType;
240 if( !compiler.StringToType( dg.GetReturnTypeName(), returnType ) )
241 {
242 compiler.errorMessenger.Output(3,dg.GetReturnTypeName(),dg.GetSourceIndex());
243 }
244 else
245 {
246 dg.SetReturnType( returnType );
247 }
248 }
249}
250
251void LexicalAnalyzer::RefleshDelegatesParameterAndReturnType( Delegates &delegates )
252{
253 delegates.Iterator_Reset();
254 while( delegates.Iterator_HasNext() )
255 {
256 Delegate &dg = *delegates.Iterator_GetNext();
257 RefleshDelegateParameterAndReturnType( dg );
258 }
259}
Note: See TracBrowser for help on using the repository browser.