From a4e168a1b45b693bf68e30f37ea233b8f151329c Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 13 Aug 2021 11:35:07 +0200 Subject: c4: added support for do/while c4: added is* (ctype) functions c4: trying to add char array globs (don't work so far) --- miniany/c4.c | 141 ++++++++++++++++++++++++++++++++++++----------------------- 1 file 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 #include #include +#include //#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; } } -- cgit v1.2.3-54-g00ecf