OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zpp.l] - Blame information for rev 209

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 dgisselq
/*******************************************************************************
2
**
3
** Filename:    zpp.l
4
**
5
** Project:     Zip CPU -- a small, lightweight, RISC CPU core
6
**
7
** Purpose:     The preprocessor for the Zip Assembler.
8
**
9
**      This routine strips comments, handles #define's, #ifdef's, and
10
**      #include statements in a C fashion.
11
**
12
**      #define macro's are also defined in the language and therefore
13
**      supposed to be supported, but the support isn't there yet.
14
**
15
** Creator:     Dan Gisselquist, Ph.D.
16 69 dgisselq
**              Gisselquist Technology, LLC
17 13 dgisselq
**
18
********************************************************************************
19
**
20
** Copyright (C) 2015, Gisselquist Technology, LLC
21
**
22
** This program is free software (firmware): you can redistribute it and/or
23
** modify it under the terms of  the GNU General Public License as published
24
** by the Free Software Foundation, either version 3 of the License, or (at
25
** your option) any later version.
26
**
27
** This program is distributed in the hope that it will be useful, but WITHOUT
28
** ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
29
** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
30
** for more details.
31
**
32
** You should have received a copy of the GNU General Public License along
33
** with this program.  (It's in the $(ROOT)/doc directory, run make with no
34
** target there if the PDF file isn't present.)  If not, see
35
**  for a copy.
36
**
37
** License:     GPL, v3, as defined and found on www.gnu.org,
38
**              http://www.gnu.org/licenses/gpl.html
39
**
40
**
41
*******************************************************************************/
42
 
43
%{
44
// #include 
45
#include 
46
#include 
47
#include 
48
#include 
49 34 dgisselq
#include 
50
#include 
51 13 dgisselq
 
52
using namespace std;
53
 
54 16 dgisselq
int yylex();
55
void    mark_line(void);
56
int     end_of_file(void);
57
void    pushf(const char *fname);
58
 
59 13 dgisselq
// #include "zprepr.tab.h"
60 16 dgisselq
int     ndef = 0, structno = 0;
61
char    *structid = NULL;
62 13 dgisselq
void    stb_define(const char *str);
63 34 dgisselq
bool    stb_current(const char *str);
64
bool    stb_hasargs(const char *str);
65
void    stb_expand(FILE *fout, const char *str);
66
std::string     stb_expand(const char *str);
67 13 dgisselq
void    stb_args(const char *str);
68
void    stb_macro(const char *value);
69
void    stb_addmacro(const char *value);
70
bool    stb_isdefined(const char *str);
71
const char      *stb_getdefn(const char *str);
72
%}
73 16 dgisselq
%x DEF DFA DFV DFV_EOL INDEF IFDEFV INNOTDEF NODEF NVRDEF COMMENT INSTRUCT
74 53 dgisselq
%x INDEF_EOL INNOTDEF_EOL GETSTRUCTID NVRDEF_EOL DONTDEF
75 13 dgisselq
%option noyywrap
76
%option stack
77
ID [_:A-Za-z][_:A-Za-z0-9]*
78 16 dgisselq
IDDOT {ID}("."{ID})*
79 13 dgisselq
 
80
%%
81
"*/"            { yy_pop_state(); }
82 53 dgisselq
[^*\n]+ { /* Ignore comments */ }
83 13 dgisselq
"*"+[^/]        { /* Ignore comments */ }
84 53 dgisselq
^"#include"[ \t]+\"[^\n\"]+\"   {
85 13 dgisselq
                char *ptr = &yytext[9], *start, *end, *str;
86
                while(isspace(*ptr))
87
                        ptr++;
88 16 dgisselq
                start = ++ptr;
89 13 dgisselq
                ptr++;
90
                while((*ptr)&&(*ptr != '\"'))
91
                        ptr++;
92
                *ptr = '\0';
93 16 dgisselq
                pushf(start);
94 13 dgisselq
                // push_file_state(yylineno); // and filename ...
95 16 dgisselq
                mark_line();
96 13 dgisselq
        }
97
^"#define"[ \t]+        { yy_push_state(DEF); }
98
 /* <*>^"#line"[ \t]+(0-9)+[ \t]+["][^"]*["][ \t]*\n       { } */
