summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-08-19 16:36:59 +0000
committerAndreas Baumann <mail@andreasbaumann.cc>2021-08-19 16:36:59 +0000
commitbfda462bca5db1693b2fa1c2845c8f4242d33782 (patch)
tree81a28cd3f75af75cc30c71a14bfb4c4475b7eae5
parent9fc685a2237b789800b770f3bc1eecb8e1bfdf7b (diff)
downloadcompilertests-bfda462bca5db1693b2fa1c2845c8f4242d33782.tar.gz
compilertests-bfda462bca5db1693b2fa1c2845c8f4242d33782.tar.bz2
c4: use cases
-rw-r--r--miniany/README19
-rw-r--r--miniany/REQUIREMENTS12
-rw-r--r--miniany/TODOS10
-rw-r--r--miniany/c4.c437
-rw-r--r--miniany/cc.c6
5 files changed, 257 insertions, 227 deletions
diff --git a/miniany/README b/miniany/README
index 851db39..f22c5f7 100644
--- a/miniany/README
+++ b/miniany/README
@@ -14,6 +14,23 @@ tcc -O0 -g -o c4 c4.c
./c4 c4.c c4.c cc.c < hello.c
```
+# Local version of c4
+
+This local version of c4 is used to guarantee that our own bootstrapped
+cc.c can also run on c4. This makes sure we are not integrating too
+complex things into our own compiler.
+
+* currently integrated:
+ - switch statement from switch-and-structs, adapted c4 to use switch
+ statements instead of ifs (as in switch-and-structs)
+* my own changes:
+ - constants like EOF, EXIT_SUCCESS, NULL
+ - standard C block comments along to c++ end of line ones
+ - negative enum initializers
+ - do/while loops
+ - more C functions like isspace, getc, strcmp
+ - some simplified functions for printing like putstring, putint, putnl
+
# Acknoledgments and references
* c4
@@ -22,7 +39,7 @@ tcc -O0 -g -o c4 c4.c
minimalistic C compiler running on an emulator on the IR, inspiration
for this project
* https://github.com/rswier/c4/blob/switch-and-structs/c4.c:
- c4 adaptions to provide switch and structs:
+ c4 adaptions to provide switch and structs
* https://github.com/EarlGray/c4: a X86 JIT version of c4
* https://github.com/jserv/amacc: based on C4, JIT or native code, for
ARM, quite well documented, also very nice list of compiler
diff --git a/miniany/REQUIREMENTS b/miniany/REQUIREMENTS
index cd6ffcf..9274af4 100644
--- a/miniany/REQUIREMENTS
+++ b/miniany/REQUIREMENTS
@@ -10,10 +10,14 @@ implementing:
not implementing:
- libc
- - printf
- - format string only, as replacement for puts
- - vararg required in compiler
- - not type-safe
+ - variadic functions are not type-safe, do we need them?
+ - printf -> putint, putchar, etc.
+ - format string only, as replacement for puts
+ - vararg required in compiler
+ - not type-safe
+ - snprintf no option, strcat, strstr etc also not really
+ - newer formating functions and logging: strfmon, error, warn, syslog
+ - syscall
- puts
- requires stdout, which is a FILE structure
- print_char
diff --git a/miniany/TODOS b/miniany/TODOS
index ed6e09e..07a0c81 100644
--- a/miniany/TODOS
+++ b/miniany/TODOS
@@ -1,12 +1,8 @@
+- c4
+ - global char array declarations
+ - void parameter
- avoid inline assembler, have more a inline bytecode adder
explicit opcodes, e.g. nop -> .byte 0x90
-- read -1 problem is the c4.c as interpreter reading behaving wrongly
- because -1 is wrongly handled in integer parsing
-- variadic functions are not type-safe, do we need them?
- - printf -> putint, putchar, etc.
- - snprintf no option, strcat, strstr etc also not really
- - newer formating functions and logging: strfmon, error, warn, syslog
- - syscall
diff --git a/miniany/c4.c b/miniany/c4.c
index 9acba4e..990c527 100644
--- a/miniany/c4.c
+++ b/miniany/c4.c
@@ -1,7 +1,7 @@
// c4.c - C in four functions
// char, int, and pointer types
-// if, while, return, and expression statements
+// if, while, do, return, switch and expression statements
// just enough features to allow self-compilation and a bit more
// Written by Robert Swierczek
@@ -55,7 +55,8 @@ void next()
while (tk = *p) {
++p;
- if (tk == '\n') {
+ switch (tk) {
+ case '\n':
if (src) {
printf("%d: %.*s", line, p - lp, lp);
lp = p;
@@ -67,11 +68,23 @@ void next()
}
}
++line;
- }
- else if (tk == '#') {
+ break;
+ case '#':
while (*p != 0 && *p != '\n') ++p;
- }
- else if ((tk >= 'a' && tk <= 'z') || (tk >= 'A' && tk <= 'Z') || tk == '_') {
+ break;
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y':
+ case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z':
+ case '_':
pp = p - 1;
while ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_')
tk = tk * 147 + *p++;
@@ -85,8 +98,8 @@ void next()
id[Hash] = tk;
tk = id[Tk] = Id;
return;
- }
- else if (tk >= '0' && tk <= '9') {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
if (ival = tk - '0') { while (*p >= '0' && *p <= '9') ival = ival * 10 + *p++ - '0'; }
else if (*p == 'x' || *p == 'X') {
while ((tk = *++p) && ((tk >= '0' && tk <= '9') || (tk >= 'a' && tk <= 'f') || (tk >= 'A' && tk <= 'F')))
@@ -95,8 +108,9 @@ void next()
else { while (*p >= '0' && *p <= '7') ival = ival * 8 + *p++ - '0'; }
tk = Num;
return;
- }
- else if (tk == '/') {
+ case ' ': case '\t':
+ break;
+ case '/':
if (*p == '/') {
++p;
while (*p != 0 && *p != '\n') ++p;
@@ -114,33 +128,39 @@ void next()
tk = Div;
return;
}
- }
- else if (tk == '\'' || tk == '"') {
+ break;
+ case '\'': case '"':
pp = data;
while (*p != 0 && *p != tk) {
if ((ival = *p++) == '\\') {
- if ((ival = *p++) == 'n') ival = '\n';
+ switch (ival = *p++) {
+ case 'n': ival = '\n'; break;
+ case 't': ival = '\t'; break;
+ }
}
if (tk == '"') *data++ = ival;
}
++p;
if (tk == '"') ival = (int)pp; else tk = Num;
return;
+ case '=': if (*p == '=') { ++p; tk = Eq; } else tk = Assign; return;
+ case '+': if (*p == '+') { ++p; tk = Inc; } else tk = Add; return;
+ case '-': if (*p == '-') { ++p; tk = Dec; } else tk = Sub; return;
+ case '!': if (*p == '=') { ++p; tk = Ne; } return;
+ case '<': if (*p == '=') { ++p; tk = Le; } else if (*p == '<') { ++p; tk = Shl; } else tk = Lt; return;
+ case '>': if (*p == '=') { ++p; tk = Ge; } else if (*p == '>') { ++p; tk = Shr; } else tk = Gt; return;
+ case '|': if (*p == '|') { ++p; tk = Lor; } else tk = Or; return;
+ case '&': if (*p == '&') { ++p; tk = Lan; } else tk = And; return;
+ case '^': tk = Xor; return;
+ case '%': tk = Mod; return;
+ case '*': tk = Mul; return;
+ case '[': tk = Brak; return;
+ case '?': tk = Cond; return;
+ case '~': case ';': case '{': case '}':
+ case '(': case ')': case ']': case ',':
+ case ':':
+ return;
}
- else if (tk == '=') { if (*p == '=') { ++p; tk = Eq; } else tk = Assign; return; }
- else if (tk == '+') { if (*p == '+') { ++p; tk = Inc; } else tk = Add; return; }
- else if (tk == '-') { if (*p == '-') { ++p; tk = Dec; } else tk = Sub; return; }
- else if (tk == '!') { if (*p == '=') { ++p; tk = Ne; } return; }
- else if (tk == '<') { if (*p == '=') { ++p; tk = Le; } else if (*p == '<') { ++p; tk = Shl; } else tk = Lt; return; }
- else if (tk == '>') { if (*p == '=') { ++p; tk = Ge; } else if (*p == '>') { ++p; tk = Shr; } else tk = Gt; return; }
- else if (tk == '|') { if (*p == '|') { ++p; tk = Lor; } else tk = Or; return; }
- else if (tk == '&') { if (*p == '&') { ++p; tk = Lan; } else tk = And; return; }
- else if (tk == '^') { tk = Xor; return; }
- else if (tk == '%') { tk = Mod; return; }
- else if (tk == '*') { tk = Mul; return; }
- else if (tk == '[') { tk = Brak; return; }
- else if (tk == '?') { tk = Cond; return; }
- else if (tk == '~' || tk == ';' || tk == '{' || tk == '}' || tk == '(' || tk == ')' || tk == ']' || tk == ',' || tk == ':') return;
}
}
@@ -148,22 +168,23 @@ void expr(int lev)
{
int t, *d;
- if (!tk) { printf("%d: unexpected eof in expression\n", line); exit(-1); }
- else if (tk == Num) { *++e = IMM; *++e = ival; next(); ty = INT; }
- else if (tk == '"') {
+ switch (tk) {
+ case 0: printf("%d: unexpected eof in expression\n", line); exit(-1);
+ case Num: *++e = IMM; *++e = ival; next(); ty = INT; break;
+ case '"':
*++e = IMM; *++e = ival; next();
while (tk == '"') next();
data = (char *)((int)data + sizeof(int) & -sizeof(int)); ty = PTR;
- }
- else if (tk == Sizeof) {
+ break;
+ case Sizeof:
next(); if (tk == '(') next(); else { printf("%d: open paren expected in sizeof\n", line); exit(-1); }
ty = INT; if (tk == Int) next(); else if (tk == Char) { next(); ty = CHAR; }
while (tk == Mul) { next(); ty = ty + PTR; }
if (tk == ')') next(); else { printf("%d: close paren expected in sizeof\n", line); exit(-1); }
*++e = IMM; *++e = (ty == CHAR) ? sizeof(char) : sizeof(int);
ty = INT;
- }
- else if (tk == Id) {
+ break;
+ case Id:
d = id; next();
if (tk == '(') {
next();
@@ -183,8 +204,8 @@ void expr(int lev)
else { printf("%d: undefined variable\n", line); exit(-1); }
*++e = ((ty = d[Type]) == CHAR) ? LC : LI;
}
- }
- else if (tk == '(') {
+ break;
+ case '(':
next();
if (tk == Int || tk == Char) {
t = (tk == Int) ? INT : CHAR; next();
@@ -197,26 +218,27 @@ void expr(int lev)
expr(Assign);
if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
}
- }
- else if (tk == Mul) {
+ break;
+ case Mul:
next(); expr(Inc);
if (ty > INT) ty = ty - PTR; else { printf("%d: bad dereference\n", line); exit(-1); }
*++e = (ty == CHAR) ? LC : LI;
- }
- else if (tk == And) {
+ break;
+ case And:
next(); expr(Inc);
if (*e == LC || *e == LI) --e; else { printf("%d: bad address-of\n", line); exit(-1); }
ty = ty + PTR;
- }
- else if (tk == '!') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = 0; *++e = EQ; ty = INT; }
- else if (tk == '~') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = -1; *++e = XOR; ty = INT; }
- else if (tk == Add) { next(); expr(Inc); ty = INT; }
- else if (tk == Sub) {
+ break;
+ case '!': next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = 0; *++e = EQ; ty = INT; break;
+ case '~': next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = -1; *++e = XOR; ty = INT; break;
+ case Add: next(); expr(Inc); ty = INT; break;
+ case Sub:
next(); *++e = IMM;
if (tk == Num) { *++e = -ival; next(); } else { *++e = -1; *++e = PSH; expr(Inc); *++e = MUL; }
ty = INT;
- }
- else if (tk == Inc || tk == Dec) {
+ break;
+ case Inc:
+ case Dec:
t = tk; next(); expr(Inc);
if (*e == LC) { *e = PSH; *++e = LC; }
else if (*e == LI) { *e = PSH; *++e = LI; }
@@ -225,17 +247,19 @@ void expr(int lev)
*++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);
*++e = (t == Inc) ? ADD : SUB;
*++e = (ty == CHAR) ? SC : SI;
+ break;
+ default: printf("%d: bad expression\n", line); exit(-1);
}
- else { printf("%d: bad expression\n", line); exit(-1); }
while (tk >= lev) { // "precedence climbing" or "Top Down Operator Precedence" method
t = ty;
- if (tk == Assign) {
+ switch (tk) {
+ case Assign:
next();
if (*e == LC || *e == LI) *e = PSH; else { printf("%d: bad lvalue in assignment\n", line); exit(-1); }
expr(Assign); *++e = ((ty = t) == CHAR) ? SC : SI;
- }
- else if (tk == Cond) {
+ break;
+ case Cond:
next();
*++e = BZ; d = ++e;
expr(Assign);
@@ -243,35 +267,36 @@ void expr(int lev)
*d = (int)(e + 3); *++e = JMP; d = ++e;
expr(Cond);
*d = (int)(e + 1);
- }
- else if (tk == Lor) { next(); *++e = BNZ; d = ++e; expr(Lan); *d = (int)(e + 1); ty = INT; }
- else if (tk == Lan) { next(); *++e = BZ; d = ++e; expr(Or); *d = (int)(e + 1); ty = INT; }
- else if (tk == Or) { next(); *++e = PSH; expr(Xor); *++e = OR; ty = INT; }
- else if (tk == Xor) { next(); *++e = PSH; expr(And); *++e = XOR; ty = INT; }
- else if (tk == And) { next(); *++e = PSH; expr(Eq); *++e = AND; ty = INT; }
- else if (tk == Eq) { next(); *++e = PSH; expr(Lt); *++e = EQ; ty = INT; }
- else if (tk == Ne) { next(); *++e = PSH; expr(Lt); *++e = NE; ty = INT; }
- else if (tk == Lt) { next(); *++e = PSH; expr(Shl); *++e = LT; ty = INT; }
- else if (tk == Gt) { next(); *++e = PSH; expr(Shl); *++e = GT; ty = INT; }
- else if (tk == Le) { next(); *++e = PSH; expr(Shl); *++e = LE; ty = INT; }
- else if (tk == Ge) { next(); *++e = PSH; expr(Shl); *++e = GE; ty = INT; }
- else if (tk == Shl) { next(); *++e = PSH; expr(Add); *++e = SHL; ty = INT; }
- else if (tk == Shr) { next(); *++e = PSH; expr(Add); *++e = SHR; ty = INT; }
- else if (tk == Add) {
+ break;
+ case Lor: next(); *++e = BNZ; d = ++e; expr(Lan); *d = (int)(e + 1); ty = INT; break;
+ case Lan: next(); *++e = BZ; d = ++e; expr(Or); *d = (int)(e + 1); ty = INT; break;
+ case Or: next(); *++e = PSH; expr(Xor); *++e = OR; ty = INT; break;
+ case Xor: next(); *++e = PSH; expr(And); *++e = XOR; ty = INT; break;
+ case And: next(); *++e = PSH; expr(Eq); *++e = AND; ty = INT; break;
+ case Eq: next(); *++e = PSH; expr(Lt); *++e = EQ; ty = INT; break;
+ case Ne: next(); *++e = PSH; expr(Lt); *++e = NE; ty = INT; break;
+ case Lt: next(); *++e = PSH; expr(Shl); *++e = LT; ty = INT; break;
+ case Gt: next(); *++e = PSH; expr(Shl); *++e = GT; ty = INT; break;
+ case Le: next(); *++e = PSH; expr(Shl); *++e = LE; ty = INT; break;
+ case Ge: next(); *++e = PSH; expr(Shl); *++e = GE; ty = INT; break;
+ case Shl: next(); *++e = PSH; expr(Add); *++e = SHL; ty = INT; break;
+ case Shr: next(); *++e = PSH; expr(Add); *++e = SHR; ty = INT; break;
+ case Add:
next(); *++e = PSH; expr(Mul);
if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; }
*++e = ADD;
- }
- else if (tk == Sub) {
+ break;
+ case Sub:
next(); *++e = PSH; expr(Mul);
if (t > PTR && t == ty) { *++e = SUB; *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = DIV; ty = INT; }
else if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; *++e = SUB; }
else *++e = SUB;
- }
- else if (tk == Mul) { next(); *++e = PSH; expr(Inc); *++e = MUL; ty = INT; }
- else if (tk == Div) { next(); *++e = PSH; expr(Inc); *++e = DIV; ty = INT; }
- else if (tk == Mod) { next(); *++e = PSH; expr(Inc); *++e = MOD; ty = INT; }
- else if (tk == Inc || tk == Dec) {
+ break;
+ case Mul: next(); *++e = PSH; expr(Inc); *++e = MUL; ty = INT; break;
+ case Div: next(); *++e = PSH; expr(Inc); *++e = DIV; ty = INT; break;
+ case Mod: next(); *++e = PSH; expr(Inc); *++e = MOD; ty = INT; break;
+ case Inc:
+ 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); }
@@ -281,16 +306,17 @@ void expr(int lev)
*++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);
*++e = (tk == Inc) ? SUB : ADD;
next();
- }
- else if (tk == Brak) {
+ break;
+ case Brak:
next(); *++e = PSH; expr(Assign);
if (tk == ']') next(); else { printf("%d: close bracket expected\n", line); exit(-1); }
if (t > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; }
else if (t < PTR) { printf("%d: pointer type expected\n", line); exit(-1); }
*++e = ADD;
*++e = ((ty = t - PTR) == CHAR) ? LC : LI;
+ break;
+ default: printf("%d: compiler error tk=%d\n", line, tk); exit(-1);
}
- else { printf("%d: compiler error tk=%d\n", line, tk); exit(-1); }
}
}
@@ -298,7 +324,8 @@ void stmt()
{
int *a, *b, *d, i;
- if (tk == If) {
+ switch (tk) {
+ case If:
next();
if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
expr(Assign);
@@ -311,8 +338,8 @@ void stmt()
stmt();
}
*b = (int)(e + 1);
- }
- else if (tk == Do) {
+ return;
+ case Do:
next();
a = e + 1;
stmt();
@@ -324,8 +351,8 @@ void stmt()
*++e = BZ; b = ++e;
*++e = JMP; *++e = (int)a;
*b = (int)(e + 1);
- }
- else if (tk == While) {
+ return;
+ case While:
next();
a = e + 1;
if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
@@ -335,8 +362,8 @@ void stmt()
stmt();
*++e = JMP; *++e = (int)a;
*b = (int)(e + 1);
- }
- else if (tk == Switch) {
+ return;
+ case Switch:
next();
if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }
expr(Assign);
@@ -347,47 +374,42 @@ void stmt()
*cas = def ? (int)def : (int)(e + 1); cas = a;
while (brak) { a = (int *)*brak; *brak = (int)(e + 1); brak = a; }
brak = b; def = d;
- }
- else if (tk == Case) {
+ return;
+ case Case:
*++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); }
*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 { printf("%d: colon expected\n", line); exit(-1); }
stmt();
- }
- else if (tk == Break) {
+ return;
+ case Break:
next();
if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
*++e = JMP; *++e = (int)brak; brak = e;
- }
- else if (tk == Default) {
+ return;
+ case Default:
next();
if (tk == ':') next(); else { printf("%d: colon expected\n", line); exit(-1); }
def = e + 1;
stmt();
- }
- else if (tk == Return) {
+ return;
+ case Return:
next();
if (tk != ';') expr(Assign);
*++e = LEV;
if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
- }
- else if (tk == '{') {
+ return;
+ case '{':
next();
while (tk != '}') stmt();
next();
- }
- else if (tk == ';') {
+ return;
+ case ';':
next();
- }
- else {
+ return;
+ default:
expr(Assign);
if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }
}
@@ -470,78 +492,65 @@ int main(int argc, char **argv)
while (tk != ';' && tk != '}') {
ty = bt;
while (tk == Mul) { next(); ty = ty + PTR; }
- if (tk == Brak) {
+ 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();
+ }
next();
- 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; }
+ if (tk != '{') { printf("%d: bad function definition\n", line); return -1; }
+ loc = ++i;
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 == 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 parameter declaration\n", line); return -1; }
- if (id[Class] == Loc) { printf("%d: duplicate parameter definition\n", line); return -1; }
+ 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++;
+ id[HVal] = id[Val]; id[Val] = ++i;
next();
if (tk == ',') next();
}
next();
- 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;
- }
}
- else {
- id[Class] = Glo;
- id[Val] = (int)data;
- data = data + sizeof(int);
+ *++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;
}
}
+ else {
+ id[Class] = Glo;
+ id[Val] = (int)data;
+ data = data + sizeof(int);
+ }
if (tk == ',') next();
}
next();
@@ -569,57 +578,59 @@ int main(int argc, char **argv)
"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
- else if (i == IMM) a = *pc++; // load global address or immediate
- else if (i == JMP) pc = (int *)*pc; // jump
- else if (i == JSR) { *--sp = (int)(pc + 1); pc = (int *)*pc; } // jump to subroutine
- else if (i == BZ) pc = a ? pc + 1 : (int *)*pc; // branch if zero
- else if (i == BNZ) pc = a ? (int *)*pc : pc + 1; // branch if not zero
- else if (i == ENT) { *--sp = (int)bp; bp = sp; sp = sp - *pc++; } // enter subroutine
- else if (i == ADJ) sp = sp + *pc++; // stack adjust
- else if (i == LEV) { sp = bp; bp = (int *)*sp++; pc = (int *)*sp++; } // leave subroutine
- else if (i == LI) a = *(int *)a; // load int
- else if (i == LC) a = *(char *)a; // load char
- else if (i == SI) *(int *)*sp++ = a; // store int
- else if (i == SC) a = *(char *)*sp++ = a; // store char
- else if (i == PSH) *--sp = a; // push
+ 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
- else if (i == OR) a = *sp++ | a;
- else if (i == XOR) a = *sp++ ^ a;
- else if (i == AND) a = *sp++ & a;
- else if (i == EQ) a = *sp++ == a;
- else if (i == NE) a = *sp++ != a;
- else if (i == LT) a = *sp++ < a;
- else if (i == GT) a = *sp++ > a;
- else if (i == LE) a = *sp++ <= a;
- else if (i == GE) a = *sp++ >= a;
- else if (i == SHL) a = *sp++ << a;
- else if (i == SHR) a = *sp++ >> a;
- else if (i == ADD) a = *sp++ + a;
- else if (i == SUB) a = *sp++ - a;
- else if (i == MUL) a = *sp++ * a;
- else if (i == DIV) a = *sp++ / a;
- else if (i == MOD) a = *sp++ % a;
+ 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;
- else if (i == OPEN) a = open((char *)sp[1], *sp);
- else if (i == READ) a = read(sp[2], (char *)sp[1], *sp);
- else if (i == CLOS) a = close(*sp);
- else if (i == PRTF) { t = sp + pc[1]; a = printf((char *)t[-1], t[-2], t[-3], t[-4], t[-5], t[-6]); }
- else if (i == MALC) a = (int)malloc(*sp);
- else if (i == FREE) free((void *)*sp);
- else if (i == MSET) a = (int)memset((char *)sp[2], sp[1], *sp);
- else if (i == MCMP) a = memcmp((char *)sp[2], (char *)sp[1], *sp);
- else if (i == GETC) a = getchar();
- else if (i == PUTS) { t = sp + pc[1]; a = printf("%s", (char *)t[-1]); }
- 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; }
+ 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 EXIT: printf("exit(%d) cycle = %d\n", *sp, cycle); return *sp;
+ default: printf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1;
+ }
}
}
diff --git a/miniany/cc.c b/miniany/cc.c
index ba7ead2..cf4f880 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -183,12 +183,14 @@ int getToken( )
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'y': case 'z':
+ case 'u': case 'v': case 'w': case 'x': case 'y':
+ case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'Y': case 'Z':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z':
case '_':
scanIdent( c );
if( ( t = keyword( ident ) ) ) {