Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e14315ee0 |
1 changed files with 136 additions and 135 deletions
271
c4.c
271
c4.c
|
|
@ -1,6 +1,6 @@
|
|||
// c4.c - C in four functions
|
||||
|
||||
// char, int, and pointer types
|
||||
// char, int, long, and pointer types
|
||||
// if, while, return, and expression statements
|
||||
// just enough features to allow self-compilation and a bit more
|
||||
|
||||
|
|
@ -15,21 +15,21 @@
|
|||
char *p, *lp, // current position in source code
|
||||
*data; // data/bss pointer
|
||||
|
||||
int *e, *le, // current position in emitted code
|
||||
*id, // currently parsed identifier
|
||||
*sym, // symbol table (simple list of identifiers)
|
||||
tk, // current token
|
||||
ival, // current token value
|
||||
ty, // current expression type
|
||||
loc, // local variable offset
|
||||
line, // current line number
|
||||
src, // print source and assembly flag
|
||||
debug; // print executed instructions
|
||||
long *e, *le, // current position in emitted code
|
||||
*id, // currently parsed identifier
|
||||
*sym, // symbol table (simple list of identifiers)
|
||||
tk, // current token
|
||||
ival, // current token value
|
||||
ty, // current expression type
|
||||
loc, // local variable offset
|
||||
line, // current line number
|
||||
src, // print source and assembly flag
|
||||
debug; // print executed instructions
|
||||
|
||||
// tokens and classes (operators last and in precedence order)
|
||||
enum {
|
||||
Num = 128, Fun, Sys, Glo, Loc, Id,
|
||||
Char, Else, Enum, If, Int, Return, Sizeof, While,
|
||||
Char, Else, Enum, If, Long, Return, Sizeof, While,
|
||||
Assign, Cond, Lor, Lan, Or, Xor, And, Eq, Ne, Lt, Gt, Le, Ge, Shl, Shr, Add, Sub, Mul, Div, Mod, Inc, Dec, Brak
|
||||
};
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ enum { LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,
|
|||
OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT };
|
||||
|
||||
// types
|
||||
enum { CHAR, INT, PTR };
|
||||
enum { CHAR, LONG, PTR };
|
||||
|
||||
// identifier offsets (since we can't create an ident struct)
|
||||
enum { Tk, Hash, Name, Class, Type, Val, HClass, HType, HVal, Idsz };
|
||||
|
|
@ -52,13 +52,13 @@ void next()
|
|||
++p;
|
||||
if (tk == '\n') {
|
||||
if (src) {
|
||||
printf("%d: %.*s", line, p - lp, lp);
|
||||
printf("%ld: %.*s", line, p - lp, lp);
|
||||
lp = p;
|
||||
while (le < e) {
|
||||
printf("%8.4s", &"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,"
|
||||
"OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,"
|
||||
"OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT,"[*++le * 5]);
|
||||
if (*le <= ADJ) printf(" %d\n", *++le); else printf("\n");
|
||||
if (*le <= ADJ) printf(" %ld\n", *++le); else printf("\n");
|
||||
}
|
||||
}
|
||||
++line;
|
||||
|
|
@ -76,7 +76,7 @@ void next()
|
|||
if (tk == id[Hash] && !memcmp((char *)id[Name], pp, p - pp)) { tk = id[Tk]; return; }
|
||||
id = id + Idsz;
|
||||
}
|
||||
id[Name] = (int)pp;
|
||||
id[Name] = (long)pp;
|
||||
id[Hash] = tk;
|
||||
tk = id[Tk] = Id;
|
||||
return;
|
||||
|
|
@ -110,7 +110,7 @@ void next()
|
|||
if (tk == '"') *data++ = ival;
|
||||
}
|
||||
++p;
|
||||
if (tk == '"') ival = (int)pp; else tk = Num;
|
||||
if (tk == '"') ival = (long)pp; else tk = Num;
|
||||
return;
|
||||
}
|
||||
else if (tk == '=') { if (*p == '=') { ++p; tk = Eq; } else tk = Assign; return; }
|
||||
|
|
@ -130,24 +130,24 @@ void next()
|
|||
}
|
||||
}
|
||||
|
||||
void expr(int lev)
|
||||
void expr(long lev)
|
||||
{
|
||||
int t, *d;
|
||||
long t, *d;
|
||||
|
||||
if (!tk) { printf("%d: unexpected eof in expression\n", line); exit(-1); }
|
||||
else if (tk == Num) { *++e = IMM; *++e = ival; next(); ty = INT; }
|
||||
if (!tk) { printf("%ld: unexpected eof in expression\n", line); exit(-1); }
|
||||
else if (tk == Num) { *++e = IMM; *++e = ival; next(); ty = LONG; }
|
||||
else if (tk == '"') {
|
||||
*++e = IMM; *++e = ival; next();
|
||||
while (tk == '"') next();
|
||||
data = (char *)((int)data + sizeof(int) & -sizeof(int)); ty = PTR;
|
||||
data = (char *)((long)data + sizeof(long) & -sizeof(long)); ty = PTR;
|
||||
}
|
||||
else if (tk == Sizeof) {
|
||||
next(); if (tk == '(') next(); else { printf("%d: open paren expected in sizeof\n", line); exit(-1); }
|
||||
ty = INT; if (tk == Int) next(); else if (tk == Char) { next(); ty = CHAR; }
|
||||
next(); if (tk == '(') next(); else { printf("%ld: open paren expected in sizeof\n", line); exit(-1); }
|
||||
ty = LONG; if (tk == Long) next(); else if (tk == Char) { next(); ty = CHAR; }
|
||||
while (tk == Mul) { next(); ty = ty + PTR; }
|
||||
if (tk == ')') next(); else { printf("%d: close paren expected in sizeof\n", line); exit(-1); }
|
||||
*++e = IMM; *++e = (ty == CHAR) ? sizeof(char) : sizeof(int);
|
||||
ty = INT;
|
||||
if (tk == ')') next(); else { printf("%ld: close paren expected in sizeof\n", line); exit(-1); }
|
||||
*++e = IMM; *++e = (ty == CHAR) ? sizeof(char) : sizeof(long);
|
||||
ty = LONG;
|
||||
}
|
||||
else if (tk == Id) {
|
||||
d = id; next();
|
||||
|
|
@ -158,162 +158,162 @@ void expr(int lev)
|
|||
next();
|
||||
if (d[Class] == Sys) *++e = d[Val];
|
||||
else if (d[Class] == Fun) { *++e = JSR; *++e = d[Val]; }
|
||||
else { printf("%d: bad function call\n", line); exit(-1); }
|
||||
else { printf("%ld: bad function call\n", line); exit(-1); }
|
||||
if (t) { *++e = ADJ; *++e = t; }
|
||||
ty = d[Type];
|
||||
}
|
||||
else if (d[Class] == Num) { *++e = IMM; *++e = d[Val]; ty = INT; }
|
||||
else if (d[Class] == Num) { *++e = IMM; *++e = d[Val]; ty = LONG; }
|
||||
else {
|
||||
if (d[Class] == Loc) { *++e = LEA; *++e = loc - d[Val]; }
|
||||
else if (d[Class] == Glo) { *++e = IMM; *++e = d[Val]; }
|
||||
else { printf("%d: undefined variable\n", line); exit(-1); }
|
||||
else { printf("%ld: undefined variable\n", line); exit(-1); }
|
||||
*++e = ((ty = d[Type]) == CHAR) ? LC : LI;
|
||||
}
|
||||
}
|
||||
else if (tk == '(') {
|
||||
next();
|
||||
if (tk == Int || tk == Char) {
|
||||
t = (tk == Int) ? INT : CHAR; next();
|
||||
if (tk == Long || tk == Char) {
|
||||
t = (tk == Long) ? LONG : CHAR; next();
|
||||
while (tk == Mul) { next(); t = t + PTR; }
|
||||
if (tk == ')') next(); else { printf("%d: bad cast\n", line); exit(-1); }
|
||||
if (tk == ')') next(); else { printf("%ld: bad cast\n", line); exit(-1); }
|
||||
expr(Inc);
|
||||
ty = t;
|
||||
}
|
||||
else {
|
||||
expr(Assign);
|
||||
if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
|
||||
if (tk == ')') next(); else { printf("%ld: close paren expected\n", line); exit(-1); }
|
||||
}
|
||||
}
|
||||
else if (tk == Mul) {
|
||||
next(); expr(Inc);
|
||||
if (ty > INT) ty = ty - PTR; else { printf("%d: bad dereference\n", line); exit(-1); }
|
||||
if (ty > LONG) ty = ty - PTR; else { printf("%ld: bad dereference\n", line); exit(-1); }
|
||||
*++e = (ty == CHAR) ? LC : LI;
|
||||
}
|
||||
else if (tk == And) {
|
||||
next(); expr(Inc);
|
||||
if (*e == LC || *e == LI) --e; else { printf("%d: bad address-of\n", line); exit(-1); }
|
||||
if (*e == LC || *e == LI) --e; else { printf("%ld: bad address-of\n", line); exit(-1); }
|
||||
ty = ty + PTR;
|
||||
}
|
||||
else if (tk == '!') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = 0; *++e = EQ; ty = INT; }
|
||||
else if (tk == '~') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = -1; *++e = XOR; ty = INT; }
|
||||
else if (tk == Add) { next(); expr(Inc); ty = INT; }
|
||||
else if (tk == '!') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = 0; *++e = EQ; ty = LONG; }
|
||||
else if (tk == '~') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = -1; *++e = XOR; ty = LONG; }
|
||||
else if (tk == Add) { next(); expr(Inc); ty = LONG; }
|
||||
else if (tk == Sub) {
|
||||
next(); *++e = IMM;
|
||||
if (tk == Num) { *++e = -ival; next(); } else { *++e = -1; *++e = PSH; expr(Inc); *++e = MUL; }
|
||||
ty = INT;
|
||||
ty = LONG;
|
||||
}
|
||||
else if (tk == Inc || tk == Dec) {
|
||||
t = tk; next(); expr(Inc);
|
||||
if (*e == LC) { *e = PSH; *++e = LC; }
|
||||
else if (*e == LI) { *e = PSH; *++e = LI; }
|
||||
else { printf("%d: bad lvalue in pre-increment\n", line); exit(-1); }
|
||||
else { printf("%ld: bad lvalue in pre-increment\n", line); exit(-1); }
|
||||
*++e = PSH;
|
||||
*++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);
|
||||
*++e = IMM; *++e = (ty > PTR) ? sizeof(long) : sizeof(char);
|
||||
*++e = (t == Inc) ? ADD : SUB;
|
||||
*++e = (ty == CHAR) ? SC : SI;
|
||||
}
|
||||
else { printf("%d: bad expression\n", line); exit(-1); }
|
||||
else { printf("%ld: bad expression\n", line); exit(-1); }
|
||||
|
||||
while (tk >= lev) { // "precedence climbing" or "Top Down Operator Precedence" method
|
||||
t = ty;
|
||||
if (tk == Assign) {
|
||||
next();
|
||||
if (*e == LC || *e == LI) *e = PSH; else { printf("%d: bad lvalue in assignment\n", line); exit(-1); }
|
||||
if (*e == LC || *e == LI) *e = PSH; else { printf("%ld: bad lvalue in assignment\n", line); exit(-1); }
|
||||
expr(Assign); *++e = ((ty = t) == CHAR) ? SC : SI;
|
||||
}
|
||||
else if (tk == Cond) {
|
||||
next();
|
||||
*++e = BZ; d = ++e;
|
||||
expr(Assign);
|
||||
if (tk == ':') next(); else { printf("%d: conditional missing colon\n", line); exit(-1); }
|
||||
*d = (int)(e + 3); *++e = JMP; d = ++e;
|
||||
if (tk == ':') next(); else { printf("%ld: conditional missing colon\n", line); exit(-1); }
|
||||
*d = (long)(e + 3); *++e = JMP; d = ++e;
|
||||
expr(Cond);
|
||||
*d = (int)(e + 1);
|
||||
*d = (long)(e + 1);
|
||||
}
|
||||
else if (tk == Lor) { next(); *++e = BNZ; d = ++e; expr(Lan); *d = (int)(e + 1); ty = INT; }
|
||||
else if (tk == Lan) { next(); *++e = BZ; d = ++e; expr(Or); *d = (int)(e + 1); ty = INT; }
|
||||
else if (tk == Or) { next(); *++e = PSH; expr(Xor); *++e = OR; ty = INT; }
|
||||
else if (tk == Xor) { next(); *++e = PSH; expr(And); *++e = XOR; ty = INT; }
|
||||
else if (tk == And) { next(); *++e = PSH; expr(Eq); *++e = AND; ty = INT; }
|
||||
else if (tk == Eq) { next(); *++e = PSH; expr(Lt); *++e = EQ; ty = INT; }
|
||||
else if (tk == Ne) { next(); *++e = PSH; expr(Lt); *++e = NE; ty = INT; }
|
||||
else if (tk == Lt) { next(); *++e = PSH; expr(Shl); *++e = LT; ty = INT; }
|
||||
else if (tk == Gt) { next(); *++e = PSH; expr(Shl); *++e = GT; ty = INT; }
|
||||
else if (tk == Le) { next(); *++e = PSH; expr(Shl); *++e = LE; ty = INT; }
|
||||
else if (tk == Ge) { next(); *++e = PSH; expr(Shl); *++e = GE; ty = INT; }
|
||||
else if (tk == Shl) { next(); *++e = PSH; expr(Add); *++e = SHL; ty = INT; }
|
||||
else if (tk == Shr) { next(); *++e = PSH; expr(Add); *++e = SHR; ty = INT; }
|
||||
else if (tk == Lor) { next(); *++e = BNZ; d = ++e; expr(Lan); *d = (long)(e + 1); ty = LONG; }
|
||||
else if (tk == Lan) { next(); *++e = BZ; d = ++e; expr(Or); *d = (long)(e + 1); ty = LONG; }
|
||||
else if (tk == Or) { next(); *++e = PSH; expr(Xor); *++e = OR; ty = LONG; }
|
||||
else if (tk == Xor) { next(); *++e = PSH; expr(And); *++e = XOR; ty = LONG; }
|
||||
else if (tk == And) { next(); *++e = PSH; expr(Eq); *++e = AND; ty = LONG; }
|
||||
else if (tk == Eq) { next(); *++e = PSH; expr(Lt); *++e = EQ; ty = LONG; }
|
||||
else if (tk == Ne) { next(); *++e = PSH; expr(Lt); *++e = NE; ty = LONG; }
|
||||
else if (tk == Lt) { next(); *++e = PSH; expr(Shl); *++e = LT; ty = LONG; }
|
||||
else if (tk == Gt) { next(); *++e = PSH; expr(Shl); *++e = GT; ty = LONG; }
|
||||
else if (tk == Le) { next(); *++e = PSH; expr(Shl); *++e = LE; ty = LONG; }
|
||||
else if (tk == Ge) { next(); *++e = PSH; expr(Shl); *++e = GE; ty = LONG; }
|
||||
else if (tk == Shl) { next(); *++e = PSH; expr(Add); *++e = SHL; ty = LONG; }
|
||||
else if (tk == Shr) { next(); *++e = PSH; expr(Add); *++e = SHR; ty = LONG; }
|
||||
else if (tk == Add) {
|
||||
next(); *++e = PSH; expr(Mul);
|
||||
if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; }
|
||||
if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(long); *++e = MUL; }
|
||||
*++e = ADD;
|
||||
}
|
||||
else if (tk == Sub) {
|
||||
next(); *++e = PSH; expr(Mul);
|
||||
if (t > PTR && t == ty) { *++e = SUB; *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = DIV; ty = INT; }
|
||||
else if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; *++e = SUB; }
|
||||
if (t > PTR && t == ty) { *++e = SUB; *++e = PSH; *++e = IMM; *++e = sizeof(long); *++e = DIV; ty = LONG; }
|
||||
else if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(long); *++e = MUL; *++e = SUB; }
|
||||
else *++e = SUB;
|
||||
}
|
||||
else if (tk == Mul) { next(); *++e = PSH; expr(Inc); *++e = MUL; ty = INT; }
|
||||
else if (tk == Div) { next(); *++e = PSH; expr(Inc); *++e = DIV; ty = INT; }
|
||||
else if (tk == Mod) { next(); *++e = PSH; expr(Inc); *++e = MOD; ty = INT; }
|
||||
else if (tk == Mul) { next(); *++e = PSH; expr(Inc); *++e = MUL; ty = LONG; }
|
||||
else if (tk == Div) { next(); *++e = PSH; expr(Inc); *++e = DIV; ty = LONG; }
|
||||
else if (tk == Mod) { next(); *++e = PSH; expr(Inc); *++e = MOD; ty = LONG; }
|
||||
else if (tk == Inc || tk == Dec) {
|
||||
if (*e == LC) { *e = PSH; *++e = LC; }
|
||||
else if (*e == LI) { *e = PSH; *++e = LI; }
|
||||
else { printf("%d: bad lvalue in post-increment\n", line); exit(-1); }
|
||||
*++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);
|
||||
else { printf("%ld: bad lvalue in post-increment\n", line); exit(-1); }
|
||||
*++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(long) : sizeof(char);
|
||||
*++e = (tk == Inc) ? ADD : SUB;
|
||||
*++e = (ty == CHAR) ? SC : SI;
|
||||
*++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);
|
||||
*++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(long) : sizeof(char);
|
||||
*++e = (tk == Inc) ? SUB : ADD;
|
||||
next();
|
||||
}
|
||||
else if (tk == Brak) {
|
||||
next(); *++e = PSH; expr(Assign);
|
||||
if (tk == ']') next(); else { printf("%d: close bracket expected\n", line); exit(-1); }
|
||||
if (t > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; }
|
||||
else if (t < PTR) { printf("%d: pointer type expected\n", line); exit(-1); }
|
||||
if (tk == ']') next(); else { printf("%ld: close bracket expected\n", line); exit(-1); }
|
||||
if (t > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(long); *++e = MUL; }
|
||||
else if (t < PTR) { printf("%ld: pointer type expected\n", line); exit(-1); }
|
||||
*++e = ADD;
|
||||
*++e = ((ty = t - PTR) == CHAR) ? LC : LI;
|
||||
}
|
||||
else { printf("%d: compiler error tk=%d\n", line, tk); exit(-1); }
|
||||
else { printf("%ld: compiler error tk=%ld\n", line, tk); exit(-1); }
|
||||
}
|
||||
}
|
||||
|
||||
void stmt()
|
||||
{
|
||||
int *a, *b;
|
||||
long *a, *b;
|
||||
|
||||
if (tk == If) {
|
||||
next();
|
||||
if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
|
||||
if (tk == '(') next(); else { printf("%ld: open paren expected\n", line); exit(-1); }
|
||||
expr(Assign);
|
||||
if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
|
||||
if (tk == ')') next(); else { printf("%ld: close paren expected\n", line); exit(-1); }
|
||||
*++e = BZ; b = ++e;
|
||||
stmt();
|
||||
if (tk == Else) {
|
||||
*b = (int)(e + 3); *++e = JMP; b = ++e;
|
||||
*b = (long)(e + 3); *++e = JMP; b = ++e;
|
||||
next();
|
||||
stmt();
|
||||
}
|
||||
*b = (int)(e + 1);
|
||||
*b = (long)(e + 1);
|
||||
}
|
||||
else if (tk == While) {
|
||||
next();
|
||||
a = e + 1;
|
||||
if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
|
||||
if (tk == '(') next(); else { printf("%ld: open paren expected\n", line); exit(-1); }
|
||||
expr(Assign);
|
||||
if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
|
||||
if (tk == ')') next(); else { printf("%ld: close paren expected\n", line); exit(-1); }
|
||||
*++e = BZ; b = ++e;
|
||||
stmt();
|
||||
*++e = JMP; *++e = (int)a;
|
||||
*b = (int)(e + 1);
|
||||
*++e = JMP; *++e = (long)a;
|
||||
*b = (long)(e + 1);
|
||||
}
|
||||
else if (tk == Return) {
|
||||
next();
|
||||
if (tk != ';') expr(Assign);
|
||||
*++e = LEV;
|
||||
if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
|
||||
if (tk == ';') next(); else { printf("%ld: semicolon expected\n", line); exit(-1); }
|
||||
}
|
||||
else if (tk == '{') {
|
||||
next();
|
||||
|
|
@ -325,15 +325,15 @@ void stmt()
|
|||
}
|
||||
else {
|
||||
expr(Assign);
|
||||
if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
|
||||
if (tk == ';') next(); else { printf("%ld: semicolon expected\n", line); exit(-1); }
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(long argc, char **argv)
|
||||
{
|
||||
int fd, bt, ty, poolsz, *idmain;
|
||||
int *pc, *sp, *bp, a, cycle; // vm registers
|
||||
int i, *t; // temps
|
||||
long fd, bt, ty, poolsz, *idmain;
|
||||
long *pc, *sp, *bp, a, cycle; // vm registers
|
||||
long i, *t; // temps
|
||||
|
||||
--argc; ++argv;
|
||||
if (argc > 0 && **argv == '-' && (*argv)[1] == 's') { src = 1; --argc; ++argv; }
|
||||
|
|
@ -343,24 +343,25 @@ int main(int argc, char **argv)
|
|||
if ((fd = open(*argv, 0)) < 0) { printf("could not open(%s)\n", *argv); return -1; }
|
||||
|
||||
poolsz = 256*1024; // arbitrary size
|
||||
if (!(sym = malloc(poolsz))) { printf("could not malloc(%d) symbol area\n", poolsz); return -1; }
|
||||
if (!(le = e = malloc(poolsz))) { printf("could not malloc(%d) text area\n", poolsz); return -1; }
|
||||
if (!(data = malloc(poolsz))) { printf("could not malloc(%d) data area\n", poolsz); return -1; }
|
||||
if (!(sp = malloc(poolsz))) { printf("could not malloc(%d) stack area\n", poolsz); return -1; }
|
||||
if (!(sym = malloc(poolsz))) { printf("could not malloc(%ld) symbol area\n", poolsz); return -1; }
|
||||
if (!(le = e = malloc(poolsz))) { printf("could not malloc(%ld) text area\n", poolsz); return -1; }
|
||||
if (!(data = malloc(poolsz))) { printf("could not malloc(%ld) data area\n", poolsz); return -1; }
|
||||
if (!(sp = malloc(poolsz))) { printf("could not malloc(%ld) stack area\n", poolsz); return -1; }
|
||||
|
||||
memset(sym, 0, poolsz);
|
||||
memset(e, 0, poolsz);
|
||||
memset(data, 0, poolsz);
|
||||
|
||||
p = "char else enum if int return sizeof while "
|
||||
"open read close printf malloc free memset memcmp exit void main";
|
||||
p = "char else enum if long return sizeof while "
|
||||
"open read close printf malloc free memset memcmp exit void main int";
|
||||
i = Char; while (i <= While) { next(); id[Tk] = i++; } // add keywords to symbol table
|
||||
i = OPEN; while (i <= EXIT) { next(); id[Class] = Sys; id[Type] = INT; id[Val] = i++; } // add library to symbol table
|
||||
i = OPEN; while (i <= EXIT) { next(); id[Class] = Sys; id[Type] = LONG; id[Val] = i++; } // add library to symbol table
|
||||
next(); id[Tk] = Char; // handle void type
|
||||
next(); idmain = id; // keep track of main
|
||||
next(); id[Tk] = Long; // handle int type
|
||||
|
||||
if (!(lp = p = malloc(poolsz))) { printf("could not malloc(%d) source area\n", poolsz); return -1; }
|
||||
if ((i = read(fd, p, poolsz-1)) <= 0) { printf("read() returned %d\n", i); return -1; }
|
||||
if (!(lp = p = malloc(poolsz))) { printf("could not malloc(%ld) source area\n", poolsz); return -1; }
|
||||
if ((i = read(fd, p, poolsz-1)) <= 0) { printf("read() returned %ld\n", i); return -1; }
|
||||
p[i] = 0;
|
||||
close(fd);
|
||||
|
||||
|
|
@ -368,8 +369,8 @@ int main(int argc, char **argv)
|
|||
line = 1;
|
||||
next();
|
||||
while (tk) {
|
||||
bt = INT; // basetype
|
||||
if (tk == Int) next();
|
||||
bt = LONG; // basetype
|
||||
if (tk == Long) next();
|
||||
else if (tk == Char) { next(); bt = CHAR; }
|
||||
else if (tk == Enum) {
|
||||
next();
|
||||
|
|
@ -378,15 +379,15 @@ int main(int argc, char **argv)
|
|||
next();
|
||||
i = 0;
|
||||
while (tk != '}') {
|
||||
if (tk != Id) { printf("%d: bad enum identifier %d\n", line, tk); return -1; }
|
||||
if (tk != Id) { printf("%ld: bad enum identifier %ld\n", line, tk); return -1; }
|
||||
next();
|
||||
if (tk == Assign) {
|
||||
next();
|
||||
if (tk != Num) { printf("%d: bad enum initializer\n", line); return -1; }
|
||||
if (tk != Num) { printf("%ld: bad enum initializer\n", line); return -1; }
|
||||
i = ival;
|
||||
next();
|
||||
}
|
||||
id[Class] = Num; id[Type] = INT; id[Val] = i++;
|
||||
id[Class] = Num; id[Type] = LONG; id[Val] = i++;
|
||||
if (tk == ',') next();
|
||||
}
|
||||
next();
|
||||
|
|
@ -395,21 +396,21 @@ int main(int argc, char **argv)
|
|||
while (tk != ';' && tk != '}') {
|
||||
ty = bt;
|
||||
while (tk == Mul) { next(); ty = ty + PTR; }
|
||||
if (tk != Id) { printf("%d: bad global declaration\n", line); return -1; }
|
||||
if (id[Class]) { printf("%d: duplicate global definition\n", line); return -1; }
|
||||
if (tk != Id) { printf("%ld: bad global declaration\n", line); return -1; }
|
||||
if (id[Class]) { printf("%ld: duplicate global definition\n", line); return -1; }
|
||||
next();
|
||||
id[Type] = ty;
|
||||
if (tk == '(') { // function
|
||||
id[Class] = Fun;
|
||||
id[Val] = (int)(e + 1);
|
||||
id[Val] = (long)(e + 1);
|
||||
next(); i = 0;
|
||||
while (tk != ')') {
|
||||
ty = INT;
|
||||
if (tk == Int) next();
|
||||
ty = LONG;
|
||||
if (tk == Long) next();
|
||||
else if (tk == Char) { next(); ty = CHAR; }
|
||||
while (tk == Mul) { next(); ty = ty + PTR; }
|
||||
if (tk != Id) { printf("%d: bad parameter declaration\n", line); return -1; }
|
||||
if (id[Class] == Loc) { printf("%d: duplicate parameter definition\n", line); return -1; }
|
||||
if (tk != Id) { printf("%ld: bad parameter declaration\n", line); return -1; }
|
||||
if (id[Class] == Loc) { printf("%ld: duplicate parameter definition\n", line); return -1; }
|
||||
id[HClass] = id[Class]; id[Class] = Loc;
|
||||
id[HType] = id[Type]; id[Type] = ty;
|
||||
id[HVal] = id[Val]; id[Val] = i++;
|
||||
|
|
@ -417,17 +418,17 @@ int main(int argc, char **argv)
|
|||
if (tk == ',') next();
|
||||
}
|
||||
next();
|
||||
if (tk != '{') { printf("%d: bad function definition\n", line); return -1; }
|
||||
if (tk != '{') { printf("%ld: bad function definition\n", line); return -1; }
|
||||
loc = ++i;
|
||||
next();
|
||||
while (tk == Int || tk == Char) {
|
||||
bt = (tk == Int) ? INT : CHAR;
|
||||
while (tk == Long || tk == Char) {
|
||||
bt = (tk == Long) ? LONG : CHAR;
|
||||
next();
|
||||
while (tk != ';') {
|
||||
ty = bt;
|
||||
while (tk == Mul) { next(); ty = ty + PTR; }
|
||||
if (tk != Id) { printf("%d: bad local declaration\n", line); return -1; }
|
||||
if (id[Class] == Loc) { printf("%d: duplicate local definition\n", line); return -1; }
|
||||
if (tk != Id) { printf("%ld: bad local declaration\n", line); return -1; }
|
||||
if (id[Class] == Loc) { printf("%ld: duplicate local definition\n", line); return -1; }
|
||||
id[HClass] = id[Class]; id[Class] = Loc;
|
||||
id[HType] = id[Type]; id[Type] = ty;
|
||||
id[HVal] = id[Val]; id[Val] = ++i;
|
||||
|
|
@ -451,48 +452,48 @@ int main(int argc, char **argv)
|
|||
}
|
||||
else {
|
||||
id[Class] = Glo;
|
||||
id[Val] = (int)data;
|
||||
data = data + sizeof(int);
|
||||
id[Val] = (long)data;
|
||||
data = data + sizeof(long);
|
||||
}
|
||||
if (tk == ',') next();
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
if (!(pc = (int *)idmain[Val])) { printf("main() not defined\n"); return -1; }
|
||||
if (!(pc = (long *)idmain[Val])) { printf("main() not defined\n"); return -1; }
|
||||
if (src) return 0;
|
||||
|
||||
// setup stack
|
||||
bp = sp = (int *)((int)sp + poolsz);
|
||||
bp = sp = (long *)((long)sp + poolsz);
|
||||
*--sp = EXIT; // call exit if main returns
|
||||
*--sp = PSH; t = sp;
|
||||
*--sp = argc;
|
||||
*--sp = (int)argv;
|
||||
*--sp = (int)t;
|
||||
*--sp = (long)argv;
|
||||
*--sp = (long)t;
|
||||
|
||||
// run...
|
||||
cycle = 0;
|
||||
while (1) {
|
||||
i = *pc++; ++cycle;
|
||||
if (debug) {
|
||||
printf("%d> %.4s", cycle,
|
||||
printf("%ld> %.4s", cycle,
|
||||
&"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,"
|
||||
"OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,"
|
||||
"OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT,"[i * 5]);
|
||||
if (i <= ADJ) printf(" %d\n", *pc); else printf("\n");
|
||||
if (i <= ADJ) printf(" %ld\n", *pc); else printf("\n");
|
||||
}
|
||||
if (i == LEA) a = (int)(bp + *pc++); // load local address
|
||||
if (i == LEA) a = (long)(bp + *pc++); // load local address
|
||||
else if (i == IMM) a = *pc++; // load global address or immediate
|
||||
else if (i == JMP) pc = (int *)*pc; // jump
|
||||
else if (i == JSR) { *--sp = (int)(pc + 1); pc = (int *)*pc; } // jump to subroutine
|
||||
else if (i == BZ) pc = a ? pc + 1 : (int *)*pc; // branch if zero
|
||||
else if (i == BNZ) pc = a ? (int *)*pc : pc + 1; // branch if not zero
|
||||
else if (i == ENT) { *--sp = (int)bp; bp = sp; sp = sp - *pc++; } // enter subroutine
|
||||
else if (i == JMP) pc = (long *)*pc; // jump
|
||||
else if (i == JSR) { *--sp = (long)(pc + 1); pc = (long *)*pc; } // jump to subroutine
|
||||
else if (i == BZ) pc = a ? pc + 1 : (long *)*pc; // branch if zero
|
||||
else if (i == BNZ) pc = a ? (long *)*pc : pc + 1; // branch if not zero
|
||||
else if (i == ENT) { *--sp = (long)bp; bp = sp; sp = sp - *pc++; } // enter subroutine
|
||||
else if (i == ADJ) sp = sp + *pc++; // stack adjust
|
||||
else if (i == LEV) { sp = bp; bp = (int *)*sp++; pc = (int *)*sp++; } // leave subroutine
|
||||
else if (i == LI) a = *(int *)a; // load int
|
||||
else if (i == LEV) { sp = bp; bp = (long *)*sp++; pc = (long *)*sp++; } // leave subroutine
|
||||
else if (i == LI) a = *(long *)a; // load long
|
||||
else if (i == LC) a = *(char *)a; // load char
|
||||
else if (i == SI) *(int *)*sp++ = a; // store int
|
||||
else if (i == SI) *(long *)*sp++ = a; // store long
|
||||
else if (i == SC) a = *(char *)*sp++ = a; // store char
|
||||
else if (i == PSH) *--sp = a; // push
|
||||
|
||||
|
|
@ -517,11 +518,11 @@ int main(int argc, char **argv)
|
|||
else if (i == READ) a = read(sp[2], (char *)sp[1], *sp);
|
||||
else if (i == CLOS) a = close(*sp);
|
||||
else if (i == PRTF) { t = sp + pc[1]; a = printf((char *)t[-1], t[-2], t[-3], t[-4], t[-5], t[-6]); }
|
||||
else if (i == MALC) a = (int)malloc(*sp);
|
||||
else if (i == MALC) a = (long)malloc(*sp);
|
||||
else if (i == FREE) free((void *)*sp);
|
||||
else if (i == MSET) a = (int)memset((char *)sp[2], sp[1], *sp);
|
||||
else if (i == MSET) a = (long)memset((char *)sp[2], sp[1], *sp);
|
||||
else if (i == MCMP) a = memcmp((char *)sp[2], (char *)sp[1], *sp);
|
||||
else if (i == EXIT) { printf("exit(%d) cycle = %d\n", *sp, cycle); return *sp; }
|
||||
else { printf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1; }
|
||||
else if (i == EXIT) { printf("exit(%ld) cycle = %ld\n", *sp, cycle); return *sp; }
|
||||
else { printf("unknown instruction = %ld! cycle = %ld\n", i, cycle); return -1; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue