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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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