summaryrefslogtreecommitdiff
path: root/miniany/c4.c
diff options
context:
space:
mode:
Diffstat (limited to 'miniany/c4.c')
-rw-r--r--miniany/c4.c380
1 files changed, 227 insertions, 153 deletions
diff --git a/miniany/c4.c b/miniany/c4.c
index 8317947..ca6d3d3 100644
--- a/miniany/c4.c
+++ b/miniany/c4.c
@@ -6,18 +6,23 @@
/* Written by Robert Swierczek */
+#if !defined(__FREESTANDING__)
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
+#endif
/* #define int long long */
char *p, *lp, /* current position in source code */
- *data; /* data/bss pointer */
+ *startp, /* start of the source code (for free) */
+ *data, /* data/bss pointer */
+ *sdata; /* start of data/bss pointer (for free) */
int *e, *le, /* current position in emitted code */
+ *se, /* start of emited code (for free) */
*cas, /* case statement patch-up pointer */
*brak, /* break statement patch-up pointer */
*def, /* default statement patch-up pointer */
@@ -63,28 +68,63 @@ enum {
/* opcodes */
enum { 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,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,SDUP,EXIT };
+ MALC,FREE,MCPY,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,SDUP,EXIT };
/* types */
enum { CHAR, INT, PTR = 256, PTR2 = 512 };
+void error(char *msg)
+{
+ putint(line);
+ putstring(": ");
+ putstring(msg);
+ putnl();
+ exit(-1);
+}
+
+void error1int(char *msg, int i)
+{
+ putint(line);
+ putstring(": ");
+ putstring(msg);
+ putint(i);
+ putnl();
+ exit(-1);
+}
+
void next()
{
char *pp;
+ char *buf;
while ((tk = *p) != 0) {
++p;
switch (tk) {
case '\n':
if (src) {
- printf("%d: %.*s", line, p - lp, lp);
+ putint(line);
+ putstring(": ");
+ buf = (char *)malloc(512);
+ memcpy(buf, lp, p - lp);
+ buf[p-lp] = 0;
+ putstring(buf);
lp = p;
while (le < e) {
- printf("%8.4s", &"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,"
+ le++;
+ memcpy(buf, &"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,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,SDUP,EXIT,"[*++le * 5]);
- if (*le <= ADJ) printf(" %d\n", *++le); else printf("\n");
+ "MALC,FREE,MCPY,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,SDUP,EXIT,"[*le * 5], 4);
+ buf[4] = 0;
+ putstring(" ");
+ putstring(buf);
+ if (*le <= ADJ) {
+ le++;
+ putchar(' ');
+ putint(*le);
+ }
+ putnl();
}
+ free(buf);
}
++line;
break;
@@ -191,7 +231,7 @@ void expr(int lev)
struct member_s *m;
switch (tk) {
- case 0: printf("%d: unexpected eof in expression\n", line); exit(-1);
+ case 0: error("unexpected eof in expression");
case Num: *++e = IMM; *++e = ival; next(); ty = INT; break;
case '"':
*++e = IMM; *++e = ival; next();
@@ -199,11 +239,11 @@ void expr(int lev)
data = (char *)(((int)data + sizeof(int)) & -sizeof(int)); ty = PTR;
break;
case Sizeof:
- next(); if (tk == '(') next(); else { printf("%d: open paren expected in sizeof\n", line); exit(-1); }
+ next(); if (tk == '(') next(); else { error("open paren expected in sizeof"); }
ty = INT; if (tk == Int) next(); else if (tk == Char) { next(); ty = CHAR; }
- else if (tk == Struct) { next(); if (tk != Id) { printf("%d: bad struct type\n", line); exit(-1); } ty = id->stype; next(); }
+ else if (tk == Struct) { next(); if (tk != Id) { error("bad struct type"); } ty = id->stype; next(); }
while (tk == Mul) { next(); ty = ty + PTR; }
- if (tk == ')') next(); else { printf("%d: close paren expected in sizeof\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("close paren expected in sizeof"); }
*++e = IMM; *++e = ty >= PTR ? sizeof(int) : tsize[ty];
ty = INT;
break;
@@ -216,7 +256,7 @@ 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 { error("bad function call"); }
if (t) { *++e = ADJ; *++e = t; }
ty = d->type;
}
@@ -224,7 +264,7 @@ void expr(int lev)
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 { error("undefined variable"); }
if ((ty = d->type) <= INT || ty >= PTR) *++e = (ty == CHAR) ? LC : LI;
}
break;
@@ -232,25 +272,25 @@ void expr(int lev)
next();
if (tk == Int || tk == Char || tk == Struct) {
if (tk == Int) { next(); t = INT; } else if (tk == Char) { next(); t = CHAR; }
- else { next(); if (tk != Id) { printf("%d: bad struct type\n", line); exit(-1); } t = id->stype; next(); }
+ else { next(); if (tk != Id) { error("bad struct type"); } t = id->stype; next(); }
while (tk == Mul) { next(); t = t + PTR; }
- if (tk == ')') next(); else { printf("%d: bad cast\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("bad cast"); }
expr(Inc);
ty = t;
}
else {
expr(Assign);
- if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("close paren expected"); }
}
break;
case Mul:
next(); expr(Inc);
- if (ty > INT) ty = ty - PTR; else { printf("%d: bad dereference\n", line); exit(-1); }
+ if (ty > INT) ty = ty - PTR; else { error("bad dereference"); }
if (ty <= INT || ty >= PTR) *++e = (ty == CHAR) ? LC : LI;
break;
case 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 { error("bad address-of"); }
ty = ty + PTR;
break;
case '!': next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = 0; *++e = EQ; ty = INT; break;
@@ -266,13 +306,13 @@ void expr(int lev)
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 { error("bad lvalue in pre-increment"); }
*++e = PSH;
*++e = IMM; *++e = ty >= PTR2 ? sizeof(int) : (ty >= PTR) ? tsize[ty - PTR] : 1;
*++e = (t == Inc) ? ADD : SUB;
*++e = (ty == CHAR) ? SC : SI;
break;
- default: printf("%d: bad expression\n", line); exit(-1);
+ default: error("bad expression");
}
while (tk >= lev) { /* "precedence climbing" or "Top Down Operator Precedence" method */
@@ -280,14 +320,14 @@ void expr(int lev)
switch (tk) {
case 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 { error("bad lvalue in assignment"); }
expr(Assign); *++e = ((ty = t) == CHAR) ? SC : SI;
break;
case Cond:
next();
*++e = BZ; b = ++e;
expr(Assign);
- if (tk == ':') next(); else { printf("%d: conditional missing colon\n", line); exit(-1); }
+ if (tk == ':') next(); else { error("conditional missing colon"); }
*b = (int)(e + 3); *++e = JMP; b = ++e;
expr(Cond);
*b = (int)(e + 1);
@@ -326,7 +366,7 @@ void expr(int lev)
case 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); }
+ else { error("bad lvalue in post-increment"); }
sz = ty >= PTR2 ? sizeof(int) : ty >= PTR ? tsize[ty - PTR] : 1;
*++e = PSH; *++e = IMM; *++e = sz;
*++e = (tk == Inc) ? ADD : SUB;
@@ -338,11 +378,11 @@ void expr(int lev)
case Dot:
ty = ty + PTR;
case Arrow:
- if (ty <= PTR+INT || ty >= PTR2) { printf("%d: structure expected\n", line); exit(-1); }
+ if (ty <= PTR+INT || ty >= PTR2) { error("structure expected"); }
next();
- if (tk != Id) { printf("%d: structure member expected\n", line); exit(-1); }
+ if (tk != Id) { error("structure member expected"); }
m = members[ty - PTR]; while (m && m->id != id) m = m->next;
- if (!m) { printf("%d: structure member not found\n", line); exit(-1); }
+ if (!m) { error("structure member not found"); }
if (m->offset) { *++e = PSH; *++e = IMM; *++e = m->offset; *++e = ADD; }
ty = m->type;
if (ty <= INT || ty >= PTR) *++e = (ty == CHAR) ? LC : LI;
@@ -350,14 +390,14 @@ void expr(int lev)
break;
case Brak:
next(); *++e = PSH; expr(Assign);
- if (tk == ']') next(); else { printf("%d: close bracket expected\n", line); exit(-1); }
- if (t < PTR) { printf("%d: pointer type expected\n", line); exit(-1); }
+ if (tk == ']') next(); else { error("close bracket expected"); }
+ if (t < PTR) { error("pointer type expected"); }
sz = (t = t - PTR) >= PTR ? sizeof(int) : tsize[t];
if (sz > 1) { *++e = PSH; *++e = IMM; *++e = sz; *++e = MUL; }
*++e = ADD;
if ((ty = t) <= INT || ty >= PTR) *++e = (ty == CHAR) ? LC : LI;
break;
- default: printf("%d: compiler error tk=%d\n", line, tk); exit(-1);
+ default: error1int("compiler error tk=", tk);
}
}
}
@@ -369,9 +409,9 @@ void stmt()
switch (tk) {
case If:
next();
- if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
+ if (tk == '(') next(); else { error("open paren expected"); }
expr(Assign);
- if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("close paren expected\n"); }
*++e = BZ; b = ++e;
stmt();
if (tk == Else) {
@@ -385,11 +425,11 @@ void stmt()
next();
a = e + 1;
stmt();
- if (tk != While) { printf("%d: while expected to terminate do loop\n", line); exit(-1); }
+ if (tk != While) { error("while expected to terminate do loop"); }
next();
- if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
+ if (tk == '(') next(); else { error("open paren expected"); }
expr(Assign);
- if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("close paren expected"); }
*++e = BZ; b = ++e;
*++e = JMP; *++e = (int)a;
*b = (int)(e + 1);
@@ -397,9 +437,9 @@ void stmt()
case While:
next();
a = e + 1;
- if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
+ if (tk == '(') next(); else { error("open paren expected"); }
expr(Assign);
- if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("close paren expected"); }
*++e = BZ; b = ++e;
stmt();
*++e = JMP; *++e = (int)a;
@@ -407,9 +447,9 @@ void stmt()
return;
case Switch:
next();
- if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
+ if (tk == '(') next(); else { error("open paren expected"); }
expr(Assign);
- if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
+ if (tk == ')') next(); else { error("close paren expected"); }
a = cas; *++e = JMP; cas = ++e;
b = brak; d = def; brak = def = 0;
stmt();
@@ -421,19 +461,19 @@ void stmt()
*++e = JMP; ++e; *e = (int)(e + 7); *++e = PSH; i = *cas; *cas = (int)e;
next();
expr(Or);
- if (e[-1] != IMM) { printf("%d: bad case immediate\n", line); exit(-1); }
+ if (e[-1] != IMM) { error("bad case immediate"); }
*e = *e - i; *++e = SUB; *++e = BNZ; cas = ++e; *e = i + e[-3];
- if (tk == ':') next(); else { printf("%d: colon expected\n", line); exit(-1); }
+ if (tk == ':') next(); else { error("colon expected"); }
stmt();
return;
case Break:
next();
- if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
+ if (tk == ';') next(); else { error("semicolon expected"); }
*++e = JMP; *++e = (int)brak; brak = e;
return;
case Default:
next();
- if (tk == ':') next(); else { printf("%d: colon expected\n", line); exit(-1); }
+ if (tk == ':') next(); else { error("colon expected"); }
def = e + 1;
stmt();
return;
@@ -441,7 +481,7 @@ void stmt()
next();
if (tk != ';') expr(Assign);
*++e = LEV;
- if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
+ if (tk == ';') next(); else { error("semicolon expected"); }
return;
case '{':
next();
@@ -453,56 +493,60 @@ void stmt()
return;
default:
expr(Assign);
- if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
+ if (tk == ';') next(); else { error("semicolon expected"); }
}
}
int main(int argc, char **argv)
{
- int fd, bt, mbt, ty, poolsz;
+ int bt, mbt, ty, poolsz;
struct ident_s *idmain;
- struct member_s *m;
+ struct member_s *m, *mtmp;
int *pc, *sp, *bp, a, cycle; /* vm registers */
int i, *t, neg; /* temps */
-
+ int rt, run, n;
+ int *ssp;
+ char *buf;
+
--argc; ++argv;
if (argc > 0 && **argv == '-' && (*argv)[1] == 's') { src = 1; --argc; ++argv; }
if (argc > 0 && **argv == '-' && (*argv)[1] == 'd') { debug = 1; --argc; ++argv; }
- if (argc < 1) { printf("usage: c4 [-s] [-d] file ...\n"); return -1; }
-
- 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 (!(tsize = malloc(PTR * sizeof(int)))) { printf("could not malloc() tsize area\n"); return -1; }
- if (!(members = malloc(PTR * sizeof(struct member_s *)))) { printf("could not malloc() members area\n"); return -1; }
+ if (!(sym = (struct ident_s *)malloc(poolsz))) { error("could not malloc symbol area"); }
+ if (!(se = le = e = (int *)malloc(poolsz))) { error("could not malloc text area"); }
+ if (!(sdata = data = malloc(poolsz))) { error("could not malloc data area"); }
+ if (!(ssp = sp = (int *)malloc(poolsz))) { error("could not malloc stack area"); }
+ if (!(tsize = (int *)malloc(PTR * sizeof(int)))) { error("could not malloc tsize area"); }
+ if (!(members = (struct member_s **)malloc(PTR * sizeof(struct member_s *)))) { error("could not malloc members area"); }
- memset(sym, 0, poolsz);
- memset(e, 0, poolsz);
- memset(data, 0, poolsz);
- memset(tsize, 0, PTR * sizeof(int));
- memset(members, 0, PTR * sizeof(struct member_s *));
+ memset((char *)sym, 0, poolsz);
+ memset((char *)e, 0, poolsz);
+ memset((char *)data, 0, poolsz);
+ memset((char *)tsize, 0, PTR * sizeof(int));
+ memset((char *)members, 0, PTR * sizeof(struct member_s *));
p = "break case char default else enum if int return sizeof do struct switch while "
"EOF EXIT_SUCCESS EXIT_FAILURE NULL "
- "open read close printf malloc free memset memcmp getchar putstring putnl putchar putint isspace isdigit isalnum isalpha strcmp strdup exit void main";
+ "malloc free memcpy memset memcmp getchar putstring putnl putchar putint isspace isdigit isalnum isalpha strcmp strdup exit void main";
i = Break; while (i <= While) { next(); id->tk = i++; } /* add keywords to symbol table */
/* add library constants */
next(); id->class = Num; id->type = INT; id->val = -1;
next(); id->class = Num; id->type = INT; id->val = 0;
next(); id->class = Num; id->type = INT; id->val = 1;
next(); id->class = Num; id->type = INT; id->val = (int)NULL;
- i = OPEN; while (i <= EXIT) { next(); id->class = Sys; id->type = INT; id->val = i++; } /* add library to symbol table */
+ i = MALC; while (i <= EXIT) { next(); id->class = Sys; id->type = INT; id->val = i++; } /* add library to symbol table */
next(); id->tk = Char; /* handle void type */
next(); idmain = id; /* keep track of main */
- 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 (!(startp = lp = p = malloc(poolsz))) { error("could not malloc source area"); }
+
+ i = 0; p[i] = getchar();
+ while (p[i]!=28 /* FS file separator */ && p[i]!=EOF) {
+ i++; p[i] = getchar();
+ if (i>=poolsz-1) { error("too small read buffer"); }
+ }
p[i] = 0;
- close(fd);
/* add primitive types */
tsize[tnew++] = sizeof(char);
@@ -522,13 +566,13 @@ 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) { error("bad enum identifier"); }
next();
if (tk == Assign) {
next();
neg = 0;
if (tk == Sub) { next(); neg =1; }
- if (tk != Num) { printf("%d: bad enum initializer\n", line); return -1; }
+ if (tk != Num) { error("bad enum initializer"); }
i = ival;
if (neg) {
i = -ival;
@@ -552,7 +596,7 @@ int main(int argc, char **argv)
}
if (tk == '{') {
next();
- if (members[bt]) { printf("%d: duplicate structure definition\n", line); return -1; }
+ if (members[bt]) { error("duplicate structure definition"); }
i = 0;
while (tk != '}') {
mbt = INT;
@@ -560,15 +604,15 @@ int main(int argc, char **argv)
else if (tk == Char) { next(); mbt = CHAR; }
else if (tk == Struct) {
next();
- if (tk != Id) { printf("%d: bad struct declaration\n", line); return -1; }
+ if (tk != Id) { error("bad struct declaration\n"); }
mbt = id->stype;
next();
}
while (tk != ';') {
ty = mbt;
while (tk == Mul) { next(); ty = ty + PTR; }
- if (tk != Id) { printf("%d: bad struct member definition\n", line); return -1; }
- m = malloc(sizeof(struct member_s));
+ if (tk != Id) { error("bad struct member definition"); }
+ m = (struct member_s *)malloc(sizeof(struct member_s));
m->id = id;
m->offset = i;
m->type = ty;
@@ -588,8 +632,8 @@ 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) { error("bad global declaration"); }
+ if (id->class) { error("duplicate global definition"); }
next();
id->type = ty;
if (tk == '(') { /* function */
@@ -602,13 +646,13 @@ int main(int argc, char **argv)
else if (tk == Char) { next(); ty = CHAR; }
else if (tk == Struct) {
next();
- if (tk != Id) { printf("%d: bad struct declaration\n", line); return -1; }
+ if (tk != Id) { error("bad struct declaration"); }
ty = id->stype;
next();
}
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) { error("bad parameter declaration"); }
+ if (id->class == Loc) { error("duplicate parameter definition"); }
id->hclass = id->class; id->class = Loc;
id->htype = id->type; id->type = ty;
id->hval = id->val; id->val = i++;
@@ -616,21 +660,21 @@ int main(int argc, char **argv)
if (tk == ',') next();
}
next();
- if (tk != '{') { printf("%d: bad function definition\n", line); return -1; }
+ if (tk != '{') { error("bad function definition"); }
loc = ++i;
next();
while (tk == Int || tk == Char || tk == Struct) {
if (tk == Int) bt = INT; else if (tk == Char) bt = CHAR; else {
next();
- if (tk != Id) { printf("%d: bad struct declaration\n", line); return -1; }
+ if (tk != Id) { error("bad struct declaration"); }
bt = id->stype;
}
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) { error("bad local declaration"); }
+ if (id->class == Loc) { error("duplicate local definition"); }
id->hclass = id->class; id->class = Loc;
id->htype = id->type; id->type = ty;
id->hval = id->val; id->val = ++i;
@@ -662,83 +706,113 @@ int main(int argc, char **argv)
next();
}
- if (!(pc = (int *)idmain->val)) { printf("main() not defined\n"); return -1; }
- if (src) return 0;
+ if (!(pc = (int *)idmain->val)) { error("main() not defined\n"); }
+ rt = 0;
+ if (!src) {
- /* setup stack */
- bp = sp = (int *)((int)sp + poolsz);
- *--sp = EXIT; /* call exit if main returns */
- *--sp = PSH; t = sp;
- *--sp = argc;
- *--sp = (int)argv;
- *--sp = (int)t;
+ /* setup stack */
+ bp = sp = (int *)((int)sp + poolsz);
+ *--sp = EXIT; /* call exit if main returns */
+ *--sp = PSH; t = sp;
+ *--sp = argc;
+ *--sp = (int)argv;
+ *--sp = (int)t;
- /* run... */
- cycle = 0;
- a = 0;
- while (1) {
- i = *pc++; ++cycle;
- if (debug) {
- printf("%d> %.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,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,SDUP,EXIT,"[i * 5]);
- if (i <= ADJ) printf(" %d\n", *pc); else printf("\n");
- }
- switch (i) {
- case LEA: a = (int)(bp + *pc++); break; /* load local address */
- case IMM: a = *pc++; break; /* load global address or immediate */
- case JMP: pc = (int *)*pc; break; /* jump */
- case JSR: *--sp = (int)(pc + 1); pc = (int *)*pc; break; /* jump to subroutine */
- case BZ: pc = a ? pc + 1 : (int *)*pc; break; /* branch if zero */
- case BNZ: pc = a ? (int *)*pc : pc + 1; break; /* branch if not zero */
- case ENT: *--sp = (int)bp; bp = sp; sp = sp - *pc++; break; /* enter subroutine */
- case ADJ: sp = sp + *pc++; break; /* stack adjust */
- case LEV: sp = bp; bp = (int *)*sp++; pc = (int *)*sp++; break; /* leave subroutine */
- case LI: a = *(int *)a; break; /* load int */
- case LC: a = *(char *)a; break; /* load char */
- case SI: *(int *)*sp++ = a; break; /* store int */
- case SC: a = *(char *)*sp++ = a; break; /* store char */
- case PSH: *--sp = a; break; /* push */
+ /* run... */
+ cycle = 0;
+ a = 0;
+ run = 1;
+ while (run) {
+ i = *pc++; ++cycle;
+ if (debug) {
+ putint(cycle);
+ putstring("> ");
+ buf = (char *)malloc( 5 );
+ memcpy(buf, &"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 ,"
+ "MALC,FREE,MCPY,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,SDUP,EXIT,"[i * 5],4);
+ buf[4] = 0;
+ putstring(buf);
+ free(buf);
+ if (i <= ADJ) {
+ putchar(' ');
+ putint(*pc);
+ }
+ putnl();
+ }
+ switch (i) {
+ case LEA: a = (int)(bp + *pc++); break; /* load local address */
+ case IMM: a = *pc++; break; /* load global address or immediate */
+ case JMP: pc = (int *)*pc; break; /* jump */
+ case JSR: *--sp = (int)(pc + 1); pc = (int *)*pc; break; /* jump to subroutine */
+ case BZ: pc = a ? pc + 1 : (int *)*pc; break; /* branch if zero */
+ case BNZ: pc = a ? (int *)*pc : pc + 1; break; /* branch if not zero */
+ case ENT: *--sp = (int)bp; bp = sp; sp = sp - *pc++; break; /* enter subroutine */
+ case ADJ: sp = sp + *pc++; break; /* stack adjust */
+ case LEV: sp = bp; bp = (int *)*sp++; pc = (int *)*sp++; break; /* leave subroutine */
+ case LI: a = *(int *)a; break; /* load int */
+ case LC: a = *(char *)a; break; /* load char */
+ case SI: *(int *)*sp++ = a; break; /* store int */
+ case SC: a = *(char *)*sp++ = a; break; /* store char */
+ case PSH: *--sp = a; break; /* push */
- case OR: a = *sp++ | a; break;
- case XOR: a = *sp++ ^ a; break;
- case AND: a = *sp++ & a; break;
- case EQ: a = *sp++ == a; break;
- case NE: a = *sp++ != a; break;
- case LT: a = *sp++ < a; break;
- case GT: a = *sp++ > a; break;
- case LE: a = *sp++ <= a; break;
- case GE: a = *sp++ >= a; break;
- case SHL: a = *sp++ << a; break;
- case SHR: a = *sp++ >> a; break;
- case ADD: a = *sp++ + a; break;
- case SUB: a = *sp++ - a; break;
- case MUL: a = *sp++ * a; break;
- case DIV: a = *sp++ / a; break;
- case MOD: a = *sp++ % a; break;
+ case OR: a = *sp++ | a; break;
+ case XOR: a = *sp++ ^ a; break;
+ case AND: a = *sp++ & a; break;
+ case EQ: a = *sp++ == a; break;
+ case NE: a = *sp++ != a; break;
+ case LT: a = *sp++ < a; break;
+ case GT: a = *sp++ > a; break;
+ case LE: a = *sp++ <= a; break;
+ case GE: a = *sp++ >= a; break;
+ case SHL: a = *sp++ << a; break;
+ case SHR: a = *sp++ >> a; break;
+ case ADD: a = *sp++ + a; break;
+ case SUB: a = *sp++ - a; break;
+ case MUL: a = *sp++ * a; break;
+ case DIV: a = *sp++ / a; break;
+ case MOD: a = *sp++ % a; break;
- case OPEN: a = open((char *)sp[1], *sp); break;
- case READ: a = read(sp[2], (char *)sp[1], *sp); break;
- case CLOS: a = close(*sp); break;
- case PRTF: t = sp + pc[1]; a = printf((char *)t[-1], t[-2], t[-3], t[-4], t[-5], t[-6]); break;
- case MALC: a = (int)malloc(*sp); break;
- case FREE: free((void *)*sp); break;
- case MSET: a = (int)memset((char *)sp[2], sp[1], *sp); break;
- case MCMP: a = memcmp((char *)sp[2], (char *)sp[1], *sp); break;
- case GETC: a = getchar(); break;
- case PUTS: t = sp + pc[1]; a = printf("%s", (char *)t[-1]); break;
- case PUTN: a = printf("\n"); break;
- case PUTC: a = putchar(*sp); break;
- case PUTI: t = sp + pc[1]; a = printf("%d", (int)t[-1]); break;
- case ISPC: t = sp + pc[1]; a = isspace( (int)t[-1]); break;
- case IDGT: t = sp + pc[1]; a = isdigit( (int)t[-1]); break;
- case IANU: t = sp + pc[1]; a = isalnum( (int)t[-1]); break;
- case IALP: t = sp + pc[1]; a = isalpha( (int)t[-1]); break;
- case SCMP: t = sp + pc[1]; a = strcmp((char *)t[-1], (char *)t[-2]); break;
- case SDUP: t = sp + pc[1]; a = (int)strdup((char *)t[-1]); break;
- case EXIT: /* printf("exit(%d) cycle = %d\n", *sp, cycle); */ return *sp;
- default: printf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1;
+ case MALC: a = (int)malloc(*sp); break;
+ case FREE: free((void *)*sp); break;
+ case MCPY: a = (int)memcpy((char *)sp[2], (char *)sp[1], *sp); break;
+ case MSET: a = (int)memset((char *)sp[2], sp[1], *sp); break;
+ case MCMP: a = memcmp((char *)sp[2], (char *)sp[1], *sp); break;
+ case GETC: a = getchar(); break;
+ case PUTS: t = sp + pc[1]; a = putstring((char *)t[-1]); break;
+ case PUTN: a = putnl(); break;
+ case PUTC: a = putchar(*sp); break;
+ case PUTI: t = sp + pc[1]; a = putint((int)t[-1]); break;
+ case ISPC: t = sp + pc[1]; a = isspace( (int)t[-1]); break;
+ case IDGT: t = sp + pc[1]; a = isdigit( (int)t[-1]); break;
+ case IANU: t = sp + pc[1]; a = isalnum( (int)t[-1]); break;
+ case IALP: t = sp + pc[1]; a = isalpha( (int)t[-1]); break;
+ case SCMP: t = sp + pc[1]; a = strcmp((char *)t[-1], (char *)t[-2]); break;
+ case SDUP: t = sp + pc[1]; a = (int)strdup((char *)t[-1]); break;
+ case EXIT: /* putstring("exit("); putint(*sp); putstring(") cycle = "); putint(cycle); putnl(); */ rt = *sp; run = 0; break;
+ default: putstring("unknown instruction = "); putint(i); putstring("! cycle = "); putint(cycle); putnl(); rt = -1; run = 0; break;
+ }
+ }
+ }
+ free((char *)startp);
+ n = 0;
+ while (n<PTR) {
+ if (members[n]) {
+ m = members[n];
+ while (m) {
+ mtmp = m;
+ m = m->next;
+ free((char *)mtmp);
+ }
}
+ n++;
}
+ free((char *)members);
+ free((char *)tsize);
+ free((char *)ssp);
+ free((char *)sdata);
+ free((char *)se);
+ free((char *)sym);
+ exit(rt);
+ return rt;
}