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

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

LexicalAnalyzer周りの修正

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