source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp@ 546

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

LexicalAnalyzerのソースコードの記述位置を整理。

File size: 7.2 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
6{
7 int i2,i3;
8 char temporary[8192];
9
10 int i=1;
11
12 Procedure::Kind kind = Procedure::Sub;
13 bool isMacro = false;
14 if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
15 if(buffer[i]==ESC_MACRO){
16 isMacro = true;
17 }
18
19 i++;
20
21 bool isCdecl = false;
22 bool isExport = false;
23 while(1){
24 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
25 isCdecl = true;
26
27 i+=2;
28 }
29 else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
30 isExport = true;
31
32 i+=2;
33 }
34 else break;
35 }
36
37 i2=0;
38 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
39 if(!pobj_c){
40 compiler.errorMessenger.Output(126,NULL,nowLine);
41 return 0;
42 }
43
44 //オペレータの場合
45 temporary[i2++]=buffer[i++];
46 temporary[i2++]=buffer[i++];
47
48 int iCalcId;
49 if(buffer[i]=='='&&buffer[i+1]=='='){
50 iCalcId=CALC_EQUAL;
51 i3=2;
52 }
53 else if(buffer[i]=='='){
54 iCalcId=CALC_SUBSITUATION;
55 i3=1;
56 }
57 else if(buffer[i]=='('){
58 iCalcId=CALC_AS;
59 i3=0;
60 }
61 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
62 iCalcId=CALC_ARRAY_SET;
63 i3=3;
64 }
65 else if(buffer[i]=='['&&buffer[i+1]==']'){
66 iCalcId=CALC_ARRAY_GET;
67 i3=2;
68 }
69 else{
70 iCalcId=GetCalcId(buffer+i,&i3);
71 i3++;
72 }
73 if(!iCalcId){
74 compiler.errorMessenger.Output(1,NULL,nowLine);
75 return 0;
76 }
77 temporary[i2++]=iCalcId;
78 temporary[i2]=0;
79
80 i+=i3;
81 }
82 else{
83 if(pobj_c){
84 //クラスメンバの場合、デストラクタには~が付くことを考慮
85 if(buffer[i]=='~'){
86 temporary[i2]='~';
87 i++;
88 i2++;
89 }
90 }
91
92 for(;;i++,i2++){
93 if(!IsVariableChar(buffer[i])){
94 temporary[i2]=0;
95 break;
96 }
97 temporary[i2]=buffer[i];
98 }
99
100 char parentName[VN_SIZE], memberName[VN_SIZE];
101 ReferenceKind refKind;
102 if( SplitMemberName( temporary, parentName, memberName, refKind ) )
103 {
104 if( pobj_c )
105 {
106 if( interfaceName )
107 {
108 lstrcpy( interfaceName, parentName );
109 }
110 else
111 {
112 compiler.errorMessenger.OutputFatalError();
113 return NULL;
114 }
115
116 char dummyMemberName[VN_SIZE];
117 if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
118 {
119 compiler.errorMessenger.Output(69,temporary,nowLine);
120 return NULL;
121 }
122 }
123 else
124 {
125 compiler.errorMessenger.Output(68,temporary,nowLine);
126 return NULL;
127 }
128
129 lstrcpy( temporary, memberName );
130 }
131 }
132
133 if( isMacro ){
134 //大文字に変換
135 CharUpper(temporary);
136 }
137
138 if(!pobj_c){
139 //クラスメンバ以外の場合のみ
140 //重複チェック
141
142 if(GetDeclareHash(temporary)){
143 compiler.errorMessenger.Output(15,temporary,nowLine);
144 return 0;
145 }
146 }
147
148 UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
149 pUserProc->SetParentClass( pobj_c );
150
151 // 親インターフェイスをセット
152 if( interfaceName && interfaceName[0] )
153 {
154 ::Interface *pTargetInterface = NULL;
155 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
156 {
157 if( pInterface->GetClass().GetName() == interfaceName )
158 {
159 pTargetInterface = pInterface;
160 break;
161 }
162 }
163 pUserProc->SetInterface( pTargetInterface );
164 }
165
166 if(isExport){
167 pUserProc->Using();
168 }
169
170 // パラメータを解析
171 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
172 pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
173
174 pUserProc->_paramStr = buffer + i;
175
176 return pUserProc;
177}
178
179void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
180{
181 extern HANDLE hHeap;
182 int i,i2,i3;
183 char temporary[8192];
184
185 // 名前空間管理
186 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
187 namespaceScopes.clear();
188
189 // Importsされた名前空間の管理
190 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
191 importedNamespaces.clear();
192
193 i=-1;
194 while(1){
195 i++;
196
197 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
198 /* Class ~ End Class
199 Interface ~ End Interface
200 を飛び越す */
201 i3=GetEndXXXCommand(source[i+1]);
202 for(i+=2,i2=0;;i++,i2++){
203 if(source[i]=='\0') break;
204 if(source[i]==1&&source[i+1]==(char)i3){
205 i++;
206 break;
207 }
208 }
209 if(source[i]=='\0') break;
210 continue;
211 }
212
213 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
214 for(i+=2,i2=0;;i2++,i++){
215 if( IsCommandDelimitation( source[i] ) ){
216 temporary[i2]=0;
217 break;
218 }
219 temporary[i2]=source[i];
220 }
221 namespaceScopes.push_back( temporary );
222
223 continue;
224 }
225 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
226 if( namespaceScopes.size() <= 0 ){
227 compiler.errorMessenger.Output(12, "End Namespace", i );
228 }
229 else{
230 namespaceScopes.pop_back();
231 }
232
233 i += 2;
234 continue;
235 }
236 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
237 for(i+=2,i2=0;;i2++,i++){
238 if( IsCommandDelimitation( source[i] ) ){
239 temporary[i2]=0;
240 break;
241 }
242 temporary[i2]=source[i];
243 }
244 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
245 {
246 compiler.errorMessenger.Output(64,temporary,cp );
247 }
248
249 continue;
250 }
251 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
252 importedNamespaces.clear();
253 continue;
254 }
255
256 if(source[i]==1&&source[i+1]==ESC_DECLARE){
257 for(i+=2,i2=0;;i2++,i++){
258 if(source[i]=='\n'){
259 temporary[i2]=0;
260 break;
261 }
262 temporary[i2]=source[i];
263 if(source[i]=='\0') break;
264 }
265 dllProcs.Add(namespaceScopes,temporary,i);
266
267 continue;
268 }
269 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
270 char statementChar = source[i+1];
271
272 for(i2=0;;i2++,i++){
273 if(IsCommandDelimitation(source[i])){
274 temporary[i2]=0;
275 break;
276 }
277 temporary[i2]=source[i];
278 if(source[i]=='\0') break;
279 }
280
281 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
282 userProcs.Insert( pUserProc, i );
283
284 /* Sub ~ End Sub
285 Function ~ End Function
286 Macro ~ End Macro
287 を飛び越す */
288 char endStatementChar = GetEndXXXCommand( statementChar );
289 for(i2=0;;i++,i2++){
290 if( source[i] == '\0' ) break;
291 if( source[i] == 1 && source[i+1] == endStatementChar ){
292 i++;
293 break;
294 }
295 }
296 if(source[i]=='\0') break;
297 continue;
298 }
299
300 //次の行
301 for(;;i++){
302 if(IsCommandDelimitation(source[i])) break;
303 }
304 if(source[i]=='\0') break;
305 }
306
307 ////////////
308 // 特殊関数
309 ////////////
310 namespaceScopes.clear();
311 importedNamespaces.clear();
312
313 compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
314 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
315 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
316 userProcs.Insert( pUserProc, i );
317}
Note: See TracBrowser for help on using the repository browser.