scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 664e782912da639d082308433dd7dddfcf9922ce
parent 7c3cd98f410be4dfea41213eb55c6ff88b09b280
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu,  7 May 2015 15:11:47 +0200

Add addinput() lexer function

This function is thought for a first attempt to add preprocessor
capabilities to the lexer.

Diffstat:
Mcc1/cc1.h | 3+++
Mcc1/error.c | 6+-----
Mcc1/lex.c | 66++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mcc1/main.c | 2+-
4 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -262,6 +262,9 @@ extern uint8_t ahead(void); extern uint8_t next(void); extern void expect(uint8_t tok); extern void discard(void); +extern char *filename(void); +extern unsigned short fileline(void); +extern void addinput(char *fname); #define accept(t) ((yytoken == (t)) ? next() : 0) /* code.c */ diff --git a/cc1/error.c b/cc1/error.c @@ -12,14 +12,10 @@ extern uint8_t failure; static void warn_helper(int8_t flag, char *fmt, va_list va) { - extern unsigned linenum; - extern unsigned columnum; - extern const char *filename; - if (!flag) return; fprintf(stderr, "%s:%s:%u: ", - (flag < 0) ? "error" : "warning", filename, linenum); + (flag < 0) ? "error" : "warning", filename(), fileline()); vfprintf(stderr, fmt, va); putc('\n', stderr); } diff --git a/cc1/lex.c b/cc1/lex.c @@ -10,15 +10,59 @@ #include "../inc/cc.h" #include "cc1.h" +typedef struct input Input; + +struct input { + char *fname; + unsigned short nline; + struct input *next; +}; + uint8_t lex_ns = NS_IDEN; -const char *filename; -unsigned linenum; uint8_t yytoken; struct yystype yylval; char yytext[IDENTSIZ + 1]; static uint8_t safe; +static Input *input; + +void +addinput(char *fname) +{ + Input *ip; + + ip = xmalloc(sizeof(Input)); + ip->next = input; + if (fname) { + if (!freopen(fname, "r", stdin)) + die("file '%s' not found", fname); + ip->fname = xstrdup(fname); + ip->nline = 1; + } else { + ip->fname = NULL; + ip->nline = (input) ? input->nline : 1; + } + input = ip; +} + +char * +filename(void) +{ + Input *ip; + + for (ip = input; ip; ip = ip->next) { + if (ip->fname) + return ip->fname; + } + return "(stdin)"; +} + +unsigned short +fileline(void) +{ + return input->nline; +} static uint8_t integer(char *s, char base) @@ -137,7 +181,7 @@ repeat: warn("character constant out of range"); break; case '\n': - ++linenum; + ++input->nline; if ((c = getchar()) == '\\') goto repeat; break; @@ -359,7 +403,7 @@ skipspaces(void) while (isspace(c = getchar())) { if (c == '\n') - ++linenum; + ++input->nline; } return c; } @@ -412,20 +456,6 @@ ahead(void) } void -lexfile(const char *file) -{ - - if (file == NULL) { - filename = "(stdin)"; - } else { - if (!freopen(file, "r", stdin)) - die("file '%s' not found", file); - filename = file; - } - linenum = 1; -} - -void setsafe(uint8_t type) { safe = type; diff --git a/cc1/main.c b/cc1/main.c @@ -66,7 +66,7 @@ main(int argc, char *argv[]) usage(); ikeywords(); - lexfile(*argv); + addinput(*argv); next();