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 pm = macro_set( plex, namedef, idname );
78
79 next = lexem_next( plex, LEXNEXT_IGNLINE );
80 if ( lexem_isys( next, LSYS_EQ ))
81 {
82 lastval = 0;
83 plex = lexem_next( next, LEXNEXT_IGNLINE );
84 if ( plex->type == LEXEM_NAME )
85 {
86 pm->mr.vallexem.type = LEXEM_NAME;
87 pm->mr.vallexem.nameid = plex->nameid;
88 plex = lexem_next( plex, LEXNEXT_IGNLINE | LEXNEXT_IGNCOMMA );
89 }
90 else
91 {
92 plex = macroexpr( plex, &pres );
93 pm->mr = *pres;
94
95 if ( pm->mr.vallexem.type == LEXEM_NUMBER &&
96 ( pm->mr.vallexem.num.type == TUint ||
97 pm->mr.vallexem.num.type == TInt ))
98 lastval = pm->mr.vallexem.num.vint + 1;
99 plex = lexem_next( plex, LEXNEXT_SKIPLINE );
100 }
101 goto export;
102 }
103 else
104 {
105 pm->mr.vallexem.num.type = TUint;
106 pm->mr.vallexem.num.vint = lastval++;
107 // printf("lv=%i\n", lastval );
108 }
109 plex = lexem_next( plex, LEXNEXT_IGNLINE | LEXNEXT_IGNCOMMA );
110
111 export:
112 if ( export )
113 {
114 uint iflag;
115 s_descid field;
116 pubyte pdata = ( pubyte )lexem_getstr( &pm->mr.vallexem );
117
118 field.flgdesc = DESCID_GLOBAL;
119 field.idtype = TStr;
120 iflag = VAR_NAME;
121 field.name = pname;
122
123 switch ( pm->mr.vallexem.type )
124 {
125 case LEXEM_STRING : break;
126 case LEXEM_BINARY :
127 field.idtype = TBuf;
128 break;
129 case LEXEM_NUMBER :
130 field.idtype = pm->mr.vallexem.num.type;
131 pdata = ( pubyte )&pm->mr.vallexem.num.vint;
132 break;
133 case LEXEM_NAME :
134 iflag |= VAR_IDNAME;
135 pdata = lexem_getname( &pm->mr.vallexem );
136 break;
137 }
138 count++;
139 iflag |= VAR_DATA;
140 out_addvar( &field, iflag, pdata );
141 }
142 }
143 if ( export )
144 {
145 out_setuint( off_count, count );
146 pname = out_finish();
147 load_define( &pname );
148 }
149 return plex;
150 }
151
Edit