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: define 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary: define command
15 *
16 ******************************************************************************/
17
18 #include "../genteeapi/gentee.h"
19 #include "define.h"
20 #include "macro.h"
21 #include "bcodes.h"
22 #include "out.h"
23
24 /*-----------------------------------------------------------------------------
25 *
26 * ID: define 22.11.06 0.0.A.
27 *
28 * Summary: define command
29 *
30 -----------------------------------------------------------------------------*/
31
32 plexem STDCALL define( plexem plex )
33 {
34 uint lastval = 0;
35 uint idname = 0;
36 bcflag bcf;
37 plexem next, pgroup = NULL;
38 pmacro pm;
39 uint export, namedef = 0;
40 pubyte pname;
41 uint off_count, count = 0;
42 pmacrores pres;
43
44 plex = lexem_next( plex, LEXNEXT_IGNLINE );
45 if ( plex->type == LEXEM_NAME ) // Имеется имя у множества
46 {
47 idname = plex->nameid + 1;
48 // macro_set( plex, LEXEM_NUMBER, 0 )->flag = MACROF_GROUP;
49 pgroup = plex;
50 plex = lexem_next( plex, LEXNEXT_IGNLINE );
51 }
52 plex = bc_flag( plex, BFLAG_DEFINE, &bcf );
53 export = bcf.value & GHDF_EXPORT;
54 namedef = LEXEM_NUMBER | ( bcf.value & GHDF_NAMEDEF ? MACRO_NAMEDEF : 0 );
55 if ( pgroup )
56 macro_set( pgroup, namedef, 0 )->flag = MACROF_GROUP;
57
58 if ( export )
59 {
60 out_init( OVM_DEFINE, bcf.value, idname ?
61 hash_name( &_compile->names, idname - 1 ) : 0 );
62 off_count = out_adduint( 0 );
63 }
64
65 plex = lexem_next( plex, LEXNEXT_IGNLINE | LEXNEXT_LCURLY );
66 while ( 1 )
67 {
68 if ( lexem_isys( plex, LSYS_RCURLY ))
69 break;
70 if ( plex->type != LEXEM_NAME )
71 msg( MExpname | MSG_LEXERR, plex );
72
73 if ( export )
74 {
75 pname = lexem_getname( plex );
76 }
77 // print("Lex=%s\n", lexem_getname( plex ));
78 pm = macro_set( plex, namedef, idname );
79
80 next = lexem_next( plex, LEXNEXT_IGNLINE );
81 if ( lexem_isys( next, LSYS_EQ ))
82 {
83 lastval = 0;
84 plex = lexem_next( next, LEXNEXT_IGNLINE );
85 if ( plex->type == LEXEM_NAME )
86 {
87 pm->mr.vallexem.type = LEXEM_NAME;
88 pm->mr.vallexem.nameid = plex->nameid;
89 plex = lexem_next( plex, LEXNEXT_IGNLINE | LEXNEXT_IGNCOMMA );
90 }
91 else
92 {
93 plex = macroexpr( plex, &pres );
94 pm->mr = *pres;
95
96 if ( pm->mr.vallexem.type == LEXEM_NUMBER &&
97 ( pm->mr.vallexem.num.type == TUint ||
98 pm->mr.vallexem.num.type == TInt ))
99 lastval = pm->mr.vallexem.num.vint + 1;
100 plex = lexem_next( plex, LEXNEXT_SKIPLINE );
101 }
102 goto export;
103 }
104 else
105 {
106 pm->mr.vallexem.num.type = TUint;
107 pm->mr.vallexem.num.vint = lastval++;
108 // printf("lv=%i\n", lastval );
109 }
110 plex = lexem_next( plex, LEXNEXT_IGNLINE | LEXNEXT_IGNCOMMA );
111
112 export:
113 if ( export )
114 {
115 uint iflag;
116 s_descid field;
117 pubyte pdata = ( pubyte )lexem_getstr( &pm->mr.vallexem );
118
119 field.flgdesc = DESCID_GLOBAL;
120 field.idtype = TStr;
121 iflag = VAR_NAME;
122 field.name = pname;
123
124 switch ( pm->mr.vallexem.type )
125 {
126 case LEXEM_STRING : break;
127 case LEXEM_BINARY :
128 field.idtype = TBuf;
129 break;
130 case LEXEM_NUMBER :
131 field.idtype = pm->mr.vallexem.num.type;
132 pdata = ( pubyte )&pm->mr.vallexem.num.vint;
133 break;
134 case LEXEM_NAME :
135 iflag |= VAR_IDNAME;
136 pdata = lexem_getname( &pm->mr.vallexem );
137 break;
138 }
139 count++;
140 iflag |= VAR_DATA;
141 out_addvar( &field, iflag, pdata );
142 }
143 }
144 if ( export )
145 {
146 out_setuint( off_count, count );
147 pname = out_finish();
148 load_define( &pname );
149 }
150 return plex;
151 }
152
153