1 /******************************************************************************
2 *
3 * Copyright (C) 2006, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: lexem 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary: Working with lexems
15 *
16 ******************************************************************************/
17
18 #include "bcodes.h"
19 #include "compinit.h"
20 #include "../vm/vm.h"
21 #include "../vm/vmres.h"
22 #include "../vm/vmtype.h"
23 #include "../common/msg.h"
24 #include "alias.h"
25
26 const pubyte nameflags[] ={
27 // Флаги для функций
28 "entry" , "main", "result", "=alias",
29 // Флаги для типов
30 "=index", "=inherit", "protected",
31 // Флаги для define
32 "export", "namedef",
33 // Флаги для import
34 "link" ,"cdeclare", "exe"
35 };
36
37 const uint valflags[] = {
38 // Флаги для функций
39 GHBC_ENTRY | BFLAG_FUNC, GHBC_MAIN | BFLAG_FUNC, GHBC_RESULT | BFLAG_FUNC, GHRT_ALIAS | BFLAG_FUNC,
40 // Флаги для типов
41 GHTY_INDEX | BFLAG_TYPE, GHTY_INHERIT | BFLAG_TYPE, GHTY_PROTECTED | BFLAG_TYPE,
42 // Флаги для define
43 GHDF_EXPORT | BFLAG_DEFINE, GHDF_NAMEDEF | BFLAG_DEFINE,
44 // Флаги для import
45 GHIMP_LINK | BFLAG_IMPORT, GHIMP_CDECL | BFLAG_IMPORT, GHIMP_EXE | BFLAG_IMPORT, 0,
46 };
47
48 /*-----------------------------------------------------------------------------
49 *
50 * ID: bc_flag 03.11.06 0.0.A.
51 *
52 * Summary: Get flags. Return the next lexem
53 *
54 -----------------------------------------------------------------------------*/
55
56 plexem STDCALL bc_flag( plexem plex, uint type, pbcflag bcf )
57 {
58 uint eqflag, i;
59
60 bcf->value = _compile->cur->priv ? GHRT_PRIVATE : 0;
61
62 if ( !lexem_isys( plex, LSYS_LESS ))
63 return plex;
64
65 while ( 1 )
66 {
67 plex = lexem_next( plex, LEXNEXT_IGNLINE );
68 nonext:
69 if ( lexem_isys( plex, LSYS_GREATER ))
70 break;
71 if ( plex->type != LEXEM_NAME )
72 msg( MExpname | MSG_LEXERR, plex );
73
74 i = 0;
75 while ( valflags[ i ] )
76 {
77 if ( valflags[ i ] & type )
78 {
79 eqflag = ( *nameflags[ i ] == '=' ? 1 : 0 );
80 if ( mem_iseqzero( nameflags[ i ] + eqflag, lexem_getname( plex )))
81 {
82 bcf->value |= valflags[ i ] & 0xFFFFFF00;
83 break;
84 }
85 }
86 i++;
87 }
88 // Нет такого флага
89 if ( !valflags[ i ] )
90 msg( MNotattrib | MSG_LEXNAMEERR, plex );
91
92 if ( eqflag )
93 {
94 plexem next;
95
96 next = lexem_next( plex, LEXNEXT_IGNLINE );
97 if ( !lexem_isys( next, LSYS_EQ ))
98 msg( MAttrval | MSG_LEXNAMEERR, plex );
99 next = lexem_next( next, LEXNEXT_IGNLINE | LEXNEXT_NAME );
100 if ( valflags[i] & GHTY_INDEX )
101 {
102 if ( mem_iseqzero( lexem_getname( next ), "this" ))
103 {
104 bcf->index.idtype = arr_count( &_vm.objtbl );
105 bcf->index.msr = 0;
106 bcf->index.oftype = 0;
107 plex = lexem_next( next, 0 );
108 }
109 else
110 plex = desc_idtype( next, &bcf->index );
111 }
112 if ( valflags[i] & GHTY_INHERIT )
113 plex = desc_idtype( next, &bcf->inherit );
114 if ( valflags[i] & GHRT_ALIAS )
115 plex = alias_add( next, &bcf->alias );
116 goto nonext;
117 }
118 }
119 return lexem_next( plex, LEXNEXT_IGNLINE );
120 }
121
122 /*-----------------------------------------------------------------------------
123 *
124 * ID: bc_method 03.11.06 0.0.A.
125 *
126 * Summary: Find method id
127 *
128 -----------------------------------------------------------------------------*/
129
130 pvmfunc STDCALL bc_method( plexem plex, uint count, puint pars )
131 {
132 pvmfunc bcode;
133 ubyte name[256];
134
135 // Формируем имя метода или оператора
136 sprintf( name, "@%s", lexem_getname( plex ));
137 bcode = vm_find( name, count, pars );
138
139 return ( uint )bcode < MSGCOUNT ? 0 : bcode;
140 }
141
142 /*-----------------------------------------------------------------------------
143 *
144 * ID: bc_func 03.11.06 0.0.A.
145 *
146 * Summary: Find func id
147 *
148 -----------------------------------------------------------------------------*/
149
150 pvmfunc STDCALL bc_func( plexem plex, uint count, puint pars )
151 {
152 pvmfunc bcode;
153 ubyte name[256];
154
155 if ( plex->flag & LEXF_NAME )
156 mem_copyuntilzero( name, ( pubyte )plex->nameid );
157 else
158 {
159 // Формируем имя метода или оператора
160 if ( plex->flag & LEXF_METHOD )
161 sprintf( name, "@%s", lexem_getname( plex ));
162 else
163 if ( plex->flag & LEXF_OPERATOR )
164 sprintf( name, "#%s", ( pubyte )&plex->oper.name );
165 else
166 mem_copyuntilzero( name, lexem_getname( plex ));
167 }
168 bcode = vm_find( name, count, pars );
169 if ( ( uint )bcode < MSGCOUNT )
170 msg( ( uint )bcode | MSG_LEXERR | MSG_VALUE, plex, name );
171 if (( plex->flag & LEXF_PROPERTY ) && !( bcode->vmo.flag & GHBC_PROPERTY ))
172 msg( MUnkprop | MSG_LEXERR, plex );
173
174 return bcode;
175 }
176
177 /*-----------------------------------------------------------------------------
178 *
179 * ID: bc_oper 03.11.06 0.0.A.
180 *
181 * Summary: Find operator id
182 *
183 -----------------------------------------------------------------------------*/
184
185 pvmfunc STDCALL bc_oper( plexem plex, uint srctype, uint desttype,
186 uint srcof, uint destof )
187 {
188 uint ptr[12];
189 // pslexsys sys;
190
191 /* if ( opers[ plex->oper.operid ].flgs & OPF_NOP )
192 {
193 return NULL;
194 }*/
195 /* ??? if ( plex->sys->oper == OpNone )
196 {
197 *ret = ( lexitem->sys->type & OPER_RETUINT ? SUInt : desttype );
198 return 0;
199 }*/
200 ptr[0] = srctype ? srctype : desttype;
201 ptr[1] = srctype ? srcof : destof;
202 ptr[2] = desttype;
203 ptr[3] = destof;
204 plex->oper.name = oper2name( plex->oper.operid );
205 // if ( plex->oper.operid == OpIncright )
206 // print("XXX=%x", plex->oper.name );
207 // print("OK %i %i %i %i\n", srctype, desttype, plex->oper.operid, plex->oper.name );
208 plex->flag |= LEXF_OPERATOR;
209 return bc_func( plex, srctype ? 2 : 1, ( puint )&ptr );
210 }
211
212 /*-----------------------------------------------------------------------------
213 *
214 * ID: bc_property 03.11.06 0.0.A.
215 *
216 * Summary: Find property id
217 *
218 -----------------------------------------------------------------------------*/
219
220 pvmfunc STDCALL bc_property( plexem plex, uint objtype, uint setpar )
221 {
222 uint pars[12];
223
224 plex->flag |= LEXF_METHOD | LEXF_PROPERTY;
225 pars[0] = objtype;
226 pars[1] = 0;
227 pars[2] = setpar;
228 pars[3] = 0;
229 return bc_func( plex, 1 + ( setpar ? 1 : 0 ), ( puint )&pars );
230 }
231
232 /*-----------------------------------------------------------------------------
233 *
234 * ID: bc_isproperty 03.11.06 0.0.A.
235 *
236 * Summary: Find possible property id
237 *
238 -----------------------------------------------------------------------------*/
239
240 pvmfunc STDCALL bc_isproperty( plexem plex, uint objtype )
241 {
242 pvmfunc bcode;
243 uint id;
244 phashitem phi = NULL;
245 ubyte name[256];
246
247 // Формируем имя метода или оператора
248 sprintf( name, "@%s", lexem_getname( plex ));
249
250 phi = hash_find( &_vm.objname, name );
251
252 if ( !phi )
253 return ( pvmfunc )0;
254
255 id = *( puint )( phi + 1 );
256
257 while ( id )
258 {
259 bcode = ( pvmfunc )PCMD( id );
260 if ( bcode->vmo.flag & GHBC_PROPERTY )
261 {
262 if ( type_isinherit( objtype, bcode->params->type ))
263 return bcode;
264 }
265 id = bcode->vmo.nextname;
266 }
267 return NULL;
268 }
269
270 //--------------------------------------------------------------------------
271
272 pvmfunc STDCALL bc_funcname( plexem plexerr, pubyte name, uint count, puint pars )
273 {
274 lexem lexerr;
275
276 mem_zero( &lexerr, sizeof( lexem ));
277 lexerr.pos = plexerr->pos;
278 lexerr.flag |= LEXF_NAME;
279 lexerr.nameid = ( uint )name;
280
281 return bc_func( &lexerr, count, pars );
282 }
283
284 //--------------------------------------------------------------------------
285
286 uint CDECLCALL bc_find( plexem plexerr, pubyte name, uint count, ... )
287 {
288 va_list argptr;
289 uint i = 0;
290 uint params[ 32 ];
291 // pvmfunc pfunc;
292
293 va_start( argptr, count );
294 while ( i < count )
295 {
296 params[ i << 1 ] = va_arg( argptr, uint );
297 params[ ( i << 1 ) + 1 ] = 0; // flags oftype
298 i++;
299 }
300 va_end( argptr );
301
302 // pfunc = vm_find( name, count, ( puint )¶ms );
303 return bc_funcname( plexerr, name, count, ( puint )¶ms )->vmo.id;
304 // return ( uint )pfunc < MSGCOUNT ? 0 : pfunc->vmo.id;
305 }
306
307 /*-----------------------------------------------------------------------------
308 *
309 * ID: bc_getid 03.11.06 0.0.A.
310 *
311 * Summary: Get an id of vm
312 *
313 -----------------------------------------------------------------------------*/
314
315 uint STDCALL bc_getid( plexem plex )
316 {
317 phashitem phi;
318 // pscompile compile = ggentee.compile;
319
320 if ( plex->type != LEXEM_NAME )
321 msg( MWrongname | MSG_LEXERR, plex );
322
323 phi = hash_find( &_vm.objname, lexem_getname( plex ) );
324
325 // result = nametbl_find( &compile->gevm.nametbl,
326 // nametbl_getname( &compile->idname, lexitem->id ), FALSE );
327
328 // if ( result )
329 // result = nametbl_valget( &compile->gevm.nametbl, result );
330 // result = nametbl_valgetname( &compile->gevm.nametbl,
331 // nametbl_getname( &compile->idname, lexitem->id ));
332 return phi ? *( puint )( phi + 1 ) : 0;
333 }
334
335 /*-----------------------------------------------------------------------------
336 *
337 * ID: bc_obj 03.11.06 0.0.A.
338 *
339 * Summary:
340 *
341 -----------------------------------------------------------------------------*/
342 /*
343 uint STDCALL bc_obj( plexem plex )
344 {
345 uint type = bc_getid( plex );
346
347 if ( type )
348 return (( pvmobj )PCMD( type ))->type;
349 ret = (( psvmobj )objtbl_getobj( &compile->gevm, type ))->type;
350 if ( ret == OVM_BYTECODE || ret == OVM_EXFUNC || ret == OVM_STACKCMD ||
351 ret == OVM_GLOBAL )
352 lexitem->sys = ( pslexsys ) type;
353 return 0;
354 }
355 */
356 /*-----------------------------------------------------------------------------
357 *
358 * ID: bc_type 03.11.06 0.0.A.
359 *
360 * Summary: Get a type of the identifier
361 *
362 -----------------------------------------------------------------------------*/
363
364 uint STDCALL bc_type( plexem plex )
365 {
366 uint type = bc_getid( plex );
367
368 // pscompile compile = ggentee.compile;
369
370 /* if ( !type || (( psvmobj )objtbl_getobj( &compile->gevm, type ))->type != OVM_TYPE )
371 if ( noerror )
372 type = 0;
373 else
374 io_mess( IOC_UNKTYPE, lexitem );
375 */
376 return (( pvmobj )PCMD( type ))->type == OVM_TYPE ? type : 0;
377 }
378
379 /*-----------------------------------------------------------------------------
380 *
381 * ID: bc_resource 03.11.06 0.0.A.
382 *
383 * Summary: Get an identifier of the resource
384 *
385 -----------------------------------------------------------------------------*/
386
387 uint STDCALL bc_resource( pubyte ptr )
388 {
389 phashitem phi;
390 puint pidphi;
391
392 phi = hash_create( &_compile->resource, ptr );
393 pidphi = ( puint )( phi + 1 );
394 if ( !*pidphi )
395 *pidphi = vmres_addstr( ptr ) + 1;
396
397 return *pidphi - 1;
398 }
399
400