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

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

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/plain; charset=Shift_JIS
File size: 6.9 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5void LexicalAnalyzer::CollectDelegates( const char *source, Delegates &delegates )
6{
7 // 名前空間管理
8 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
9 namespaceScopes.clear();
10
11 // Imports情報のクリア
12 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
13
14 for (int i=0; source[i] != '\0'; i++)
15 {
16 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
17 i+=2;
18 char const* p = &source[i];
19 while (!IsCommandDelimitation(source[i]))
20 {
21 ++i;
22 }
23 namespaceScopes.push_back(std::string(p, &source[i]));
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 ){
39 i+=2;
40 char const* p = &source[i];
41 while (!IsCommandDelimitation(source[i]))
42 {
43 ++i;
44 }
45 std::string s(p, &source[i]);
46 if (!compiler.GetNamespaceSupporter().ImportsNamespace(s))
47 {
48 compiler.errorMessenger.Output(64, s.c_str(), i);
49 }
50
51 continue;
52 }
53 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED )
54 {
55 // Imports情報のクリア
56 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
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];
80 GetIdentifierToken( name, source, i );
81
82 if( source[i] != '(' )
83 {
84 compiler.errorMessenger.Output(1,NULL,nowLine);
85 continue;
86 }
87
88 // パラメータ文字列
89 char paramStr[8192];
90 i += GetStringInPare( paramStr, source + i, true );
91
92 // 戻り値の型の文字列
93 char returnTypeName[VN_SIZE] = "";
94 if( source[i] == 1 && source[i+1] == ESC_AS )
95 {
96 i += 2;
97 GetCommandToken( returnTypeName, source, i );
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);
109 strcpy( returnTypeName, "Double" );
110 }
111 }
112
113 delegates.Put( new Delegate( Symbol( namespaceScopes, name ), compiler.GetNamespaceSupporter().GetImportedNamespaces(), procKind, paramStr, returnTypeName, nowLine ) );
114 }
115 }
116}
117
118std::string LexicalAnalyzer::GenerateDelegatesSourceCode( const Delegates &delegates )
119{
120 std::string destSource = "";
121
122 Jenga::Common::SourceTemplate sourceTemplate( ActiveBasic::Common::Environment::GetAbdevSystemDirPath() + "\\templates\\delegate_class.tab" );
123
124 foreach (auto pDelegate, delegates)
125 {
126 const Delegate &dg = *pDelegate;
127
128 if( dg.IsExternal() )
129 {
130 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
131 continue;
132 }
133
134 std::map<std::string,std::string> values;
135
136 if( dg.GetNamespaceScopes().size() )
137 {
138 std::string namespaceScopesCommandStr;
139 std::string endNamespaceScopesCommandStr;
140 foreach( const std::string &namespaceStr, dg.GetNamespaceScopes() )
141 {
142 if( namespaceScopesCommandStr.size() )
143 {
144 namespaceScopesCommandStr += ':';
145 endNamespaceScopesCommandStr += ':';
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
197 // 呼び出し側の実引数文字列を作成
198 Jenga::Common::Strings paramVarNames;
199 LexicalAnalyzer::ExtractParameterVarNames( dg.GetParamStr().c_str(), paramVarNames, dg.GetSourceIndex() );
200 std::string tempParamStrForCall;
201 foreach( const std::string &varName, paramVarNames )
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 ) );
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
222void LexicalAnalyzer::RefleshDelegateParameterAndReturnType( Delegate &dg )
223{
224 if( dg.IsExternal() )
225 {
226 // 外部参照の場合はリフレッシュが不要
227 return;
228 }
229
230 compiler.GetNamespaceSupporter().SetImportedNamespaces( dg.GetImportedNamespaces() );
231 compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( dg.GetNamespaceScopes() );
232
233 // パラメータを解析
234 Jenga::Common::Strings parameterStrings;
235 SplitParameter( dg.GetParamStr(), parameterStrings );
236 ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( dg.GetParameters(), parameterStrings, dg.GetSourceIndex() );
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 {
248 compiler.errorMessenger.Output(3,dg.GetReturnTypeName(),dg.GetSourceIndex());
249 }
250 else
251 {
252 dg.SetReturnType( returnType );
253 }
254 }
255}
256
257void LexicalAnalyzer::RefleshDelegatesParameterAndReturnType( Delegates &delegates )
258{
259 foreach (auto *pDelegate, delegates)
260 {
261 RefleshDelegateParameterAndReturnType(*pDelegate);
262 }
263}
Note: See TracBrowser for help on using the repository browser.