summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-08-13 11:35:07 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2021-08-13 11:35:07 +0200
commita4e168a1b45b693bf68e30f37ea233b8f151329c (patch)
treeeb9debec5f78bc145bd5d1b74a307c6aea5090c4
parent7d0ea16a2c64883810f57b05d864837ddd724441 (diff)
downloadcompilertests-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.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; }
}