diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2021-08-13 11:35:07 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2021-08-13 11:35:07 +0200 |
commit | a4e168a1b45b693bf68e30f37ea233b8f151329c (patch) | |
tree | eb9debec5f78bc145bd5d1b74a307c6aea5090c4 | |
parent | 7d0ea16a2c64883810f57b05d864837ddd724441 (diff) | |
download | compilertests-a4e168a1b45b693bf68e30f37ea233b8f151329c.tar.gz compilertests-a4e168a1b45b693bf68e30f37ea233b8f151329c.tar.bz2 |
c4: added support for do/while
c4: added is* (ctype) functions
c4: trying to add char array globs (don't work so far)
-rw-r--r-- | miniany/c4.c | 141 |
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; } } |