commit 8a0eb2024f8b312ab8ff40423306cd25c74e6fe1
parent 5ebf14dd5565d7acaa934e6e9d7dc6dbec90fc16
Author: m21c <ho*******@gmail.com>
Date: Thu, 16 Sep 2021 21:29:35 +0200
removed haslhs-param from gettok()
Diffstat:
| M | compiler.c | | | 217 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 122 insertions(+), 95 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -108,8 +108,7 @@ typedef enum Kind {
#define isoperator(kind) ((kind) >= OSTART && (kind) < ASTART)
#define isastnode(kind) ((kind) >= ASTART && (kind) < MAXKINDS)
-bool isatomnode(Kind kind)
-{
+bool isatomnode(Kind kind) {
return kind == 'I' || kind == ADECLREF || kind == 'N' || kind == 'S' ||
kind == 'C';
}
@@ -337,7 +336,6 @@ typedef struct Source {
int lastindent, lastkind;
Node tok;
-
/* environment */
Env *headenv, *currenv;
@@ -954,7 +952,7 @@ error(SrcLoc *loc, const char *fmt, ...) {
((indent) + (source)->tabwidth - ((indent) % (source)->tabwidth))
static int
-gettok(Source *source, bool haslhs) {
+gettok(Source *source) {
register int c0 = (uchar) source->line[source->currloc.column];
static bool hasnewline = false;
@@ -1310,17 +1308,8 @@ skipwhite:
case '}':
case ']':
case ')':
- goto joindelim;
-
case '[':
- if (haslhs)
- c0 = OARRAY;
- goto joindelim;
-
case '(':
- if (haslhs)
- c0 = OCALL;
- joindelim:
++source->currloc.column;
return source->tok.kind = c0;
}
@@ -1338,7 +1327,7 @@ skipwhite:
goto joinop;
case '*':
- source->tok.kind = select('=', OMULA, (haslhs ? OMUL : OLPTR));
+ source->tok.kind = select('=', OMULA, OMUL);
goto joinop;
case '/':
@@ -1366,20 +1355,15 @@ skipwhite:
goto joinop;
case '&':
- source->tok.kind = select('=', OANDA, select('&', OLAND,
- /*(haslhs ? OBAND : ORPTR)*/ OBAND));
+ source->tok.kind = select('=', OANDA, select('&', OLAND, OBAND));
goto joinop;
case '+':
- source->tok.kind = select('=', OADDA, select('+',
- (haslhs ? OSUFINC : OINC),
- (haslhs ? OADD : OPLUS)));
+ source->tok.kind = select('=', OADDA, select('+', OSUFINC, OADD));
goto joinop;
case '-':
- source->tok.kind = select('=', OSUBA, select('-',
- (haslhs ? OSUFDEC : ODEC),
- (haslhs ? OSUB : OMINUS)));
+ source->tok.kind = select('=', OSUBA, select('-', OSUFDEC, OSUB));
goto joinop;
case '|':
@@ -1411,8 +1395,47 @@ skipwhite:
}
#define skipnewline(source) \
- ((source)->tok.kind == '\n' ? (void) gettok(source, false) : (void) 0)
+ ((source)->tok.kind == '\n' ? (void) gettok(source) : (void) 0)
+static Kind
+getunary(Source *source) {
+ Kind kind = source->tok.kind;
+
+ if (getprec(kind) == PUNARY)
+ return kind;
+
+ switch (kind) {
+ case OMUL: return OLPTR;
+ /* case OBAND: return ORPTR; */
+ case OADD: return OPLUS;
+ case OSUB: return OMINUS;
+ case OSUFINC: return OINC;
+ case OSUFDEC: return ODEC;
+ default: return 0;
+ }
+}
+
+static Kind
+getunarysuffix(Source *source) {
+ Kind kind = source->tok.kind;
+
+ if (getprec(kind) == PUNSUF)
+ return kind;
+
+ /* TODO(m21c): check if this is correct: */
+ switch (source->lastkind) {
+ case '\n': case ';':
+ return 0;
+ default:
+ break;
+ }
+
+ switch (kind) {
+ case '(': return OCALL;
+ case '[': return OARRAY;
+ default: return 0;
+ }
+}
/* - ast-node - */
@@ -1582,8 +1605,7 @@ popenv(Source *source) {
}
static void
-deferfuncenv(Source *source, int keydeclinfunc)
-{
+deferfuncenv(Source *source, int keydeclinfunc) {
Env *env, *funcenv = NULL;
for (env = source->currenv; env; env = env->below) {
@@ -1734,7 +1756,7 @@ defertypedeclaration(Source *source, int key) {
(&(source)->tok.loc)
static bool
-expect(Source *source, int kind, bool nexthaslhs, const char *fmt, ...) {
+expect(Source *source, int kind, const char *fmt, ...) {
va_list ap;
int line = source->tok.loc.line;
@@ -1752,7 +1774,7 @@ expect(Source *source, int kind, bool nexthaslhs, const char *fmt, ...) {
return false;
}
- gettok(source, nexthaslhs);
+ gettok(source);
return true;
}
@@ -1804,7 +1826,7 @@ qualifiers(Source *source, int allowmask) {
flags |= f & allowmask & mask;
mask &= m;
- gettok(source, false);
+ gettok(source);
}
finish:
@@ -1834,7 +1856,7 @@ checkend(Source *source, bool hastail, int needindent,
const char *expecterrmsg)
{
if (getkind(source) == '\n') {
- gettok(source, false);
+ gettok(source);
if (getkind(source) == ';')
error(getloc(source), expecterrmsg);
}
@@ -1843,7 +1865,7 @@ checkend(Source *source, bool hastail, int needindent,
return true;
if (getkind(source) == ';') {
- gettok(source, false);
+ gettok(source);
/* NOTE(m21c): used for REPL. it allows having
* semicolons on line-endings and nultiple
@@ -1941,23 +1963,23 @@ gettype(Source *source, Type *basetype) {
advance:
flags = qualifiers(source, QTYPE);
- if (getkind(source) == '[' || getkind(source) == OARRAY) {
+ if (getkind(source) == '[') {
Type *tmp = maketype(getloc(source), prim + TARRAY, basetype);
basetype = tmp;
- gettok(source, false);
+ gettok(source);
if (source->tok.kind != ']')
basetype->u.val = readexpr(source, PASSIGN);
- expect(source, ']', false, "expect ']'");
+ expect(source, ']', "expect ']'");
goto advance;
}
- if (getkind(source) == OLPTR || getkind(source) == OMUL) {
+ if (getkind(source) == OMUL) {
Type *tmp = maketype(getloc(source), prim + TPTR, basetype);
basetype = tmp;
- gettok(source, false);
+ gettok(source);
goto advance;
}
@@ -1991,7 +2013,7 @@ declaration(Source *source, Type *ty) {
if (getkind(source) == 'I') {
decl = makedecl(source, source->tok.u.key, DVAR);
decl->type = ty;
- gettok(source, true);
+ gettok(source);
/* module for variable */
} else if (getkind(source) == 'T') {
@@ -1999,7 +2021,7 @@ declaration(Source *source, Type *ty) {
if (getkind(source) == ODISP || getkind(source) == ':') {
selfparam = getkind(source) == ':';
- gettok(source, false);
+ gettok(source);
} else {
error(getloc(source), "expected '.' or ':'");
}
@@ -2010,7 +2032,7 @@ declaration(Source *source, Type *ty) {
/* variable name */
if (getkind(source) == 'I') {
- gettok(source, true);
+ gettok(source);
} else {
error(getloc(source), "expected identifier");
}
@@ -2023,12 +2045,12 @@ declaration(Source *source, Type *ty) {
}
/* function declaration */
- if (getkind(source) == OCALL) {
+ if (getkind(source) == '(') {
Env *functionenv = NULL;
Node *body = NULL;
/* function params */
- gettok(source, false);
+ gettok(source);
if (getkind(source) != ')') {
Decl *param;
Node *paramlist;
@@ -2046,7 +2068,7 @@ declaration(Source *source, Type *ty) {
param->kind = DPARAM;
}
}
- expect(source, ')', true, "expected ')'");
+ expect(source, ')', "expected ')'");
/* function body */
if (getkind(source) != OASS) {
@@ -2054,7 +2076,7 @@ declaration(Source *source, Type *ty) {
/* function init (body defined by assigment) */
} else if (getkind(source) == OASS) {
- gettok(source, false);
+ gettok(source);
functionenv->kind = SFUNCTION;
body = readexpr(source, PASSIGN);
@@ -2088,7 +2110,7 @@ declaration(Source *source, Type *ty) {
/* variable init */
if (getkind(source) == OASS) {
- gettok(source, false);
+ gettok(source);
assert(decl);
decl->content = readexpr(source, PASSIGN);
@@ -2116,7 +2138,7 @@ readident(Source *source, int flags) {
int key = source->tok.u.key;
decl = finddeclaration(source, source->currenv, source->tok.u.key);
- gettok(source, true);
+ gettok(source);
if (source->currenv->kind == SRECORD) {
int kind = getkind(source);
@@ -2162,11 +2184,11 @@ readrecord(Source *source, int indent, bool isunion) {
indent = source->lastindent;
recordnode = makenode(&source->tok, NULL);
recordnode->kind = getkind(source);
- gettok(source, false);
+ gettok(source);
if (getkind(source) == 'I') {
recordnode->lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
} else {
error(getloc(source), "expected identifier");
}
@@ -2197,11 +2219,11 @@ readatom(Source *source, int flags) {
lhs = makenode(&source->tok, source->lastis->lhs);
}
- gettok(source, false);
+ gettok(source);
lhs->kind = 'O';
if (getkind(source) == KNOT)
- gettok(source, false), lhs->kind = ONEQ;
+ gettok(source), lhs->kind = ONEQ;
else
lhs->kind = OEQU;
@@ -2210,9 +2232,13 @@ readatom(Source *source, int flags) {
}
/* unary prefix operators */
- if (getprec(getkind(source)) == PUNARY) {
+ if (getunary(source)) {
lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+
+ /* TODO(m21c): remove redundant function-call */
+ lhs->kind = getunary(source);
+
+ gettok(source);
lhs->lhs = readatom(source, 0);
return lhs;
}
@@ -2229,9 +2255,8 @@ readatom(Source *source, int flags) {
/* actual atom */
switch (getkind(source)) {
- case OCALL:
case '(':
- gettok(source, false);
+ gettok(source);
if (getkind(source) == '\n') {
/* FIXME(m21c): stmtlist should ignore indentation in
@@ -2246,7 +2271,7 @@ readatom(Source *source, int flags) {
/* NOTE(m21c): expecting that the type is also set in lhs->type */
lhs->kind = OCAST;
skipnewline(source);
- expect(source, ')', true, "expected ')'");
+ expect(source, ')', "expected ')'");
lhs->lhs = readatom(source, 0);
break;
@@ -2262,7 +2287,7 @@ readatom(Source *source, int flags) {
/* deletenode(lhs); */
skipnewline(source);
- expect(source, ')', true, "expected ')'");
+ expect(source, ')', "expected ')'");
lhs = declaration(source, gettype(source, ty));
@@ -2273,7 +2298,7 @@ readatom(Source *source, int flags) {
skipnewline(source);
}
- expect(source, ')', true, "expected ')'");
+ expect(source, ')', "expected ')'");
break;
case 'I':
@@ -2283,7 +2308,7 @@ readatom(Source *source, int flags) {
case 'T':
do {
Type *type = source->tok.type;
- gettok(source, false);
+ gettok(source);
lhs = declaration(source, gettype(source, type));
} while (0);
break;
@@ -2292,7 +2317,7 @@ readatom(Source *source, int flags) {
case 'S':
case 'C':
lhs = makenode(&source->tok, NULL);
- gettok(source, true);
+ gettok(source);
if (flags & QCONST) {
/* TODO(m21c): const - conversion */
@@ -2306,7 +2331,7 @@ readatom(Source *source, int flags) {
lhs->kind = 'N';
lhs->type = prim + TBOOL;
lhs->u.u = (uint64_t) (getkind(source) == KTRUE);
- gettok(source, true);
+ gettok(source);
break;
@@ -2315,7 +2340,7 @@ readatom(Source *source, int flags) {
lhs->kind = 'N';
lhs->type = maketype(&source->tok.loc, prim + TPTR, prim + TVOID);
lhs->u.u = (uint64_t) (getkind(source) == KTRUE);
- gettok(source, true);
+ gettok(source);
break;
@@ -2326,7 +2351,7 @@ readatom(Source *source, int flags) {
case KNOT:
lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
lhs->kind = OLNOT;
lhs->lhs = readexpr(source, PRELAT);
@@ -2336,14 +2361,14 @@ readatom(Source *source, int flags) {
case KCONTINUE:
lhs = makenode(&source->tok, NULL);
lhs->kind = getkind(source);
- gettok(source, true);
+ gettok(source);
if (getkind(source) == ':') {
- gettok(source, false);
+ gettok(source);
skipnewline(source);
if (getkind(source) == 'I') {
lhs->lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
} else {
error(getloc(source), "expected identifier");
}
@@ -2353,15 +2378,15 @@ readatom(Source *source, int flags) {
case KRETURN:
lhs = makenode(&source->tok, NULL);
- gettok(source, true);
+ gettok(source);
lhs->kind = ARETURN;
if (getkind(source) == ':') {
- gettok(source, false);
+ gettok(source);
skipnewline(source);
if (getkind(source) == 'I') {
lhs->lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
} else {
error(getloc(source), "expected identifier");
}
@@ -2375,7 +2400,7 @@ readatom(Source *source, int flags) {
case KDO:
indent = source->lastindent;
lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
lhs->kind = ADO;
lhs->lhs = stmtlist(source, indent, SSCOPE);
@@ -2384,13 +2409,13 @@ readatom(Source *source, int flags) {
case KLOOP:
indent = source->lastindent;
lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
lhs->kind = ALOOP;
lhs->lhs = stmtlist(source, indent, SSCOPE);
if (getkind(source) == KUNTIL && source->lastindent >= indent) {
lhs->kind = ALOOPUNTIL;
- gettok(source, false);
+ gettok(source);
lhs->u.payload = readexpr(source, POR);
}
@@ -2402,7 +2427,7 @@ readatom(Source *source, int flags) {
case KWHILE:
indent = source->lastindent;
lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
lhs->kind = AWHILE;
lhs->u.payload = readexpr(source, POR);
lhs->lhs = stmtlist(source, indent, SSCOPE);
@@ -2412,18 +2437,18 @@ readatom(Source *source, int flags) {
case KIF:
indent = source->lastindent;
lhs = makenode(&source->tok, NULL);
- gettok(source, false);
+ gettok(source);
lhs->kind = AIF;
lhs->u.payload = readexpr(source, POR);
skipnewline(source);
if (getkind(source) == 'I' && source->tok.u.key == auxthen)
- gettok(source, false);
+ gettok(source);
lhs->lhs = stmtlist(source, indent, SSCOPE);
joinelse:
if (getkind(source) == KELSE && source->lastindent >= indent) {
- gettok(source, false);
+ gettok(source);
lhs->rhs = stmtlist(source, indent, SSCOPE);
}
@@ -2433,52 +2458,55 @@ readatom(Source *source, int flags) {
joinerror:
error(getloc(source), "expected expression");
lhs = makenode(&source->tok, NULL);
- gettok(source, true);
+ gettok(source);
}
/* unary postfix operators */
- while (getprec(getkind(source)) == PUNSUF) {
+ while (getunarysuffix(source)) {
lhs = makenode(&source->tok, lhs);
+ /* TODO(m21c): remove redundant function-call */
+ lhs->kind = getunarysuffix(source);
+
if (getkind(source) == ODISP) {
- gettok(source, false);
+ gettok(source);
skipnewline(source);
if (getkind(source) != 'I')
error(getloc(source), "expected identifier");
lhs->rhs = makenode(&source->tok, NULL);
- } else if (getkind(source) == OCALL) {
- gettok(source, false);
+ } else if (getkind(source) == '(') {
+ gettok(source);
if (getkind(source) != ')') {
lhs->rhs = exprlist(source, false, NULL);
source->lastis = savedis;
}
- expect(source, ')', true, "expected ')'");
+ expect(source, ')', "expected ')'");
continue;
- } else if (getkind(source) == OARRAY) {
- gettok(source, false);
+ } else if (getkind(source) == '[') {
+ gettok(source);
lhs->rhs = exprlist(source, false, NULL);
source->lastis = savedis;
- expect(source, ']', true, "expected ']'");
+ expect(source, ']', "expected ']'");
continue;
}
- gettok(source, true);
+ gettok(source);
}
/* 'not'-suffix for the binary 'is'-operator (i.e. 'is not') */
while (getkind(source) == KIS) {
lhs = makenode(&source->tok, lhs);
- gettok(source, false);
+ gettok(source);
lhs->kind = 'O';
if (getkind(source) == KNOT)
- gettok(source, false), lhs->kind = ONEQ;
+ gettok(source), lhs->kind = ONEQ;
else
lhs->kind = OEQU;
@@ -2496,7 +2524,7 @@ readexpr(Source *source, int minprec) {
/* only binary expr */
while (getprec(getkind(source)) >= minprec) {
lhs = makenode(&source->tok, lhs);
- gettok(source, false);
+ gettok(source);
skipnewline(source);
lhs->rhs = readexpr(
@@ -2600,7 +2628,7 @@ exprlist(Source *source, bool isparam, Type *paramtype) {
lhs = makenode(&source->tok, lhs);
lhs->kind = ACOMMA;
- gettok(source, false);
+ gettok(source);
if (getkind(source) == 'I' && isdeclaration) {
assert(paramtype);
@@ -2718,8 +2746,7 @@ static Node *
conv(Node *node);
static Node *
-autoref(Type *ty, Node *node)
-{
+autoref(Type *ty, Node *node) {
int numderefs = 0, i;
Node *n;
Type *t;
@@ -4071,9 +4098,9 @@ initsource(Source *source, const char *filename, FILE *file) {
source->implicitenv = envbuf + envtop++;
- gettok(source, false);
+ gettok(source);
if (getkind(source) == '\n')
- gettok(source, false);
+ gettok(source);
}
@@ -4142,15 +4169,15 @@ main(int argc, char **argv) {
highlight(stdout, HLNONE);
source->handlereplprompt = false;
}
- gettok(source, false);
+ gettok(source);
} else if (getkind(source) == ';') {
- gettok(source, false);
+ gettok(source);
}
if (source->lastkind != ';' && source->lastkind != '\n') {
error(getloc(source), "expected new line");
while (getkind(source) != ';' && getkind(source) != '\n' && getkind(source) != 0)
- gettok(source, false);
+ gettok(source);
if (source->filein == stdin) {
highlight(stdout, HLPROMPT);
@@ -4160,7 +4187,7 @@ main(int argc, char **argv) {
}
if (getkind(source) != 0)
- gettok(source, false);
+ gettok(source);
}
}