99 16 dgisselq
{IDDOT}/[^(]    {
100 34 dgisselq
                // fprintf(stderr, "Defining \'%s\'\n", yytext);
101 13 dgisselq
                stb_define(yytext);
102
                BEGIN DFV;
103
        }
104 16 dgisselq
{IDDOT}/[(]     { stb_define(yytext); BEGIN DFA; }
105 53 dgisselq
"("[^)\n]+")"                           {
106 16 dgisselq
                /* Process macro arguments */
107 13 dgisselq
                stb_args(yytext);
108
                BEGIN DFV;
109
        }
110 34 dgisselq
^[ \t]+ { stb_macro(yytext); /* Replicate initial spaces */ }
111
[ \t]+  { stb_macro(" "); /* Ignore all  but one internal space */ }
112
{ID}    {/* Parse to end of line, get value for our define */
113
                // fprintf(stderr, "%s may be a macro, line %d\n", yytext, yylineno);
114
                if ((!stb_current(yytext))&&(stb_isdefined(yytext))) {
115
                        // fprintf(stderr, "Recursive MACRO!\n");
116
                        stb_macro(stb_getdefn(yytext));
117
                } else {
118
                        // fprintf(stderr, "But it is not defined\n");
119
                        stb_macro(yytext);
120
                }
121
        }
122
{ID}[ \t]*[(][ \t]*{ID}[ \t]*(,[ \t]*{ID}[ \t]*)*[)]    {
123
                // fprintf(stderr, "%s may be a macro within a macro!\n", yytext);
124
                if ((!stb_current(yytext))&&(stb_isdefined(yytext))) {
125
                        if (stb_hasargs(yytext)) {
126
                                std::string str = stb_expand(yytext);
127
                                stb_macro(str.c_str());
128
                        } else {
129
                                char *dup = strdup(yytext), *ptr;
130
                                ptr = strchr(dup, '(');
131
                                *ptr = '\0';
132
                                stb_macro(stb_getdefn(dup));
133
                                free(dup);
134
                                yyless(strchr(yytext,'(')-yytext);
135
                        }
136 69 dgisselq
                } else if (!stb_current(yytext)) {
137
                        stb_macro(yytext);
138 34 dgisselq
                } else {
139
                        char *dup = strdup(yytext), *ptr;
140
                        ptr = strchr(dup, '(');
141
                        *ptr = '\0';
142
                        stb_macro(stb_getdefn(dup));
143
                        free(dup);
144
                        yyless(strchr(yytext,'(')-yytext);
145
                }
146
        }
147
[^a-zA-Z_0-9 \t\n]+     {/* Parse to end of line, get value for our define */
148
                // fprintf(stderr, "A: Adding to macro %s\n", yytext);
149 13 dgisselq
                stb_macro(yytext);
150 16 dgisselq
        }
151 34 dgisselq
0[xX][0-9A-Fa-f]+       {/* Get any hexadecimal constants */
152
                // fprintf(stderr, "B: Adding to macro %s\n", yytext);
153
                stb_macro(yytext);
154
        }
155
[0-9A-Fa-f]+[hH]        {/* Get any hexadecimal constants */
156
                // fprintf(stderr, "C: Adding to macro %s\n", yytext);
157
                stb_macro(yytext);
158
        }
159 53 dgisselq
[0-7]+[oO]      {/* Get any octal constants */
160 34 dgisselq
                // fprintf(stderr, "D: Adding to macro %s\n", yytext);
161
                stb_macro(yytext);
162
        }
163 53 dgisselq
[0-9]+  {/* Get any decimal constants */
164 34 dgisselq
                // fprintf(stderr, "E: Adding to macro %s\n", yytext);
165
                stb_macro(yytext);
166
        }
167 16 dgisselq
[ \t]*((;|"//").*)?$    {/* Parse to end of line, get value for our define */
168 13 dgisselq
                yy_pop_state();
169
        }
170 16 dgisselq
[ \t]*"\\"[ \t]*((;|"//").*)?\n {/* Continue onto next line */
171
                fprintf(yyout, "\n"); mark_line(); yylineno++;
172
                stb_macro("\n");
173
        }
174 53 dgisselq
^"#define".*$   { yy_push_state(DONTDEF); }
175
"\\"[ \t]*((;"//").*)?\n        {/* Continue onto next line */
176
                fprintf(yyout, "\n"); mark_line(); yylineno++; }
177
[a-zA-Z0-9_,.()]*       { }
178
[ \t]*                  { }
179
((;|"//").*)?$          { yy_pop_state(); }
180
"\\"[ \t]*((;|"//").*)?\n       {/* Continue onto next line */
181
                fprintf(yyout, "\n"); mark_line(); yylineno++; }
182 13 dgisselq
^[ \t]+.[dD][aA][tT][aA]?       { fprintf(yyout, "\tWORD"); }
183 53 dgisselq
^"#defcont"[ \t]+       {
184
                yy_push_state(DFV); }
185
^"#ifdef"[ \t]* { ndef = 0;
186
                yy_push_state(IFDEFV); }
187
^"#ifndef"[ \t]*        { ndef = 1;
188
                yy_push_state(IFDEFV); }
189
^"#ifdef"[ \t]* { ndef = 2;
190
                yy_push_state(IFDEFV); }
191
^"#ifndef"[ \t]*        { ndef = 2;
192
                yy_push_state(IFDEFV); }
193 16 dgisselq
{IDDOT} {
194 13 dgisselq
                bool    known = stb_isdefined(yytext);
195 53 dgisselq
                if (ndef == 2) {
196
                        BEGIN NVRDEF_EOL;
197
                } else if ( ((known)&&(ndef==0)) || ((!known)&&(ndef!=0)) ) {
198 13 dgisselq
                        BEGIN INDEF_EOL;
199
                } else {
200
                        BEGIN INNOTDEF_EOL;
201
                }
202
        }
203
        /* Not yet: ^"#if"[ \t]*                { yy_push_state(IFDEFE); }
204
        /* Not yet: ^"#if"[ \t]*                { yy_push_state(IFDEFE); }
205
        /* Not yet:  { yy_push_state(IFDEFE); } */
206
        /* ^"#elsif"[ \t]*      { yy_pop_state(); yy_push_state(IFDEFE); } */
207
[ \t]*$         { BEGIN INDEF; }
208
(;|"//").*$             { BEGIN INDEF; }
209
[ \t]*$         { BEGIN INNOTDEF; }
210
(;|"//").*$     { BEGIN INNOTDEF; }
211 53 dgisselq
[ \t]*$         { BEGIN NVRDEF; }
212
(;|"//").*$             { BEGIN NVRDEF; }
213
[^ \t\n].*$             { BEGIN INDEF; mark_line(); }
214
[^ \t\n].*$     { BEGIN INNOTDEF; mark_line(); }
215 13 dgisselq
^"#else"[ \t]*((;|"//").*)?$    { BEGIN NODEF; }
216
^"#else"[ \t]*((;|"//").*)?$            { BEGIN INDEF; }
217 53 dgisselq
^[^#\n]([^\n]*)$                { /* Skip text */ }
218 13 dgisselq
^"#elsif"[ \t]*         { BEGIN NVRDEF; }
219 53 dgisselq
^"#endif"[ \t]*((;|"//").*)?$   {
220
                                yy_pop_state(); }
221 26 dgisselq
^"#endif"[ \t]*"/*"     { BEGIN COMMENT; }
222 53 dgisselq
^"#endif"       { yy_pop_state(); }
223
<*>^"#ifdef"[ \t]*         { fprintf(stderr, "ERR: Line %d, Unknown ifdef!! (state = %d)\n", yylineno, YYSTATE);}
224
<*>^"#else"[ \t]*          { fprintf(stderr, "ERR: Line %d, Unknown else!! (state = %d)\n", yylineno, YYSTATE);}
225
<*>^"#endif"[ \t]*         { fprintf(stderr, "ERR: Line %d, Unknown endif!! (state = %d)\n", yylineno, YYSTATE);}
226
^"#struct"[ \t]*        { yy_push_state(GETSTRUCTID); structno  = 0; }
227
<*>^"#"{ID}[ \t]*          {
228
        fprintf(stderr, "ERR: Line %d, unrecognized preprocessor instruction, \'%s\' (state = %d)\n",
229
                        yylineno, yytext, YYSTATE);
230
        }
231 16 dgisselq
{ID}/[ \t\n;/]  { BEGIN INSTRUCT;
232
                structid = strdup(yytext);
233
                }
234
{ID}("."{ID})*  {
235
                fprintf(yyout, "\t%s.%s\tequ\t%d", structid, yytext, structno++); }
236
^"#endstruct".*$        { yy_pop_state(); }
237 13 dgisselq
        /* Not yet: ^"#struct"[ \t]*    {}      */
238
        /* Not yet: ^"#endstruct"[ \t]* {}      */
239
        /* Not yet: ^"#seg"[ \t]*       {}      */
240
{ID}/[^(]       {
241
                if (stb_isdefined(yytext))
242
                        fprintf(yyout, "%s", stb_getdefn(yytext));
243
                else
244
                        fprintf(yyout, "%s", yytext);
245
        }
246 34 dgisselq
{ID}([ \t]*)    {
247
                if (stb_isdefined(yytext))
248
                        fprintf(yyout, "%s", stb_getdefn(yytext));
249
                else
250
                        fprintf(yyout, "%s", yytext);
251
        }
252
{ID}[ \t]*[(][ \t]*{ID}[ \t]*(,[ \t]*{ID}[ \t]*)*[)]    {
253
                // fprintf(stderr, "%s may be a macro!\n", yytext);
254
                if (stb_isdefined(yytext)) {
255
                        if (stb_hasargs(yytext)) {
256
                                stb_expand(yyout, yytext);
257
                        } else {
258
                                fprintf(yyout, "%s", stb_getdefn(yytext));
259
                                yyless(strchr(yytext,'(')-yytext);
260
                        }
261
                } else {
262
                        // fprintf(stderr, "But it is not defined\n");
263
                        fprintf(yyout, "%s", yytext);
264
                }
265
        }
266 69 dgisselq
"\'"(("\\\'")|([^'\\])|("\\"[0abfnrtv])|("\\\\")|("\\\"")){1,4}"\'" { ECHO; }
267 16 dgisselq
<*>[ \t]*"//".*$   { /* Ignore (trailing) comment only lines */ }
268
<*>[ \t]*";".*$            { /* Ignore (trailing) comment only lines */ }
269 26 dgisselq
<*>"#warning".*$   { fprintf(stderr, "WARNING: %s\n", &yytext[8]); }
270
<*>"#error".*$             { fprintf(stderr, "ERROR: %s\n", &yytext[8]); exit(-1); }
271 13 dgisselq
<*>"/*"                    { yy_push_state(COMMENT); }
272
<*>[ \t]+          { ECHO; }
273 16 dgisselq
<*>\n                      { ECHO; yylineno++; mark_line(); }
274 13 dgisselq
        /* <*>.                    { printf("Unmatched \'%c\'\n", yytext[0]); } */
275 53 dgisselq
<>       { fprintf(stderr, "Unexpected EOF!  Expecting #endif\n"); yyterminate(); }
276
<>               { fprintf(stderr, "Unexpected EOF!  Expecting #endif\n"); yyterminate(); }
277
<>       { fprintf(stderr, "Unexpected EOF!  Expecting */\n"); yyterminate(); }
278
<>       { fprintf(stderr, "Unexpected EOF!  Expecting #endstruct\n"); yyterminate(); }
279
<>       { fprintf(stderr, "Unexpected EOF!  Expecting #struct ID, then #endstruct\n"); yyterminate(); }
280
<> { fprintf(stderr, "Unexpected EOF!  Expecting end of line\n"); yyterminate(); }
281
<        { fprintf(stderr, "Unexpected EOF  Expecting end of line, then #endif\n"); yyterminate(); }
282 26 dgisselq
<>       { if (end_of_file()) yyterminate(); }
283 13 dgisselq
 
284
%%
285
 
286 34 dgisselq
class   SYMTABLE_ACTION {
287
public:
288
        // Types: 0 (end of actions), 1-X, argument number, <0 raw string
289
        int             m_type;
290
        std::string     m_str;          // if m_type < 0, have m_str
291
};
292
 
293 13 dgisselq
class   SYMTABLE_ENTRY {
294
private:
295 34 dgisselq
        bool    m_reduced;
296 13 dgisselq
        std::string     &trim(std::string &s) {
297
                std::string::iterator   ptr = s.end();
298
 
299
                while((ptr >= s.begin())&&(isspace(*ptr)))
300
                        *ptr-- = '\0';
301
 
302
                return s;
303
        }
304
 
305
public:
306
        std::string     m_name, m_value, m_args;
307 34 dgisselq
        std::vector     m_actions;
308 13 dgisselq
        SYMTABLE_ENTRY(const char *str) : m_name(str) {
309
                trim(m_name);
310 34 dgisselq
                m_reduced = false;
311 13 dgisselq
        }
312
        SYMTABLE_ENTRY &operator+=(const char *str) {
313
                const char      *start = str;
314
 
315
                while(isspace(*start))
316
                        start++;
317
                if (m_value.length()!=0)
318
                        m_value += " ";
319
 
320 34 dgisselq
                m_value += str;
321 13 dgisselq
 
322
                /*
323
                printf("ENTRY::SYMBOL \'%s\' NOW = \'%s\'\n",
324
                        m_name.c_str(), m_value.c_str());
325
                */
326
                return *this;
327
        }
328
        SYMTABLE_ENTRY &setargs(const char *str) {
329
                m_args += str;
330
                return *this;
331
        }
332
 
333 16 dgisselq
        const std::string &getdefn(void) {
334 13 dgisselq
                return m_value;
335
        }
336 34 dgisselq
 
337
        bool    hasargs(void) {
338
                return (m_args.size()>0);
339
        }
340
 
341
        void    reduce(void) {
342
                if (m_reduced)
343
                        return;
344
 
345
                // fprintf(stderr, "Reducing %s ( %s ) \n", m_name.c_str(), m_args.c_str());
346
                std::vector     alist;
347
                int i=0, bg, en;
348
                do {
349
                        if ((m_args[i] == ',')||(m_args[i] == '('))
350
                                i++;
351
                        while((m_args[i])&&(isspace(m_args[i])))
352
                                i++;
353
                        bg = i;
354
                        while((m_args[i])&&(
355
                                (isalpha(m_args[i]))
356
                                ||(m_args[i]==':')
357
                                ||(m_args[i]=='_')
358
                                ||(isdigit(m_args[i]))))
359
                                i++;
360
                        en = i;
361
                        while((m_args[i])&&(isspace(m_args[i])))
362
                                i++;
363
 
364
                        alist.push_back(m_args.substr(bg,en-bg));
365
                        // printf("Found argument %2ld of %s: \'%s\'\n",
366
                                // alist.size(),
367
                                // m_name.c_str(),
368
                                // m_args.substr(bg,en-bg).c_str());
369
                } while((m_args[i])&&(m_args[i] == ','));
370
 
371
                assert(m_args[i] == ')');
372
 
373
                // Now that we know our arguments, lets look for these
374
                // arguments in our macro definition
375
                std::string     building;
376
                i = 0;
377
                while(m_value[i]) {
378
                        int     nxti = m_value.size(), nxtv;
379
                        for(int a=0; a
380
                                const char *ptr;
381
                                ptr = strstr(m_value.c_str()+i, alist[a].c_str());
382
                                while((ptr)&&(ptr-m_value.c_str() < nxti)) {
383
                                        int loc = ptr-m_value.c_str();
384
                                        const char *pre = ptr-1;
385
                                        const char *pst = ptr+alist[a].size();
386
                                        if ((loc < nxti)&&(
387
                                                (loc == i)
388
                                                ||((!isalpha(*pre)
389
                                                        &&(*pre != '_')
390
                                                        &&(*pre != ':')
391
                                                        &&(!isdigit(*pre)))))
392
                                                &&((*pst=='\0')
393
                                                ||(     (!isalpha(*pst))
394
                                                        &&(*pst != '_')
395
                                                        &&(*pst != ':')
396
                                                        &&(!isdigit(*pst)))))
397
                                        {
398
                                                        nxti = loc;
399
                                                        nxtv = a;
400
                                                        break;
401
                                        } else {
402
                                                ptr = strstr(m_value.c_str()+loc, alist[a].c_str());
403
                                                loc = ptr-m_value.c_str();
404
                                        }
405
                                }
406
                        }
407
 
408
                        if (nxti < m_value.size()) {
409
                                // Found an argument!!
410
                                SYMTABLE_ACTION act;
411
                                if (nxti > i) {
412
                                        act.m_type = -1;
413
                                        act.m_str = m_value.substr(i,nxti-i);
414
                                        // printf("ACTION: \'%s\'\n", act.m_str.c_str());
415
                                        m_actions.push_back(act);
416
                                }
417
                                act.m_type = nxtv;
418
                                act.m_str = "";
419
                                m_actions.push_back(act);
420
                                // printf("ACTION[%2d]: \'%s\'\n", nxtv, alist[nxtv].c_str());
421
 
422
                                i = nxti+alist[nxtv].size();
423
                        } else break; // No more arguments
424
                } if (i
425
                        SYMTABLE_ACTION act;
426
                        act.m_type = -1;
427
                        act.m_str = m_value.substr(i);
428
                        // printf("ACTION: \'%s\'\n", act.m_str.c_str());
429
                        m_actions.push_back(act);
430
                }
431
                m_reduced = true;
432
        }
433
 
434
        std::string expand(std::string args) {
435
                if (!m_reduced)
436
                        reduce();
437
                std::vector     alist;
438
                std::string     result;
439
 
440
                // printf("Expanding %s\n", args.c_str());
441
                int i=0, bg, en, nest=-1;
442
                do {
443
                        if ((args[i] == '(')||(args[i] == ',')) {
444
                                if (args[i] =='(')
445
                                        nest++;
446
                                i++;
447
                        }
448
                        while((args[i])&&(isspace(args[i])))
449
                                i++;
450
                        bg = i;
451
                        while((args[i])&&(args[i] != ',')&&((args[i] != ')')||(nest != 0))) {
452
                                if (args[i] == '(')
453
                                        nest++;
454
                                else if (args[i] == ')')
455
                                        nest--;
456
                                i++;
457
                        } en = i-1;
458
                        while((en>0)&&(isspace(args[en])))
459
                                en--;
460
                        alist.push_back(args.substr(bg,en+1-bg));
461
                        // printf("Argument %2ld of %s maps to \'%s\'\n",
462
                                // alist.size(),
463
                                // m_name.c_str(),
464
                                // args.substr(bg,en+1-bg).c_str());
465
                } while((args[i])&&(args[i] == ','));
466
 
467
                // printf("At end, args[i] = \'%s\'\n", &args[i]);
468
                assert(args[i] == ')');
469
 
470
                // printf("Filling in %ld actions\n", m_actions.size());
471
                for(i=0; i
472
                        if((m_actions[i].m_type >= 0)&&(m_actions[i].m_type < alist.size()))
473
                                result += alist[m_actions[i].m_type].c_str();
474
                        else if (m_actions[i].m_type < 0)
475
                                result += m_actions[i].m_str.c_str();
476
                        // else {
477
                                // fprintf(fout, "m_type = %d, size = %ld\n", m_actions[i].m_type, alist.size());
478
                        // }
479
                }
480
 
481
                return result;
482
        }
483 13 dgisselq
};
484
 
485
class   SYMBOL_TABLE {
486
private:
487
        typedef SYMTABLE_ENTRY  *TBLV;
488
        typedef std::list       TBLT;
489
 
490
        TBLT    m_tbl;
491
        TBLT::iterator  lookup(const char *str) {
492
                TBLT::iterator  i = m_tbl.begin();
493
                for(; (i!= m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0); i++)
494
                        ;
495
                if ((i != m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())==0))
496
                        return i;
497
                return m_tbl.end();
498
        }
499
 
500
public:
501
        SYMBOL_TABLE(void) {}
502
 
503
        void define(const char *str) {
504
                SYMTABLE_ENTRY  *v = new SYMTABLE_ENTRY(str);
505
                TBLT::iterator  i = m_tbl.begin();
506
                for(; (i!= m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0); i++)
507
                        ;
508
                m_tbl.insert(i, v);
509
 
510 34 dgisselq
                // fprintf(stderr, "SYMS::Defining SYMBOL: \'%s\'\n", str);
511 13 dgisselq
        }
512
 
513
        bool defined(const char *str) {
514
                TBLT::iterator  i = lookup(str);
515
                if (i==m_tbl.end())
516
                        return false;
517
                else
518
                        return true;
519
        }
520
 
521
 
522
        void    undefine(const char *str) {
523
                TBLT::iterator  i = lookup(str);
524
                if (i == m_tbl.end())
525
                        return;
526
                TBLV    v = (*i);
527
                m_tbl.erase(i);
528
                delete  v;
529
        }
530
 
531
        void    addmacro(const char *name, const char *str) {
532
                TBLT::iterator i = lookup(name);
533
                if (i == m_tbl.end()) {
534 46 dgisselq
                        fprintf(stderr, "ADDMACRO::INTERNAL ERR, \'%s\' NOT DEFINED!\n", name);
535 13 dgisselq
                } *(*i) += str;
536
        }
537
 
538
        void    addargs(const char *name, const char *str) {
539
                TBLT::iterator i = lookup(name);
540
                if (i == m_tbl.end()) {
541
                        fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
542
                } (*i)->setargs(str);
543
        }
544 34 dgisselq
        bool    hasargs(const char *name) {
545
                TBLT::iterator i = lookup(name);
546
                if (i == m_tbl.end()) {
547
                        return false;
548
                } return (*i)->hasargs();
549
        }
550 13 dgisselq
        const   char *getdefn(const char *name) {
551
                TBLT::iterator i = lookup(name);
552
                if (i == m_tbl.end()) {
553 46 dgisselq
                        fprintf(stderr, "GETDEFN::INTERNAL ERR, \'%s\' NOT DEFINED!\n", name);
554 13 dgisselq
                        return NULL;
555
                } (*i)->getdefn().c_str();
556
        }
557 34 dgisselq
 
558
        std::string     expand(const char *name, const char *ptr) {
559
                TBLT::iterator  i = lookup(name);
560
                if (i==m_tbl.end())
561
                        return std::string("");
562
                return (*i)->expand(std::string(ptr));
563
        }
564 13 dgisselq
 
565
};
566
 
567
SYMTABLE_ENTRY  *last = NULL;
568
SYMBOL_TABLE    syms;
569
std::string     last_define;
570
 
571 46 dgisselq
char    *stb_trim(const char *str) {
572
        // fprintf(stderr, "Checking whether %s needs to be expanded\n",str);
573
        char *dup = strdup(str), *chr;
574
        chr = strchr(dup, '(');
575
        if (chr != NULL)
576
                *chr = '\0';
577
        // fprintf(stderr, "\tLooking it up by the name \'%s\'\n", dup);
578
 
579
        // Now, let's trim our string
580
        char    *end = dup+strlen(dup)-1;
581
        while((*dup)&&(end>dup)&&(isspace(*end)))
582
                *end-- = '\0';
583
        return dup;
584
}
585
 
586 13 dgisselq
void    stb_define(const char *str) {
587 34 dgisselq
        /*
588
        if (last_define.size()>0) {
589
                fprintf(stderr, "LAST-DEFINE(%s): %s\n", last_define.c_str(),
590
                        stb_getdefn(last_define.c_str()));
591
        } */
592 46 dgisselq
        char    *alt = stb_trim(str);
593
        if (syms.defined(alt)) {
594 13 dgisselq
                fprintf(stderr, "WARNING!  Symbol \'%s\' is already defined!\n", str);
595
                syms.undefine(str);
596
        }
597
 
598 46 dgisselq
        syms.define(alt);
599
        last_define = alt;
600
        free(alt);
601 13 dgisselq
}
602
 
603
void    stb_args(const char *args) {
604
        syms.addargs(last_define.c_str(), args);
605
}
606
 
607
void    stb_macro(const char *value) {
608
        syms.addmacro(last_define.c_str(), value);
609
}
610
 
611
void    stb_addmacro(const char *value) {
612
        syms.addmacro(last_define.c_str(),value);
613
}
614
 
615
bool    stb_isdefined(const char *str) {
616 46 dgisselq
        char    *dup = stb_trim(str);
617
        bool r = (syms.defined(dup));
618
        free(dup);
619
        return r;
620 13 dgisselq
}
621
 
622
const char *stb_getdefn(const char *str) {
623 46 dgisselq
        char    *dup = stb_trim(str);
624
        const char      *r;
625
        r = syms.getdefn(dup);
626
        free(dup);
627
        return r;
628 13 dgisselq
}
629
 
630 34 dgisselq
bool    stb_current(const char *str) {
631
        return (strcmp(str, last_define.c_str())==0);
632
}
633
 
634
bool    stb_hasargs(const char *str) {
635 46 dgisselq
        char    *dup = stb_trim(str);
636
        bool r = (syms.hasargs(dup));
637
        // fprintf(stderr, "\t%s has %sarguments\n", dup, (r)?"":"no ");
638
        free(dup);
639
        return r;
640 34 dgisselq
}
641
 
642
std::string     stb_expand(const char *macro) {
643
        const   char    *ptr;
644
        std::string     str;
645
        ptr = strchr(macro, '(');
646
        assert(ptr);
647
        ptr--;
648
        while((ptr>macro)&&(isspace(*ptr)))
649
                ptr--;
650
        char *nam = strndup(macro, ptr+1-macro);
651
        ptr = strchr(ptr, '(');
652
        // fprintf(stderr, "Requesting an expansion of %s -- %s\n", nam, ptr);
653
        str = syms.expand(nam, ptr);
654
        free(nam);
655
 
656
        return str;
657
}
658
 
659
void    stb_expand(FILE *fout, const char *macro) {
660
        std::string     str = stb_expand(macro);
661
        fprintf(fout, "%s", str.c_str());
662
}
663
 
664 16 dgisselq
class   BUFSTACK {
665
public:
666
        FILE            *m_fp;
667
        char            *m_fname;
668
        int             m_lineno;
669
        BUFSTACK        *m_prev;
670
        YY_BUFFER_STATE m_bs;
671
 
672
        static  BUFSTACK        *curbs;
673
        static  const char      *curfilename;
674
 
675
        BUFSTACK(void) {
676
                m_fp = stdin;
677
 
678
                if (curbs)
679
                        curbs->m_lineno = yylineno;
680
                m_prev = curbs;
681
                // m_bs = yy_create_buffer(fp, YY_BUF_SIZE);
682
                m_fname = strdup("(stdin)");
683
                // yy_switch_to_buffer(m_bs);
684
                m_bs = NULL;
685
                curbs = this;
686
                m_lineno = 1;
687
                curfilename = m_fname;
688
 
689
                yyrestart(m_fp);
690
                yylineno = 1;
691
        }
692
 
693
        BUFSTACK(const char *fname) {
694
                m_fp = fopen(fname, "r");
695
                if (!m_fp) {
696 36 dgisselq
                        char *pathptr = getenv("ZIPINC");
697
                        if (!pathptr) {
698
                                fprintf(stderr, "Cannot open %s\n", fname);
699
                                perror("O/S Err:");
700
                                exit(-1);
701
                        } else {
702
                                char    *dptr, *colonp;
703
                                char *pathcpy = new char[strlen(pathptr)+8192];
704
                                strcpy(pathcpy, pathptr);
705
 
706 53 dgisselq
                                // fprintf(stderr, "ZIPINC := %s\n", pathptr);
707 36 dgisselq
                                dptr = pathptr;
708
                                while((!m_fp)&&(NULL != (colonp = strchr(dptr, ':')))) {
709
                                        strncpy(pathcpy, dptr, colonp-pathptr);
710
                                        strcat(pathcpy, "/");
711
                                        strcat(pathcpy, fname);
712 53 dgisselq
                                        // fprintf(stderr, "Looking for include file, %s\n", pathcpy);
713 36 dgisselq
                                        if (access(fname, R_OK)==0)
714
                                                m_fp = fopen(pathcpy, "r");
715
                                        dptr = colonp+1;
716
                                } if ((!m_fp)&&(*dptr)) {
717
                                        strcpy(pathcpy, dptr);
718
                                        strcat(pathcpy, "/");
719
                                        strcat(pathcpy, fname);
720 53 dgisselq
                                        // fprintf(stderr, "Looking for include file, %s\n", pathcpy);
721 36 dgisselq
                                        m_fp = fopen(pathcpy, "r");
722
                                } if (!m_fp) {
723
                                        fprintf(stderr, "Cannot open %s\n", fname);
724
                                        perror("O/S Err:");
725
                                        exit(-1);
726
                                }
727
 
728
                                delete[] pathcpy;
729
                        }
730 16 dgisselq
                }
731
 
732
                if (curbs)
733
                        curbs->m_lineno = yylineno;
734
                m_prev = curbs;
735
                m_bs = yy_create_buffer(m_fp, YY_BUF_SIZE);
736
                m_fname = strdup(fname);
737
                yy_switch_to_buffer(m_bs);
738
                curbs = this;
739
                m_lineno = 1;
740
                curfilename = m_fname;
741
 
742
                yyrestart(m_fp);
743
                yylineno = 1;
744
        }
745
 
746
        ~BUFSTACK(void) {
747
                // fprintf(stderr, "DELETING(%s)\n", m_fname);
748
                fclose(m_fp);
749
                free(m_fname);
750
                if (m_bs)
751
                        yy_delete_buffer(m_bs);
752
                curbs = m_prev;
753
 
754
                if (curbs) {
755
                        yy_switch_to_buffer(curbs->m_bs);
756
                        yylineno = curbs->m_lineno;
757
                        curfilename = curbs->m_fname;
758
                }
759
        }
760
 
761
        void    mark(void) {
762
                FILE    *fp = yyout;
763
                if (!fp) fp = stdout;
764
                fprintf(fp, "#line %d \"%s\"\n", yylineno, m_fname);
765
        }
766
 
767 26 dgisselq
        void    markline(void) {
768
                FILE    *fp = yyout;
769
                if (!fp) fp = stdout;
770
                fprintf(fp, "#line %d\n", yylineno);
771
        }
772
 
773 16 dgisselq
        static  void pop(void) {
774
                // fprintf(stderr, "POP! (%s)\n", curbs->m_fname);
775
                if (curbs)
776
                        delete curbs;
777
        }
778
};
779
 
780
BUFSTACK *BUFSTACK::curbs = NULL;
781
const char *BUFSTACK::curfilename = NULL;
782
 
783
int             last_marked_line = -1;
784
const char      *last_marked_file = NULL;
785
void    mark_line(void) {
786
        if ((yylineno != last_marked_line+1)||(BUFSTACK::curfilename != last_marked_file))
787 26 dgisselq
                if (BUFSTACK::curfilename == last_marked_file)
788
                        BUFSTACK::curbs->markline();
789
                else BUFSTACK::curbs->mark();
790 16 dgisselq
        last_marked_line = yylineno;
791
        last_marked_file = BUFSTACK::curfilename;
792
}
793
 
794
int     end_of_file(void) {
795
        BUFSTACK::pop();
796
        return (BUFSTACK::curbs == NULL);
797
}
798
 
799
void    pushf(const char *fname) {
800
        BUFSTACK        *bs = new BUFSTACK(fname);
801
}
802
 
803 13 dgisselq
int main(int argc, char **argv) {
804 16 dgisselq
        yylineno = 1;
805
        if (argc < 2) { // Stdin only
806
                BUFSTACK::curbs = new BUFSTACK();
807
                yylex();
808
        } else {
809
                for(int argn=1; argn
810
                        BUFSTACK        *bs = new BUFSTACK(argv[argn]);
811
                        mark_line();
812
                        yylex();
813
                        // delete       bs;
814
                }
815
        }
816 26 dgisselq
 
817
        return 0;
818 13 dgisselq
}
819 53 dgisselq
// .*           { fprintf(stderr, "Ignoring everything, line %d, \'%s\'\n", yylineno, yytext); /* Ignore everything in these states*/ }
820 13 dgisselq
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.