summaryrefslogtreecommitdiff
path: root/miniany/c4.c
diff options
context:
space:
mode:
Diffstat (limited to 'miniany/c4.c')
-rw-r--r--miniany/c4.c141
1 files changed, 87 insertions, 54 deletions
diff --git a/miniany/c4.c b/miniany/c4.c
index a3cc0ff..a6d24d3 100644
--- a/miniany/c4.c
+++ b/miniany/c4.c
@@ -11,6 +11,7 @@
#include <memory.h>
#include <unistd.h>
#include <fcntl.h>
+#include <ctype.h>
//#define int long long
char *p, *lp, // current position in source code
@@ -30,14 +31,14 @@ int *e, *le, // current position in emitted code
// 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, Int, Return, Sizeof, Do, While,
Assign, Cond, Lor, Lan, Or, Xor, And, Eq, Ne, Lt, Gt, Le, Ge, Shl, Shr, Add, Sub, Mul, Div, Mod, Inc, Dec, Brak
};
// 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,EXIT };
+ OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,EXIT };
// types
enum { CHAR, INT, PTR };
@@ -58,7 +59,7 @@ void next()
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,GETC,PUTS,PUTN,PUTC,PUTI,EXIT,"[*++le * 5]);
+ "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,EXIT,"[*++le * 5]);
if (*le <= ADJ) printf(" %d\n", *++le); else printf("\n");
}
}
@@ -308,6 +309,19 @@ void stmt()
}
*b = (int)(e + 1);
}
+ else if (tk == Do) {
+ next();
+ a = e + 1;
+ stmt();
+ if (tk != While) { printf("%d: while expected to terminate do loop\n", line); exit(-1); }
+ next();
+ if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
+ expr(Assign);
+ if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
+ *++e = BZ; b = ++e;
+ *++e = JMP; *++e = (int)a;
+ *b = (int)(e + 1);
+ }
else if (tk == While) {
next();
a = e + 1;
@@ -362,13 +376,14 @@ int main(int argc, char **argv)
memset(e, 0, poolsz);
memset(data, 0, poolsz);
- p = "char else enum if int return sizeof while "
- "EOF EXIT_SUCCESS "
- "open read close printf malloc free memset memcmp getchar putstring putnl putchar putint exit void main";
+ p = "char else enum if int return sizeof do while "
+ "EOF EXIT_SUCCESS EXIT_FAILURE "
+ "open read close printf malloc free memset memcmp getchar putstring putnl putchar putint isspace isdigit isalnum isalpha strcmp exit void main";
i = Char; 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;
i = OPEN; 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
@@ -409,64 +424,77 @@ 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; }
- next();
- id[Type] = ty;
- if (tk == '(') { // function
- id[Class] = Fun;
- id[Val] = (int)(e + 1);
- next(); i = 0;
- while (tk != ')') {
- ty = INT;
- if (tk == Int) 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; }
- id[HClass] = id[Class]; id[Class] = Loc;
- id[HType] = id[Type]; id[Type] = ty;
- id[HVal] = id[Val]; id[Val] = i++;
- next();
- if (tk == ',') next();
- }
+ if (tk == Brak) {
next();
- if (tk != '{') { printf("%d: bad function definition\n", line); return -1; }
- loc = ++i;
+ if (tk == Num) next();
+ else { printf("%d: integer as dimensions of array expected\n", line); return -1; }
+ if (tk == ']') next();
+ else { printf("%d: ] expected\n", line); return -1; }
+ id[Type] = ty + PTR;
+ id[Class] = Glo;
+ id[Val] = (int)data;
+ data = data + ival * sizeof(char);
+ }
+ else {
+ if (tk != Id) { printf("%d: bad global declaration\n", line); return -1; }
+ if (id[Class]) { printf("%d: duplicate global definition\n", line); return -1; }
next();
- while (tk == Int || tk == Char) {
- bt = (tk == Int) ? INT : CHAR;
- next();
- while (tk != ';') {
- ty = bt;
+ id[Type] = ty;
+ if (tk == '(') { // function
+ id[Class] = Fun;
+ id[Val] = (int)(e + 1);
+ next(); i = 0;
+ while (tk != ')') {
+ ty = INT;
+ if (tk == Int) next();
+ else if (tk == Char) { next(); ty = CHAR; }
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("%d: bad parameter declaration\n", line); return -1; }
+ if (id[Class] == Loc) { printf("%d: 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;
+ id[HVal] = id[Val]; id[Val] = i++;
next();
if (tk == ',') next();
}
next();
- }
- *++e = ENT; *++e = i - loc;
- while (tk != '}') stmt();
- *++e = LEV;
- id = sym; // unwind symbol table locals
- while (id[Tk]) {
- if (id[Class] == Loc) {
- id[Class] = id[HClass];
- id[Type] = id[HType];
- id[Val] = id[HVal];
+ if (tk != '{') { printf("%d: bad function definition\n", line); return -1; }
+ loc = ++i;
+ next();
+ while (tk == Int || tk == Char) {
+ bt = (tk == Int) ? INT : 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; }
+ id[HClass] = id[Class]; id[Class] = Loc;
+ id[HType] = id[Type]; id[Type] = ty;
+ id[HVal] = id[Val]; id[Val] = ++i;
+ next();
+ if (tk == ',') next();
+ }
+ next();
+ }
+ *++e = ENT; *++e = i - loc;
+ while (tk != '}') stmt();
+ *++e = LEV;
+ id = sym; // unwind symbol table locals
+ while (id[Tk]) {
+ if (id[Class] == Loc) {
+ id[Class] = id[HClass];
+ id[Type] = id[HType];
+ id[Val] = id[HVal];
+ }
+ id = id + Idsz;
}
- id = id + Idsz;
}
- }
- else {
- id[Class] = Glo;
- id[Val] = (int)data;
- data = data + sizeof(int);
+ else {
+ id[Class] = Glo;
+ id[Val] = (int)data;
+ data = data + sizeof(int);
+ }
}
if (tk == ',') next();
}
@@ -492,7 +520,7 @@ int main(int argc, char **argv)
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,EXIT,"[i * 5]);
+ "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,EXIT,"[i * 5]);
if (i <= ADJ) printf(" %d\n", *pc); else printf("\n");
}
if (i == LEA) a = (int)(bp + *pc++); // load local address
@@ -540,6 +568,11 @@ int main(int argc, char **argv)
else if (i == PUTN) a = printf("\n");
else if (i == PUTC) a = putchar(*sp);
else if (i == PUTI) { t = sp + pc[1]; a = printf("%d", (int)t[-1]); }
+ else if (i == ISPC) { t = sp + pc[1]; a = isspace( (int)t[-1]); }
+ else if (i == IDGT) { t = sp + pc[1]; a = isdigit( (int)t[-1]); }
+ else if (i == IANU) { t = sp + pc[1]; a = isalnum( (int)t[-1]); }
+ else if (i == IALP) { t = sp + pc[1]; a = isalpha( (int)t[-1]); }
+ else if (i == SCMP) { t = sp + pc[1]; a = strcmp((char *)t[-1], (char *)t[-2]); }
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; }
}