commit 1a41782c6970d2f794df42b7805dccd7ed8a6bbd
parent f70c013813990eded0b7ca3cf923fa3b956f454d
Author: erai <erai@omiltem.net>
Date: Sat, 16 Mar 2024 11:39:46 -0400
multiple sources
Diffstat:
M | .gitignore | | | 1 | + |
M | bootstrap.sh | | | 4 | ++-- |
M | cc0.c | | | 471 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
M | cc1.c | | | 396 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
D | cc2 | | | 0 | |
5 files changed, 542 insertions(+), 330 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,4 @@
cc0
cc1
+cc2
lex
diff --git a/bootstrap.sh b/bootstrap.sh
@@ -10,11 +10,11 @@ set -ue
${CC} ${CFLAGS} -o cc0 ./cc0.c || exit 1
# Then use the bootstrap to compile the compiler
-timeout 1 sh -c ./cc0 < cc1.c > cc1 || { echo "cc0 failed"; exit 1; }
+timeout 1 sh -c './cc0 cc1.c -o cc1' || { echo "cc0 failed"; exit 1; }
chmod +x cc1
# Then compile the compiler with itself
-timeout 1 sh -c ./cc1 < cc1.c > cc2 || { echo "cc1 failed"; exit 1; }
+timeout 1 sh -c './cc1 cc1.c -o cc2' || { echo "cc1 failed"; exit 1; }
chmod +x cc2
# And check our work
diff --git a/cc0.c b/cc0.c
@@ -1,10 +1,18 @@
+#define _POSIX_C_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
///////////////////////////////////////////////////////////////////////////////
// Forward Declarations //
///////////////////////////////////////////////////////////////////////////////
+FILE *fin;
+FILE *fout;
+
+int nc;
+unsigned char *filename;
int lineno;
struct node;
struct type;
@@ -12,6 +20,7 @@ struct label;
struct fix;
struct sdecl;
+void feed(void);
struct node *type(void);
struct node *stmt_list(void);
struct node *expr(void);
@@ -27,10 +36,64 @@ void addfixup(struct label *l);
void
die(char *msg)
{
- fprintf(stderr, "die(%d): %s\n", lineno, msg);
+ fprintf(stderr, "die(%s:%d): %s\n", filename, lineno, msg);
exit(1);
}
+void
+open_output(unsigned char *name)
+{
+ int fd;
+
+ filename = name;
+
+ if (fout != stdout) {
+ die("multiple output files");
+ }
+
+ unlink((char *)name);
+
+ fd = open((char *)name, 64 + 1, (7 << 6) + (7 << 3) + 7);
+ if (fd < 0) {
+ die("failed to open output");
+ }
+
+ fout = fdopen(fd, "wb");
+}
+
+void
+open_source(unsigned char *name)
+{
+ int fd;
+
+ if (fin != stdin) {
+ die("invalid");
+ }
+
+ filename = name;
+
+ fd = open((char *)name, 0, 0);
+ if (fd < 0) {
+ die("failed to open file");
+ }
+
+ fin = fdopen(fd, "rb");
+ lineno = 1;
+
+ nc = fgetc(fin);
+ feed();
+}
+
+void
+close_source(void)
+{
+ if (fin != stdin) {
+ fclose(fin);
+ fin = stdin;
+ }
+ fin = stdin;
+}
+
// strlen-ish
int
slen(unsigned char *s)
@@ -147,7 +210,7 @@ feed_ident(void)
}
token[tlen] = nc;
tlen = tlen + 1;
- nc = getchar();
+ nc = fgetc(fin);
}
token[tlen] = 0;
}
@@ -178,7 +241,7 @@ feed_escape(void)
{
int hex;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == 't') {
nc = '\t';
} else if (nc == 'r') {
@@ -186,10 +249,10 @@ feed_escape(void)
} else if (nc == 'n') {
nc = '\n';
} else if (nc == 'x') {
- nc = getchar();
+ nc = fgetc(fin);
hex = hexdig(nc) * 16;
- nc = getchar();
+ nc = fgetc(fin);
hex = hex + hexdig(nc);
nc = hex;
@@ -203,11 +266,11 @@ void
feed_str(void)
{
tt = T_STR;
- nc = getchar();
+ nc = fgetc(fin);
while (1) {
if (nc == '"') {
token[tlen] = 0;
- nc = getchar();
+ nc = fgetc(fin);
return;
}
@@ -229,7 +292,7 @@ feed_str(void)
token[tlen] = nc;
tlen = tlen + 1;
- nc = getchar();
+ nc = fgetc(fin);
}
}
@@ -238,7 +301,7 @@ void
feed_char(void)
{
tt = T_CHAR;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == 0 || nc == EOF || nc == '\'' || nc == '\n') {
die("invalid char");
@@ -250,14 +313,14 @@ feed_char(void)
token[tlen] = nc;
tlen = tlen + 1;
- nc = getchar();
+ nc = fgetc(fin);
if (nc != '\'') {
die("expected '");
}
token[tlen] = 0;
- nc = getchar();
+ nc = fgetc(fin);
}
// Read a hex number
@@ -278,7 +341,7 @@ feed_hex(void)
}
token[tlen] = nc;
tlen = tlen + 1;
- nc = getchar();
+ nc = fgetc(fin);
}
if (!tlen) {
@@ -297,10 +360,10 @@ feed_num(void)
if (nc == '0') {
token[tlen] = nc;
tlen = tlen + 1;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == 'x') {
- nc = getchar();
+ nc = fgetc(fin);
feed_hex();
return;
}
@@ -315,7 +378,7 @@ feed_num(void)
}
token[tlen] = nc;
tlen = tlen + 1;
- nc = getchar();
+ nc = fgetc(fin);
}
token[tlen] = 0;
}
@@ -334,21 +397,21 @@ feed(void)
return;
} else if (nc == ' ' || nc == '\t' || nc == '\r') {
// Whitespace
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '\n') {
// Line end
- nc = getchar();
+ nc = fgetc(fin);
lineno = lineno + 1;
} else if (nc == '/') {
// Comment
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '/') {
// Read until the end of the comment
while (1) {
if (nc == '\n' || nc == EOF) {
break;
}
- nc = getchar();
+ nc = fgetc(fin);
}
} else {
tt = T_DIV;
@@ -387,100 +450,100 @@ feed(void)
// Single character tokens
if (nc == '(') {
tt = T_LPAR;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == ')') {
tt = T_RPAR;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '{') {
tt = T_LBRA;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '}') {
tt = T_RBRA;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == ',') {
tt = T_COMMA;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == ';') {
tt = T_SEMI;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == ':') {
tt = T_COLON;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '*') {
tt = T_STAR;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '.') {
tt = T_DOT;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '=') {
tt = T_ASSIGN;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '=') {
tt = T_EQ;
- nc = getchar();
+ nc = fgetc(fin);
}
} else if (nc == '&') {
tt = T_AMP;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '&') {
tt = T_BAND;
- nc = getchar();
+ nc = fgetc(fin);
}
} else if (nc == '~') {
tt = T_NOT;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '|') {
tt = T_OR;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '|') {
tt = T_BOR;
- nc = getchar();
+ nc = fgetc(fin);
}
} else if (nc == '^') {
tt = T_XOR;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '!') {
tt = T_BANG;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '=') {
tt = T_NE;
- nc = getchar();
+ nc = fgetc(fin);
}
} else if (nc == '<') {
tt = T_LT;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '<') {
tt = T_LSH;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '=') {
tt = T_LE;
- nc = getchar();
+ nc = fgetc(fin);
}
} else if (nc == '>') {
tt = T_GT;
- nc = getchar();
+ nc = fgetc(fin);
if (nc == '>') {
tt = T_RSH;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '=') {
tt = T_GE;
- nc = getchar();
+ nc = fgetc(fin);
}
} else if (nc == '[') {
tt = T_LSQ;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == ']') {
tt = T_RSQ;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '+') {
tt = T_ADD;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '-') {
tt = T_SUB;
- nc = getchar();
+ nc = fgetc(fin);
} else if (nc == '%') {
tt = T_MOD;
- nc = getchar();
+ nc = fgetc(fin);
} else {
die("invalid char");
}
@@ -498,6 +561,7 @@ struct node {
int n;
unsigned char *s;
int offset;
+ unsigned char *filename;
int lineno;
};
@@ -577,6 +641,7 @@ mknode(int kind, struct node *a, struct node *b)
n->n = 0;
n->s = 0;
n->offset = 0;
+ n->filename = filename;
n->lineno = lineno;
return n;
@@ -1971,9 +2036,11 @@ program(void)
void
setup(void)
{
+ filename = (unsigned char *)"<stdin>";
+ fin = stdin;
+ fout = stdout;
lineno = 1;
- nc = getchar();
- feed();
+ nc = 0;
}
///////////////////////////////////////////////////////////////////////////////
@@ -2449,6 +2516,7 @@ declare(struct node *n)
struct type *t;
d = find(n->a->s);
t = prototype(n->b);
+ filename = n->filename;
lineno = n->lineno;
if (d->ftype) {
unify(d->ftype, t);
@@ -2891,6 +2959,7 @@ typestmt(struct node *n)
return;
}
+ filename = n->filename;
lineno = n->lineno;
kind = n->kind;
@@ -4008,194 +4077,194 @@ writeout(void)
}
// magic
- putchar(0x7f);
- putchar('E');
- putchar('L');
- putchar('F');
+ fputc(0x7f, fout);
+ fputc('E', fout);
+ fputc('L', fout);
+ fputc('F', fout);
// class
- putchar(2);
+ fputc(2, fout);
// endian
- putchar(1);
+ fputc(1, fout);
// version
- putchar(1);
+ fputc(1, fout);
// abi
- putchar(0);
+ fputc(0, fout);
// abi version
- putchar(0);
+ fputc(0, fout);
// padding
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// type
- putchar(2);
- putchar(0);
+ fputc(2, fout);
+ fputc(0, fout);
// machine
- putchar(62);
- putchar(0);
+ fputc(62, fout);
+ fputc(0, fout);
// version
- putchar(1);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(1, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
entry = load_addr + d->label->at + 128;
// entry point
- putchar(entry);
- putchar(entry >> 8);
- putchar(entry >> 16);
- putchar(entry >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(entry, fout);
+ fputc(entry >> 8, fout);
+ fputc(entry >> 16, fout);
+ fputc(entry >> 24, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phoff
- putchar(64);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(64, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// shoff
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// flags
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// ehsize
- putchar(64);
- putchar(0);
+ fputc(64, fout);
+ fputc(0, fout);
// phentsize
- putchar(56);
- putchar(0);
+ fputc(56, fout);
+ fputc(0, fout);
// phnum
- putchar(1);
- putchar(0);
+ fputc(1, fout);
+ fputc(0, fout);
// shentsize
- putchar(64);
- putchar(0);
+ fputc(64, fout);
+ fputc(0, fout);
// shnum
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
// shstrndx
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].type
- putchar(1);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(1, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].flags
- putchar(5);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(5, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].offset
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].vaddr
- putchar(load_addr);
- putchar(load_addr >> 8);
- putchar(load_addr >> 16);
- putchar(load_addr >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(load_addr, fout);
+ fputc(load_addr >> 8, fout);
+ fputc(load_addr >> 16, fout);
+ fputc(load_addr >> 24, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].paddr
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
at = at + 128;
// phdr[0].filesize
- putchar(at);
- putchar(at >> 8);
- putchar(at >> 16);
- putchar(at >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(at, fout);
+ fputc(at >> 8, fout);
+ fputc(at >> 16, fout);
+ fputc(at >> 24, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].memsize
- putchar(at);
- putchar(at >> 8);
- putchar(at >> 16);
- putchar(at >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(at, fout);
+ fputc(at >> 8, fout);
+ fputc(at >> 16, fout);
+ fputc(at >> 24, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// phdr[0].align
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
+ fputc(0, fout);
// nop sled
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
+ fputc(0x90, fout);
// text
b = text;
@@ -4208,7 +4277,7 @@ writeout(void)
if (i >= b->fill) {
break;
}
- putchar(b->buf[i]);
+ fputc(b->buf[i], fout);
i = i + 1;
}
b = b->next;
@@ -4721,18 +4790,48 @@ int
main(int argc, char **argv)
{
struct node *p;
+ int i;
// Setup the compiler
setup();
- // Parse the program
- p = program();
+ i = 1;
+ while (1) {
+ if (i >= argc) {
+ break;
+ }
+
+ if (!cmp((unsigned char *)argv[i], (unsigned char *)"-o")) {
+ i = i + 1;
+ if (i >= argc) {
+ die("invalid -o at end of argument list");
+ }
- // Verify types
- typecheck(p);
+ open_output((unsigned char *)argv[i]);
- // Generate code
- translate(p);
+ i = i + 1;
+ continue;
+ }
+
+ open_source((unsigned char *)argv[i]);
+
+ // Parse the program
+ p = program();
+
+ // Verify types
+ typecheck(p);
+
+ // Generate code
+ translate(p);
+
+ close_source();
+
+ i = i + 1;
+ }
+
+ if (fout == stdout) {
+ open_output((unsigned char *)"a.out");
+ }
// Define _start, syscall
add_stdlib();
diff --git a/cc1.c b/cc1.c
@@ -10,6 +10,7 @@ struct node {
kind: int;
a: *node;
b: *node;
+ filename: *byte;
lineno: int;
colno: int;
n: int;
@@ -83,7 +84,9 @@ struct compiler {
page: *page;
// Lexer
+ fdin: int;
nc: int;
+ filename: *byte;
lineno: int;
colno: int;
tt: int;
@@ -92,6 +95,7 @@ struct compiler {
tmax: int;
// Assembler
+ fdout: int;
at: int;
text: *chunk;
text_end: *chunk;
@@ -227,6 +231,30 @@ write(fd: int, buf: *byte, n: int): int {
return syscall(1, fd, buf: int, n, 0, 0, 0);
}
+open(name: *byte, flags: int, mode: int): int {
+ return syscall(2, name: int, flags, mode, 0, 0, 0);
+}
+
+lseek(fd: int, offset: int, whence: int): int {
+ return syscall(8, fd, offset, whence, 0, 0, 0);
+}
+
+close(fd: int): int {
+ return syscall(3, fd, 0, 0, 0, 0, 0);
+}
+
+fchmod(fd: int, mode: int): int {
+ return syscall(91, fd, mode, 0, 0, 0, 0);
+}
+
+rename(oldname: *byte, newname: *byte): int {
+ return syscall(82, oldname: int, newname: int, 0, 0, 0, 0);
+}
+
+unlink(name: *byte): int {
+ return syscall(87, name: int, 0, 0, 0, 0, 0);
+}
+
mmap(addr: int, len: int, prot: int, flags: int, fd: int, off: int): int {
return syscall(9, addr, len, prot, flags, fd, off);
}
@@ -280,10 +308,10 @@ alloc(c: *compiler, size: int): *byte {
return ret;
}
-getchar(): int {
+getchar(c: *compiler): int {
var b: byte;
var ret: int;
- ret = read(0, &b, 1);
+ ret = read(c.fdin, &b, 1);
if (ret < 0) {
exit(3);
}
@@ -293,11 +321,11 @@ getchar(): int {
return b: int;
}
-putchar(ch: int) {
+putchar(c: *compiler, ch: int) {
var b: byte;
var ret: int;
b = ch: byte;
- ret = write(1, &b, 1);
+ ret = write(c.fdout, &b, 1);
if (ret != 1) {
exit(3);
}
@@ -416,7 +444,11 @@ fdputd(fd: int, n: int) {
}
show_context(c: *compiler) {
- fdput(2, "on -:");
+ fdput(2, "on ");
+ if (c.filename) {
+ fdput(2, c.filename);
+ }
+ fdput(2, ":");
fdputd(2, c.lineno);
fdput(2, ":");
fdputd(2, c.colno);
@@ -431,10 +463,59 @@ die(c: *compiler, msg: *byte) {
exit(1);
}
+open_output(c: *compiler, filename: *byte) {
+ var fd: int;
+
+ c.filename = filename;
+
+ if (c.fdout != 1) {
+ die(c, "multiple output files");
+ }
+
+ unlink(filename);
+
+ fd = open(filename, 64 + 1, (7 << 6) + (7 << 3) + 7);
+ if (fd < 0) {
+ die(c, "failed to open output");
+ }
+
+ c.fdout = fd;
+}
+
+open_source(c: *compiler, filename: *byte) {
+ var fd: int;
+
+ c.filename = filename;
+ c.nc = 0;
+ c.lineno = 1;
+ c.colno = 1;
+ c.tlen = 0;
+ c.tt = 0;
+
+ fd = open(filename, 0, 0);
+ if (fd < 0) {
+ die(c, "failed to open file");
+ }
+
+ c.fdin = fd;
+ c.nc = getchar(c);
+
+ feed(c);
+}
+
+close_source(c: *compiler) {
+ if (c.fdin != 0) {
+ close(c.fdin);
+ }
+ c.fdin = 0;
+}
+
comp_setup(c: *compiler) {
c.page = 0:*page;
- c.nc = getchar();
+ c.fdin = 0;
+ c.nc = 0;
+ c.filename = 0:*byte;
c.lineno = 1;
c.colno = 1;
c.tlen = 0;
@@ -442,17 +523,16 @@ comp_setup(c: *compiler) {
c.token = alloc(c, c.tmax);
c.tt = 0;
+ c.fdout = 1;
c.at = 0;
c.text = 0:*chunk;
c.text_end = 0:*chunk;
c.decls = 0:*decl;
-
- feed(c);
}
feedc(c: *compiler) {
- c.nc = getchar();
+ c.nc = getchar(c);
if (c.nc == '\n') {
c.lineno = c.lineno + 1;
c.colno = 0;
@@ -676,10 +756,10 @@ feed_escape(c: *compiler) {
} else if (c.nc == 'n') {
c.nc = '\n';
} else if (c.nc == 'x') {
- c.nc = getchar();
+ c.nc = getchar(c);
hex = hexdig(c) * 16;
- c.nc = getchar();
+ c.nc = getchar(c);
hex = hex + hexdig(c);
c.nc = hex;
@@ -785,6 +865,7 @@ mknode(c: *compiler, kind: int, a: *node, b: *node): *node {
ret.kind = kind;
ret.a = a;
ret.b = b;
+ ret.filename = c.filename;
ret.lineno = c.lineno;
ret.colno = c.colno;
ret.n = 0;
@@ -2568,6 +2649,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
var v: *decl;
var kind: int;
+ c.filename = n.filename;
c.lineno = n.lineno;
c.colno = 0;
@@ -3181,6 +3263,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
return;
}
+ c.filename = n.filename;
c.lineno = n.lineno;
c.colno = 0;
@@ -4218,190 +4301,190 @@ writeout(c: *compiler) {
text_size = text_size + 128;
// magic
- putchar(0x7f);
- putchar('E');
- putchar('L');
- putchar('F');
+ putchar(c, 0x7f);
+ putchar(c, 'E');
+ putchar(c, 'L');
+ putchar(c, 'F');
// class
- putchar(2);
+ putchar(c, 2);
// endian
- putchar(1);
+ putchar(c, 1);
// version
- putchar(1);
+ putchar(c, 1);
// abi
- putchar(0);
+ putchar(c, 0);
// abi version
- putchar(0);
+ putchar(c, 0);
// padding
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// type
- putchar(2);
- putchar(0);
+ putchar(c, 2);
+ putchar(c, 0);
// machine
- putchar(62);
- putchar(0);
+ putchar(c, 62);
+ putchar(c, 0);
// version
- putchar(1);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 1);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// entry point
- putchar(entry);
- putchar(entry >> 8);
- putchar(entry >> 16);
- putchar(entry >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, entry);
+ putchar(c, entry >> 8);
+ putchar(c, entry >> 16);
+ putchar(c, entry >> 24);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phoff
- putchar(64);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 64);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// shoff
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// flags
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// ehsize
- putchar(64);
- putchar(0);
+ putchar(c, 64);
+ putchar(c, 0);
// phentsize
- putchar(56);
- putchar(0);
+ putchar(c, 56);
+ putchar(c, 0);
// phnum
- putchar(1);
- putchar(0);
+ putchar(c, 1);
+ putchar(c, 0);
// shentsize
- putchar(64);
- putchar(0);
+ putchar(c, 64);
+ putchar(c, 0);
// shnum
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
// shstrndx
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].type
- putchar(1);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 1);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].flags
- putchar(5);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 5);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].offset
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].vaddr
- putchar(0);
- putchar(0);
- putchar(0x10);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0x10);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].paddr
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].filesize
- putchar(text_size);
- putchar(text_size >> 8);
- putchar(text_size >> 16);
- putchar(text_size >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, text_size);
+ putchar(c, text_size >> 8);
+ putchar(c, text_size >> 16);
+ putchar(c, text_size >> 24);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].memsize
- putchar(text_size);
- putchar(text_size >> 8);
- putchar(text_size >> 16);
- putchar(text_size >> 24);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, text_size);
+ putchar(c, text_size >> 8);
+ putchar(c, text_size >> 16);
+ putchar(c, text_size >> 24);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// phdr[0].align
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
- putchar(0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
+ putchar(c, 0);
// nop sled
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
- putchar(0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
+ putchar(c, 0x90);
b = c.text;
loop {
@@ -4413,7 +4496,7 @@ writeout(c: *compiler) {
if (i >= b.fill) {
break;
}
- putchar(b.buf[i]: int);
+ putchar(c, b.buf[i]: int);
i = i + 1;
}
b = b.next;
@@ -4423,9 +4506,38 @@ writeout(c: *compiler) {
main(argc: int, argv: **byte, envp: **byte) {
var c: compiler;
var p: *node;
+ var i: int;
+
comp_setup(&c);
- p = parse_program(&c);
- compile(&c, p);
+
+ i = 1;
+ loop {
+ if (i >= argc) {
+ break;
+ }
+
+ if (!strcmp(argv[i], "-o")) {
+ i = i + 1;
+ if (i >= argc) {
+ die(&c, "invalid -o at end of argument list");
+ }
+ open_output(&c, argv[i]);
+ i = i + 1;
+ continue;
+ }
+
+ open_source(&c, argv[i]);
+ p = parse_program(&c);
+ close_source(&c);
+ compile(&c, p);
+
+ i = i + 1;
+ }
+
+ if (c.fdout == 1) {
+ open_output(&c, "a.out");
+ }
+
gen_builtins(&c);
writeout(&c);
}
diff --git a/cc2 b/cc2
Binary files differ.