aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c4
-rw-r--r--pp.c6
-rw-r--r--scan.c50
-rw-r--r--scan.h4
4 files changed, 41 insertions, 23 deletions
diff --git a/main.c b/main.c
index 89e0b18..d526bae 100644
--- a/main.c
+++ b/main.c
@@ -37,12 +37,10 @@ main(int argc, char *argv[])
if (argc > 1)
usage();
- if (argc == 1 && !freopen(argv[0], "r", stdin))
- fatal("open %s:", argv[0]);
if (output && !freopen(output, "w", stdout))
fatal("open %s:", output);
- ppinit(argc ? argv[0] : "<stdin>");
+ ppinit(argv[0]);
if (pponly) {
while (tok.kind != TEOF) {
tokprint(&tok);
diff --git a/pp.c b/pp.c
index 9772499..3cb4244 100644
--- a/pp.c
+++ b/pp.c
@@ -8,7 +8,6 @@
#include "scan.h"
#include "token.h"
-static struct scanner *scanner;
static struct token pending;
static void
@@ -85,14 +84,15 @@ keyword(struct token *tok)
void
ppinit(const char *file)
{
- scanner = mkscanner(file);
+ if (scanfrom(file) < 0)
+ fatal("open %s:", file);
next();
}
static void
nextinto(struct token *t)
{
- do scan(scanner, t);
+ do scan(t);
while (t->kind == TNEWLINE);
if (t->kind == TIDENT)
keyword(t);
diff --git a/scan.c b/scan.c
index e6b7d70..8db5136 100644
--- a/scan.c
+++ b/scan.c
@@ -16,10 +16,14 @@ struct buffer {
struct scanner {
int chr;
bool usebuf;
+ FILE *file;
struct location loc;
struct buffer buf;
+ struct scanner *next;
};
+static struct scanner *scanner;
+
static void
bufadd(struct buffer *b, char c)
{
@@ -51,16 +55,16 @@ nextchar(struct scanner *s)
if (s->usebuf)
bufadd(&s->buf, s->chr);
for (;;) {
- s->chr = getchar();
+ s->chr = getc(s->file);
if (s->chr == '\n')
++s->loc.line, s->loc.col = 1;
else
++s->loc.col;
if (s->chr != '\\')
break;
- c = getchar();
+ c = getc(s->file);
if (c != '\n') {
- ungetc(c, stdin);
+ ungetc(c, s->file);
break;
}
++s->loc.line, s->loc.col = 1;
@@ -337,7 +341,7 @@ again:
loc = s->loc;
nextchar(s);
if (s->chr != '.') {
- ungetc(s->chr, stdout);
+ ungetc(s->chr, s->file);
s->loc = loc;
s->chr = '.';
return TPERIOD;
@@ -372,32 +376,48 @@ again:
}
}
-struct scanner *
-mkscanner(const char *file)
+int
+scanfrom(const char *name)
{
struct scanner *s;
+ FILE *file;
+ if (name) {
+ file = fopen(name, "r");
+ if (!file)
+ return -1;
+ } else {
+ file = stdin;
+ name = "<stdin>";
+ }
s = xmalloc(sizeof(*s));
+ s->file = file;
s->buf.str = NULL;
s->buf.len = 0;
s->buf.cap = 0;
s->usebuf = false;
- s->loc.file = file;
+ s->loc.file = name;
s->loc.line = 1;
s->loc.col = 0;
+ s->next = scanner;
+ scanner = s;
nextchar(s);
-
- return s;
+ return 0;
}
void
-scan(struct scanner *s, struct token *t)
+scan(struct token *t)
{
- t->loc = s->loc;
- t->kind = scankind(s);
- if (s->usebuf) {
- t->lit = bufget(&s->buf);
- s->usebuf = false;
+ for (;;) {
+ t->loc = scanner->loc;
+ t->kind = scankind(scanner);
+ if (t->kind != TEOF || !scanner->next)
+ break;
+ scanner = scanner->next;
+ }
+ if (scanner->usebuf) {
+ t->lit = bufget(&scanner->buf);
+ scanner->usebuf = false;
} else {
t->lit = NULL;
}
diff --git a/scan.h b/scan.h
index eaf3c6d..ebfd513 100644
--- a/scan.h
+++ b/scan.h
@@ -1,4 +1,4 @@
struct token;
-struct scanner *mkscanner(const char *file);
-void scan(struct scanner *, struct token *);
+int scanfrom(const char *file);
+void scan(struct token *);