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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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