commit 503dcb4b282301c142050c5bbcfe955d29fe8bcf
parent 18f42c96e78f5b8ee31e00d09f244892bf4bb009
Author: m21c <ho*******@gmail.com>
Date: Thu, 1 Apr 2021 20:44:28 +0200
changed node kind - layout + improved .gitignore
Diffstat:
| M | .gitignore | | | 3 | +++ |
| M | aria.c | | | 824 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
2 files changed, 418 insertions(+), 409 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -5,3 +5,5 @@ test/*
debug*.cmd
debug*.sh
+
+*.exe
+\ No newline at end of file
diff --git a/aria.c b/aria.c
@@ -211,43 +211,6 @@ advance:
/* - lexer - */
-enum {
- OSUFINC, OSUFDEC, OARRAY, OCALL, ODISP,
-
- ODEREF, OINC, ODEC, OBNOT, OLNOT, OFLIP, OADDR, OPLUS, OMINUS,
- OCAST,
-
- OMUL, ODIV, OMOD, OLSH, OARSH, ORSH, OBAND,
-
- OADD, OSUB, OBOR, OXOR,
-
- ORANGE,
-
- OLEQ, OLET, OGEQ, OGRT, ONEQ, OEQU, OIDENT,
-
- OLAND,
-
- OLOR,
-
- OASS,
- OMULA, ODIVA, OMODA, OLSHA, OARSHA, ORSHA, OANDA,
- OADDA, OSUBA, OORA, OXORA,
-};
-
-enum {
- PUNSUF = 9,
- PUNARY = 8,
- PMUL = 7,
- PADD = 6,
- PRANGE = 5,
- PRELAT = 4,
- PAND = 3,
- POR = 2,
- PASSIGN = 1,
-
- PSTART = 0
-};
-
typedef
struct Op {
const char *debugstr;
@@ -258,67 +221,6 @@ struct Op {
bool rassoc;
} Op;
-const Op ops[] = {
- [OSUFINC] = {"unary++", "++", 1, PUNSUF, false},
- [OSUFDEC] = {"unary--", "++", 1, PUNSUF, false},
- [OARRAY] = {"unary[]", "", 1, PUNSUF, false},
- [OCALL] = {"unary()", "", 1, PUNSUF, false},
- [ODISP] = {"unary._", ".", 1, PUNSUF, false},
-
- [ODEREF] = {"*unary", "*", 1, PUNARY, true},
- [OINC] = {"++unary", "++", 1, PUNARY, true},
- [ODEC] = {"--unary", "--", 1, PUNARY, true},
- [OBNOT] = {"~unary", "~", 1, PUNARY, true},
- [OLNOT] = {"!unary", "!", 1, PUNARY, true},
- [OFLIP] = {"~=unary", "~=", 1, PUNARY, true},
- [OADDR] = {"&unary", "&", 1, PUNARY, true},
- [OPLUS] = {"+unary", "+", 1, PUNARY, true},
- [OMINUS] = {"-unary", "-", 1, PUNARY, true},
- [OCAST] = {"(type) unary", "", 1, PUNARY, true},
-
- [OMUL] = {"*", "*", 2, PMUL, false},
- [ODIV] = {"/", "/", 2, PMUL, false},
- [OMOD] = {"%", "%", 2, PMUL, false},
- [OLSH] = {"<<", "<<", 2, PMUL, false},
- [OARSH] = {">>>", ">>>", 2, PMUL, false},
- [ORSH] = {">>", ">>", 2, PMUL, false},
- [OBAND] = {"&", "&", 2, PMUL, false},
-
- [OADD] = {"+", "+", 2, PADD, false},
- [OSUB] = {"-", "-", 2, PADD, false},
- [OBOR] = {"|", "|", 2, PADD, false},
- [OXOR] = {"^", "^", 2, PADD, false},
-
- [ORANGE] = {"..", "..", 2, PRANGE, false},
-
- [OLEQ] = {"<=", "<=", 2, PRELAT, false},
- [OLET] = {"<", "<", 2, PRELAT, false},
- [OGEQ] = {">=", ">=", 2, PRELAT, false},
- [OGRT] = {">", ">", 2, PRELAT, false},
- [ONEQ] = {"!=", "!=", 2, PRELAT, false},
- [OEQU] = {"==", "==", 2, PRELAT, false},
- [OIDENT] = {"===", "===", 2, PRELAT, false},
-
- [OLAND] = {"&&", "&&", 2, PAND, false},
-
- [OLOR] = {"||", "||", 2, POR, false},
-
- [OASS] = {"=", "=", 2, PASSIGN, true},
- [OMULA] = {"*=", "*=", 2, PASSIGN, true},
- [ODIVA] = {"/=", "/=", 2, PASSIGN, true},
- [OMODA] = {"%=", "%=", 2, PASSIGN, true},
- [OLSHA] = {"<<=", "<<=", 2, PASSIGN, true},
- [OARSHA] = {">>>=", ">>>=", 2, PASSIGN, true},
- [ORSHA] = {">>=", ">>=", 2, PASSIGN, true},
- [OANDA] = {"&=", "&=", 2, PASSIGN, true},
- [OADDA] = {"+=", "+=", 2, PASSIGN, true},
- [OSUBA] = {"-=", "-=", 2, PASSIGN, true},
- [OORA] = {"|=", "|=", 2, PASSIGN, true},
- [OXORA] = {"^=", "^=", 2, PASSIGN, true}
-};
-
-#define lengthof(array) ((int) sizeof(array) / (int) sizeof (*(array)))
-
typedef
struct Keyword {
const char *str;
@@ -332,7 +234,33 @@ struct Keyword {
} Keyword;
enum {
- KVOID, KBOOL,
+ PUNSUF = 10,
+ PUNARY = 9,
+ PMUL = 8,
+ PADD = 7,
+ PRANGE = 6,
+ PRELAT = 5,
+ PAND = 4,
+ POR = 3,
+ PASSIGN = 2,
+
+ PSTART = 1
+};
+
+#define KSTART 0x100
+#define OSTART 0x200
+#define ASTART 0x300
+
+typedef enum Kind {
+ ANNOT = '@',
+ SEMIDELIM = ';', COMMADELIM = ',', COLONDELIM = ':', LCURLDELIM = '{',
+ RCURLDELIM = ']', RSQRDELIM = ']', RPARDELIM = ')',
+ IDENT = 'I',
+ NUMBER = 'N',
+ STRING = 'S',
+
+ KVOID = KSTART,
+ KBOOL,
KU8, KS8, KU16, KS16, KU32, KS32, KU64, KS64,
@@ -354,7 +282,196 @@ enum {
KBREAK, KCONTINUE, KGOTO, KRETURN,
KIF, KELSE, KCASE, KOF, KDO,
- KFOR, KLOOP, KWHILE, KUNTIL
+ KFOR, KLOOP, KWHILE, KUNTIL,
+
+ OSUFINC = OSTART,
+ OSUFDEC, OARRAY, OCALL, ODISP,
+
+ ODEREF, OINC, ODEC, OBNOT, OLNOT, OFLIP, OADDR, OPLUS, OMINUS,
+ OCAST,
+
+ OMUL, ODIV, OMOD, OLSH, OARSH, ORSH, OBAND,
+
+ OADD, OSUB, OBOR, OXOR,
+
+ ORANGE,
+
+ OLEQ, OLET, OGEQ, OGRT, ONEQ, OEQU, OIDENT,
+
+ OLAND,
+
+ OLOR,
+
+ OASS,
+ OMULA, ODIVA, OMODA, OLSHA, OARSHA, ORSHA, OANDA,
+ OADDA, OSUBA, OORA, OXORA,
+
+ ASTMT = ASTART,
+ ADO, ADECL, ADECLREF, ALOOP, ALOOPUNTIL, AWHILE, AFOR, ACONTINUE,
+ ABREAK, ASCOPE, ARETURN, AGOTO, ALABEL, AIF, ASWITCH, ACASE,
+
+ MAXKINDS
+} Kind;
+
+const char *astnames[] = {
+ "Statement",
+ "Do",
+ "Declaration",
+ "Declaration Reference",
+ "Loop",
+ "Loop-Until",
+ "While",
+ "For",
+ "Continue",
+ "Break",
+ "Scope",
+ "Return",
+ "Goto",
+ "Label",
+ "If",
+ "Switch",
+ "Case"
+};
+
+/*
+Node kinds:
+ '@' - Annotation
+ ';' ',' ':' '{' '}' ']' ')' - Delimiters
+ 'A' - Statement
+ 'I' - Identifier
+ 'K' - Keyword
+ 'N' - Number-literal
+ 'O' - Operator
+ 'S' - String-literal
+*/
+
+#define opentry(numops, rassoc, prec) \
+ ((uint8_t) ( ((numops) << 6) | ((rassoc) << 5) | (prec) ))
+
+const uint8_t opinfo[] = {
+ [0] = 0,
+
+ [OSUFINC] = opentry(1, false, PUNSUF),
+ [OSUFDEC] = opentry(1, false, PUNSUF),
+ [OARRAY] = opentry(1, false, PUNSUF),
+ [OCALL] = opentry(1, false, PUNSUF),
+ [ODISP] = opentry(1, false, PUNSUF),
+
+ [ODEREF] = opentry(1, true, PUNARY),
+ [OINC] = opentry(1, true, PUNARY),
+ [ODEC] = opentry(1, true, PUNARY),
+ [OBNOT] = opentry(1, true, PUNARY),
+ [OLNOT] = opentry(1, true, PUNARY),
+ [OFLIP] = opentry(1, true, PUNARY),
+ [OADDR] = opentry(1, true, PUNARY),
+ [OPLUS] = opentry(1, true, PUNARY),
+ [OMINUS] = opentry(1, true, PUNARY),
+ [OCAST] = opentry(1, true, PUNARY),
+
+ [OMUL] = opentry(2, false, PMUL),
+ [ODIV] = opentry(2, false, PMUL),
+ [OMOD] = opentry(2, false, PMUL),
+ [OLSH] = opentry(2, false, PMUL),
+ [OARSH] = opentry(2, false, PMUL),
+ [ORSH] = opentry(2, false, PMUL),
+ [OBAND] = opentry(2, false, PMUL),
+
+ [OADD] = opentry(2, false, PADD),
+ [OSUB] = opentry(2, false, PADD),
+ [OBOR] = opentry(2, false, PADD),
+ [OXOR] = opentry(2, false, PADD),
+
+ [ORANGE] = opentry(2, false, PRANGE),
+
+ [OLEQ] = opentry(2, false, PRELAT),
+ [OLET] = opentry(2, false, PRELAT),
+ [OGEQ] = opentry(2, false, PRELAT),
+ [OGRT] = opentry(2, false, PRELAT),
+ [ONEQ] = opentry(2, false, PRELAT),
+ [OEQU] = opentry(2, false, PRELAT),
+ [OIDENT] = opentry(2, false, PRELAT),
+
+ [OLAND] = opentry(2, false, PAND),
+
+ [OLOR] = opentry(2, false, POR),
+
+ [OASS] = opentry(2, true, PASSIGN),
+ [OMULA] = opentry(2, true, PASSIGN),
+ [ODIVA] = opentry(2, true, PASSIGN),
+ [OMODA] = opentry(2, true, PASSIGN),
+ [OLSHA] = opentry(2, true, PASSIGN),
+ [OARSHA] = opentry(2, true, PASSIGN),
+ [ORSHA] = opentry(2, true, PASSIGN),
+ [OANDA] = opentry(2, true, PASSIGN),
+ [OADDA] = opentry(2, true, PASSIGN),
+ [OSUBA] = opentry(2, true, PASSIGN),
+ [OORA] = opentry(2, true, PASSIGN),
+ [OXORA] = opentry(2, true, PASSIGN),
+
+ [MAXKINDS] = 0
+};
+
+#define getnumops(kind) (opinfo[kind] >> 6)
+#define israssoc(kind) ((opinfo[kind] >> 5) & 0x01)
+#define getprec(kind) ((opinfo[kind] & 0x2f))
+
+const Op ops[] = {
+ [OSUFINC - OSTART] = {"unary++", "++", 1, PUNSUF, false},
+ [OSUFDEC - OSTART] = {"unary--", "++", 1, PUNSUF, false},
+ [OARRAY - OSTART] = {"unary[]", "", 1, PUNSUF, false},
+ [OCALL - OSTART] = {"unary()", "", 1, PUNSUF, false},
+ [ODISP - OSTART] = {"unary._", ".", 1, PUNSUF, false},
+
+ [ODEREF - OSTART] = {"*unary", "*", 1, PUNARY, true},
+ [OINC - OSTART] = {"++unary", "++", 1, PUNARY, true},
+ [ODEC - OSTART] = {"--unary", "--", 1, PUNARY, true},
+ [OBNOT - OSTART] = {"~unary", "~", 1, PUNARY, true},
+ [OLNOT - OSTART] = {"!unary", "!", 1, PUNARY, true},
+ [OFLIP - OSTART] = {"~=unary", "~=", 1, PUNARY, true},
+ [OADDR - OSTART] = {"&unary", "&", 1, PUNARY, true},
+ [OPLUS - OSTART] = {"+unary", "+", 1, PUNARY, true},
+ [OMINUS - OSTART] = {"-unary", "-", 1, PUNARY, true},
+ [OCAST - OSTART] = {"(type) unary", "", 1, PUNARY, true},
+
+ [OMUL - OSTART] = {"*", "*", 2, PMUL, false},
+ [ODIV - OSTART] = {"/", "/", 2, PMUL, false},
+ [OMOD - OSTART] = {"%", "%", 2, PMUL, false},
+ [OLSH - OSTART] = {"<<", "<<", 2, PMUL, false},
+ [OARSH - OSTART] = {">>>", ">>>", 2, PMUL, false},
+ [ORSH - OSTART] = {">>", ">>", 2, PMUL, false},
+ [OBAND - OSTART] = {"&", "&", 2, PMUL, false},
+
+ [OADD - OSTART] = {"+", "+", 2, PADD, false},
+ [OSUB - OSTART] = {"-", "-", 2, PADD, false},
+ [OBOR - OSTART] = {"|", "|", 2, PADD, false},
+ [OXOR - OSTART] = {"^", "^", 2, PADD, false},
+
+ [ORANGE - OSTART] = {"..", "..", 2, PRANGE, false},
+
+ [OLEQ - OSTART] = {"<=", "<=", 2, PRELAT, false},
+ [OLET - OSTART] = {"<", "<", 2, PRELAT, false},
+ [OGEQ - OSTART] = {">=", ">=", 2, PRELAT, false},
+ [OGRT - OSTART] = {">", ">", 2, PRELAT, false},
+ [ONEQ - OSTART] = {"!=", "!=", 2, PRELAT, false},
+ [OEQU - OSTART] = {"==", "==", 2, PRELAT, false},
+ [OIDENT - OSTART] = {"===", "===", 2, PRELAT, false},
+
+ [OLAND - OSTART] = {"&&", "&&", 2, PAND, false},
+
+ [OLOR - OSTART] = {"||", "||", 2, POR, false},
+
+ [OASS - OSTART] = {"=", "=", 2, PASSIGN, true},
+ [OMULA - OSTART] = {"*=", "*=", 2, PASSIGN, true},
+ [ODIVA - OSTART] = {"/=", "/=", 2, PASSIGN, true},
+ [OMODA - OSTART] = {"%=", "%=", 2, PASSIGN, true},
+ [OLSHA - OSTART] = {"<<=", "<<=", 2, PASSIGN, true},
+ [OARSHA - OSTART] = {">>>=", ">>>=", 2, PASSIGN, true},
+ [ORSHA - OSTART] = {">>=", ">>=", 2, PASSIGN, true},
+ [OANDA - OSTART] = {"&=", "&=", 2, PASSIGN, true},
+ [OADDA - OSTART] = {"+=", "+=", 2, PASSIGN, true},
+ [OSUBA - OSTART] = {"-=", "-=", 2, PASSIGN, true},
+ [OORA - OSTART] = {"|=", "|=", 2, PASSIGN, true},
+ [OXORA - OSTART] = {"^=", "^=", 2, PASSIGN, true}
};
Keyword keywords[] = {
@@ -416,6 +533,8 @@ Keyword keywords[] = {
{"until", 0, false, 0, false, 0},
};
+#define lengthof(array) ((int) sizeof(array) / (int) sizeof (*(array)))
+
#define KEYWORD_MAP_SIZE 128
const char *keywordkeys[KEYWORD_MAP_SIZE];
int keywordvals[KEYWORD_MAP_SIZE];
@@ -587,88 +706,21 @@ getstringkey(StringMap *map, const char *str, int n) {
#define getstring(map, key) ((map).vals[(key) - 1].str)
#define getlength(map, key) ((map).vals[(key) - 1].len)
-enum {
- ASTMT,
- ADO,
- ADECL,
- ADECLREF,
- ALOOP,
- ALOOPUNTIL,
- AWHILE,
- AFOR,
- ACONTINUE,
- ABREAK,
- ASCOPE,
- ARETURN,
- AGOTO,
- ALABEL,
- AIF,
- ASWITCH,
- ACASE
-};
-
-const char *astnames[] = {
- "Statement",
- "Do",
- "Declaration",
- "Declaration Reference",
- "Loop",
- "Loop-Until",
- "While",
- "For",
- "Continue",
- "Break",
- "Scope",
- "Return",
- "Goto",
- "Label",
- "If",
- "Switch",
- "Case"
-};
-
-/*
-Node kinds:
- '@' - Annotation
- ';' ',' ':' '{' '}' ']' ')' - Delimiters
- 'A' - Statement
- 'I' - Identifier
- 'K' - Keyword
- 'N' - Number-literal
- 'O' - Operator
- 'S' - String-literal
-*/
struct Node {
- char kind;
+ Kind kind;
Type *type;
union {
- int id;
+ int key;
double d;
uint64_t u;
int64_t s;
- struct {
- int id;
- Node *cond;
- } cond;
-
- struct {
- int id;
- Node *init;
- } decl;
-
- struct {
- int id;
- Decl *ref;
- } declref;
-
- struct {
- int id;
- Env *env;
- } scope;
+ Node *payload;
+ Decl *declref;
+ Env *env;
} u;
Node *lhs, *rhs;
@@ -776,21 +828,20 @@ skipwhite:
c0 = line[++currcol];
keyword = getkeyword(line + lastcol, currcol - lastcol);
- if (tok.kind != '@' && keyword >= 0 &&
- (tok.kind != 'O' || tok.u.id != ODISP)) {
+ if (tok.kind != '@' && keyword >= 0 && tok.kind != ODISP) {
if (keywords[keyword].isop) {
- tok.u.id = keywords[keyword].opid;
- return tok.kind = 'O';
+ return tok.kind = keywords[keyword].opid;
} else if (keywords[keyword].istype) {
+ /*
tok.u.id = keywords[keyword].typeid;
tok.type = prim + tok.u.id;
+ */
return tok.kind = 'T';
}
- tok.u.id = keyword;
- return tok.kind = 'K';
+ return tok.kind = keyword + KSTART;
}
- tok.u.id = getstringkey(&idents,
+ tok.u.key = getstringkey(&idents,
line + lastcol, currcol - lastcol);
return tok.kind = 'I';
}
@@ -969,7 +1020,7 @@ skipwhite:
/* TODO(m21c): read '\''-token as character-literal 'C' */
- tok.u.id = getstringkey(&strings, line + lastcol, j - lastcol);
+ tok.u.key = getstringkey(&strings, line + lastcol, j - lastcol);
return tok.kind = 'S';
}
@@ -986,11 +1037,11 @@ skipwhite:
goto joindelim;
case '[':
if (haslhs)
- c0 = 'O', tok.u.id = OARRAY;
+ c0 = OARRAY;
goto joindelim;
case '(':
if (haslhs)
- c0 = 'O', tok.u.id = OCALL;
+ c0 = OCALL;
joindelim:
++currcol;
return tok.kind = c0;
@@ -1001,26 +1052,26 @@ skipwhite:
(line[currcol] == (ch) ? ++currcol, (then) : (otherwise))
switch (line[currcol++]) {
case '.':
- /* tok.u.id = select('.', ORANGE, ODISP); */
- tok.u.id = ODISP;
+ /* tok.kind = select('.', ORANGE, ODISP); */
+ tok.kind = ODISP;
goto joinop;
case '*':
- tok.u.id = select('=', OMULA, (haslhs ? OMUL : ODEREF));
+ tok.kind = select('=', OMULA, (haslhs ? OMUL : ODEREF));
goto joinop;
case '/':
- tok.u.id = select('=', ODIVA, ODIV);
+ tok.kind = select('=', ODIVA, ODIV);
goto joinop;
case '%':
- tok.u.id = select('=', OMODA, OMOD);
+ tok.kind = select('=', OMODA, OMOD);
goto joinop;
case '<':
- tok.u.id = select('=', OLEQ,
+ tok.kind = select('=', OLEQ,
select('<',
select('=', OLSHA, OLSH),
OLET));
goto joinop;
case '>':
- tok.u.id = select('=', OGEQ,
+ tok.kind = select('=', OGEQ,
select('>',
select('>',
select('=', OARSHA, OARSH),
@@ -1028,35 +1079,35 @@ skipwhite:
OGRT));
goto joinop;
case '&':
- tok.u.id = select('=', OANDA, select('&', OLAND,
+ tok.kind = select('=', OANDA, select('&', OLAND,
(haslhs ? OBAND : OADDR)));
goto joinop;
case '+':
- tok.u.id = select('=', OADDA, select('+',
+ tok.kind = select('=', OADDA, select('+',
(haslhs ? OSUFINC : OINC),
(haslhs ? OADD : OPLUS)));
goto joinop;
case '-':
- tok.u.id = select('=', OSUBA, select('-',
+ tok.kind = select('=', OSUBA, select('-',
(haslhs ? OSUFDEC : ODEC),
(haslhs ? OSUB : OMINUS)));
goto joinop;
case '|':
- tok.u.id = select('=', OORA, select('|', OLOR, OBOR));
+ tok.kind = select('=', OORA, select('|', OLOR, OBOR));
goto joinop;
case '^':
- tok.u.id = select('=', OXORA, OXOR);
+ tok.kind = select('=', OXORA, OXOR);
goto joinop;
case '!':
- tok.u.id = select('=', ONEQ, OLNOT);
+ tok.kind = select('=', ONEQ, OLNOT);
goto joinop;
case '~':
- tok.u.id = select('=', OFLIP, OBNOT);
+ tok.kind = select('=', OFLIP, OBNOT);
goto joinop;
case '=':
- tok.u.id = select('=', select('=', OIDENT, OEQU), OASS);
+ tok.kind = select('=', select('=', OIDENT, OEQU), OASS);
joinop:
- return tok.kind = 'O';
+ return tok.kind;
default:
error("invalid input character '%c'", c0);
@@ -1288,11 +1339,7 @@ printnode(FILE *out, Node *node) {
case 'T':
return fprintf(out, "Type");
case 'I':
- return fprintf(out, "%s", getstring(idents, node->u.id));
- case 'O':
- return fprintf(out, "%s", ops[node->u.id].str);
- case 'K':
- return fprintf(out, "%s", keywords[node->u.id].str);
+ return fprintf(out, "%s", getstring(idents, node->u.key));
case 'N':
if (node->type->kind == TFLOAT ||
node->type->kind == TDOUBLE ||
@@ -1303,8 +1350,8 @@ printnode(FILE *out, Node *node) {
else
return fprintf(out, "%lu", node->u.u);
case 'S':
- str = getstring(strings, node->u.id);
- len = getlength(strings, node->u.id);
+ str = getstring(strings, node->u.key);
+ len = getlength(strings, node->u.key);
n += fprintf(out, "\"");
for (i = 0; i < len; ++i) {
switch (str[i]) {
@@ -1335,6 +1382,12 @@ printnode(FILE *out, Node *node) {
}
}
n += printf("\"");
+ return n;
+ default:
+ if (node->kind >= KSTART && node->kind < OSTART)
+ return fprintf(out, "%s", keywords[node->kind - KSTART].str);
+ if (node->kind >= OSTART && node->kind < ASTART)
+ return fprintf(out, "%s", ops[node->kind - OSTART].str);
}
return n;
@@ -1347,32 +1400,29 @@ printast(Node *node, int indent) {
assert(node);
- if (node->kind == 'O')
- n += printf("%s(", ops[node->u.id].debugstr);
- else if (node->kind == 'A')
- n += printf("%s(", astnames[node->u.id]);
+ if (node->kind >= OSTART && node->kind < ASTART)
+ n += printf("%s(", ops[node->kind - OSTART].debugstr);
+ else if (node->kind >= ASTART && node->kind < MAXKINDS)
+ n += printf("%s(", astnames[node->kind - ASTART]);
else
printnode(stdout, node);
- if (node->kind == 'A' && (
- node->u.id == AIF ||
- node->u.id == AWHILE ||
- node->u.id == ALOOPUNTIL
- ) && node->u.cond.cond)
+ if ((node->kind == AIF || node->kind == AWHILE ||
+ node->kind == ALOOPUNTIL) && node->u.payload)
{
newline = true;
n += printf("\n");
for (i = 0; i <= indent; ++i)
n += printf(" ");
n += printf("cond: ");
- n += printast(node->u.cond.cond, indent + 1);
- } else if (node->kind == 'A' && node->u.id == ADECL && node->u.decl.init) {
+ n += printast(node->u.payload, indent + 1);
+ } else if (node->kind == ADECL && node->u.payload) {
newline = true;
n += printf("\n");
for (i = 0; i <= indent; ++i)
n += printf(" ");
n += printf("init: ");
- n += printast(node->u.decl.init, indent + 1);
+ n += printast(node->u.payload, indent + 1);
}
if (node->lhs) {
@@ -1459,10 +1509,10 @@ int
qualifiers(int allowmask) {
int flags = 0, mask = allowmask;
- while (tok.kind == 'K') {
+ while (tok.kind >= KSTART && tok.kind < OSTART) {
int f, m;
- switch (tok.u.id) {
+ switch (tok.kind) {
case KEXTERN:
f = QEXTERN, m = ~QVISIB;
break;
@@ -1483,13 +1533,13 @@ qualifiers(int allowmask) {
}
if (f & ~allowmask) {
- const char *str = keywords[tok.u.id].str;
+ const char *str = keywords[tok.kind - KSTART].str;
error("invalid qualifier '%s'", str);
} else if (f & flags & QTYPE) {
- const char *str = keywords[tok.u.id].str;
+ const char *str = keywords[tok.kind - KSTART].str;
warn("redundant qualifier '%s'", str);
} else if (f & ~mask) {
- const char *str = keywords[tok.u.id].str;
+ const char *str = keywords[tok.kind - KSTART].str;
error("redundant qualifier '%s'", str);
}
@@ -1548,14 +1598,12 @@ advance:
goto advance;
}
- if (tok.kind == 'O') {
- if (tok.u.id == ODEREF) {
- Type *tmp = maketype();
- tmp->kind = TPTR;
- tmp->target = ty, ty = tmp;
- gettok(false);
- goto advance;
- }
+ if (tok.kind == ODEREF) {
+ Type *tmp = maketype();
+ tmp->kind = TPTR;
+ tmp->target = ty, ty = tmp;
+ gettok(false);
+ goto advance;
}
basetype->type = ty;
@@ -1574,15 +1622,14 @@ declaration(Node *typenode) {
Node *result = typenode;
if (tok.kind == 'I') {
- Decl *decl = makedecl(tok.u.id, DVAR);
+ Decl *decl = makedecl(tok.u.key, DVAR);
result = makenode(typenode);
- result->kind = 'A';
- result->u.decl.id = ADECL;
+ result->kind = ADECL;
result->rhs = makenode(NULL);
gettok(true);
} else if (tok.kind == 'T') {
Node *module = gettype(getbasetype(0));
- if (tok.kind == 'O' && tok.u.id == ODISP || tok.kind == ':') {
+ if (tok.kind == ODISP || tok.kind == ':') {
has_self_param = tok.kind == ':';
gettok(false);
} else {
@@ -1591,12 +1638,10 @@ declaration(Node *typenode) {
if (tok.kind == 'I') {
module = makenode(module);
- module->kind = 'O';
- module->u.id = ODISP;
+ module->kind = ODISP;
module->rhs = makenode(NULL);
result = makenode(typenode);
- result->kind = 'A';
- result->u.decl.id = ADECL;
+ result->kind = ADECL;
result->rhs = module;
gettok(true);
} else {
@@ -1606,25 +1651,25 @@ declaration(Node *typenode) {
return result;
}
- if (tok.kind == 'O' && tok.u.id == OCALL) {
+ if (tok.kind == OCALL) {
Node *params;
gettok(false);
params = exprlist(true, NULL);
expect(')', true, "expected ')'");
- if (tok.kind != 'O' || tok.u.id != OASS) {
+ if (tok.kind != OASS) {
Node *stmts;
stmts = stmtlist(lastindent, SFUNCTION);
- result->u.decl.init = stmts;
+ result->u.payload = stmts;
}
}
- if (tok.kind == 'O' && tok.u.id == OASS) {
+ if (tok.kind == OASS) {
gettok(false);
- result->u.decl.init = expr(PSTART);
+ result->u.payload = expr(PSTART);
} else {
- result->u.decl.init = NULL;
+ result->u.payload = NULL;
}
return result;
@@ -1637,20 +1682,14 @@ isatom(void) {
case '\n': case ';':
case ',': case ':':
case ')': case ']': case '}':
+ case KELSE:
+ case KUNTIL:
return false;
- case 'O':
- if (ops[tok.u.id].prec != PUNARY)
- return false;
- return true;
- case 'K':
- switch (tok.u.id) {
- case KELSE:
- case KUNTIL:
- return false;
- }
- return true;
}
+ if (getnumops(tok.kind) && getprec(tok.kind) != PUNARY)
+ return false;
+
return true;
}
@@ -1693,8 +1732,7 @@ stmtlist(int indent, EnvKind envkind) {
stmt = exprlist(false, NULL);
stmt = makenode(stmt);
- stmt->kind = 'A';
- stmt->u.id = ASTMT;
+ stmt->kind = ASTMT;
if (!lhs) {
result = lhs = stmt;
@@ -1707,9 +1745,8 @@ stmtlist(int indent, EnvKind envkind) {
env = popenv();
result = makenode(result);
- result->kind = 'A';
- result->u.scope.id = ASCOPE;
- result->u.scope.env = env;
+ result->kind = ASCOPE;
+ result->u.env = env;
env->stmts = result;
return result;
@@ -1724,7 +1761,7 @@ atom(int flags) {
/* int flags; */
/* unary 'is'-operator */
- if (tok.kind == 'K' && tok.u.id == KIS) {
+ if (tok.kind == KIS) {
if (!lastis) {
error("there is no left-hand-side for 'is'");
lhs = makenode(NULL);
@@ -1735,17 +1772,17 @@ atom(int flags) {
gettok(false);
lhs->kind = 'O';
- if (tok.kind == 'K' && tok.u.id == KNOT)
- gettok(false), lhs->u.id = ONEQ;
+ if (tok.kind == KNOT)
+ gettok(false), lhs->kind = ONEQ;
else
- lhs->u.id = OEQU;
+ lhs->kind = OEQU;
lhs->rhs = expr(PRELAT);
return lhs;
}
/* unary prefix operators */
- if (tok.kind == 'O' && ops[tok.u.id].prec == PUNARY) {
+ if (getprec(tok.kind) == PUNARY) {
lhs = makenode(NULL);
gettok(false);
lhs->lhs = atom(0);
@@ -1774,8 +1811,7 @@ atom(int flags) {
lhs = exprlist(false, NULL), lastis = savedis;
if (lhs->kind == 'T') {
/* NOTE(m21c): expecting that the type is also set in lhs->type */
- lhs->kind = 'O';
- lhs->u.id = OCAST;
+ lhs->kind = OCAST;
skipnewline();
expect(')', true, "expected ')'");
@@ -1792,8 +1828,7 @@ atom(int flags) {
lhs = exprlist(false, NULL), lastis = savedis;
if (lhs->kind == 'T') {
/* NOTE(m21c): expecting that the type is also set in lhs->type */
- lhs->kind = 'O';
- lhs->u.id = OCAST;
+ lhs->kind = OCAST;
skipnewline();
expect(')', true, "expected ')'");
@@ -1808,11 +1843,10 @@ atom(int flags) {
case 'I':
lhs = makenode(NULL);
- lhs->u.declref.ref = finddeclaration(lhs->u.id);
+ lhs->u.declref = finddeclaration(tok.u.key);
- if (lhs->u.declref.ref) {
- lhs->kind = 'A';
- lhs->u.declref.id = ADECLREF;
+ if (lhs->u.declref) {
+ lhs->kind = ADECLREF;
} else {
Env *funcenv = getfuncenv();
if (funcenv) {
@@ -1828,8 +1862,9 @@ atom(int flags) {
}
}
} else {
- error("'%s' undeclared", getstring(idents, lhs->u.id));
+ error("'%s' undeclared", getstring(idents, tok.u.key));
}
+ lhs->u.key = tok.u.key;
}
gettok(true);
@@ -1847,110 +1882,92 @@ atom(int flags) {
/* TODO(m21c): const - conversion */
}
break;
- case 'K':
- switch (tok.u.id) {
- case KNOT:
- lhs = makenode(NULL);
+ case KNOT:
+ lhs = makenode(NULL);
+ gettok(false);
+ lhs->kind = OLNOT;
+ lhs->lhs = expr(PRELAT);
+ break;
+ case KBREAK:
+ case KCONTINUE:
+ lhs = makenode(NULL);
+ lhs->kind = tok.kind == KBREAK ? ABREAK : ACONTINUE;
+ gettok(true);
+ if (tok.kind == ':') {
gettok(false);
- lhs->kind = 'O';
- lhs->u.id = OLNOT;
- lhs->lhs = expr(PRELAT);
- break;
- case KBREAK:
- case KCONTINUE:
- lhs = makenode(NULL);
- lhs->kind = 'A';
- lhs->u.id = tok.u.id == KBREAK ? ABREAK : ACONTINUE;
- gettok(true);
- if (tok.kind == ':') {
- gettok(false);
- skipnewline();
- if (tok.kind == 'I') {
- lhs->lhs = makenode(NULL);
- gettok(false);
- } else {
- error("expected identifier");
- }
- }
- break;
- case KRETURN:
- lhs = makenode(NULL);
- gettok(true);
- lhs->kind = 'A';
- lhs->u.id = ARETURN;
- if (tok.kind == ':') {
+ skipnewline();
+ if (tok.kind == 'I') {
+ lhs->lhs = makenode(NULL);
gettok(false);
- skipnewline();
- if (tok.kind == 'I') {
- lhs->lhs = makenode(NULL);
- gettok(false);
- } else {
- error("expected identifier");
- }
+ } else {
+ error("expected identifier");
}
- if (isatom())
- lhs->rhs = exprlist(false, NULL);
- break;
- case KDO:
- indent = lastindent;
- lhs = makenode(NULL);
- gettok(false);
- lhs->kind = 'A';
- lhs->u.id = ADO;
- lhs->lhs = stmtlist(indent, SSCOPE);
- break;
- case KLOOP:
- indent = lastindent;
- lhs = makenode(NULL);
+ }
+ break;
+ case KRETURN:
+ lhs = makenode(NULL);
+ gettok(true);
+ lhs->kind = ARETURN;
+ if (tok.kind == ':') {
gettok(false);
- lhs->kind = 'A';
- lhs->u.id = ALOOP;
- lhs->lhs = stmtlist(indent, SSCOPE);
-
- if (tok.kind == 'K' && tok.u.id == KUNTIL &&
- lastindent >= indent)
- {
- lhs->u.cond.id = ALOOPUNTIL;
+ skipnewline();
+ if (tok.kind == 'I') {
+ lhs->lhs = makenode(NULL);
gettok(false);
- lhs->u.cond.cond = expr(POR);
+ } else {
+ error("expected identifier");
}
- if (lhs->u.id != ALOOP)
- goto joinelse;
- else
- break;
- case KWHILE:
- indent = lastindent;
- lhs = makenode(NULL);
+ }
+ if (isatom())
+ lhs->rhs = exprlist(false, NULL);
+ break;
+ case KDO:
+ indent = lastindent;
+ lhs = makenode(NULL);
+ gettok(false);
+ lhs->kind = ADO;
+ lhs->lhs = stmtlist(indent, SSCOPE);
+ break;
+ case KLOOP:
+ indent = lastindent;
+ lhs = makenode(NULL);
+ gettok(false);
+ lhs->kind = ALOOP;
+ lhs->lhs = stmtlist(indent, SSCOPE);
+
+ if (tok.kind == KUNTIL && lastindent >= indent) {
+ lhs->kind = ALOOPUNTIL;
gettok(false);
- lhs->kind = 'A';
- lhs->u.cond.id = AWHILE;
- lhs->u.cond.cond = expr(POR);
- lhs->lhs = stmtlist(indent, SSCOPE);
+ lhs->u.payload = expr(POR);
+ }
+ if (lhs->kind != ALOOP)
goto joinelse;
- case KIF:
- indent = lastindent;
- lhs = makenode(NULL);
- gettok(false);
- lhs->kind = 'A';
- lhs->u.cond.id = AIF;
- lhs->u.cond.cond = expr(POR);
- skipnewline();
- if (tok.kind == 'I' && tok.u.id == auxthen)
- gettok(false);
- lhs->lhs = stmtlist(indent, SSCOPE);
- joinelse:
- if (tok.kind == 'K' && tok.u.id == KELSE &&
- lastindent >= indent)
- {
- gettok(false);
- lhs->rhs = stmtlist(indent, SSCOPE);
- }
+ else
break;
- default:
- goto joinerror;
+ case KWHILE:
+ indent = lastindent;
+ lhs = makenode(NULL);
+ gettok(false);
+ lhs->kind = AWHILE;
+ lhs->u.payload = expr(POR);
+ lhs->lhs = stmtlist(indent, SSCOPE);
+ goto joinelse;
+ case KIF:
+ indent = lastindent;
+ lhs = makenode(NULL);
+ gettok(false);
+ lhs->kind = AIF;
+ lhs->u.payload = expr(POR);
+ skipnewline();
+ if (tok.kind == 'I' && tok.u.key == auxthen)
+ gettok(false);
+ lhs->lhs = stmtlist(indent, SSCOPE);
+ joinelse:
+ if (tok.kind == KELSE && lastindent >= indent) {
+ gettok(false);
+ lhs->rhs = stmtlist(indent, SSCOPE);
}
break;
- case 'O':
default:
joinerror:
error("expected expression");
@@ -1959,21 +1976,21 @@ atom(int flags) {
}
/* unary postfix operators */
- while (tok.kind == 'O' && ops[tok.u.id].prec == PUNSUF) {
+ while (getprec(tok.kind) == PUNSUF) {
lhs = makenode(lhs);
- if (tok.u.id == ODISP) {
+ if (tok.kind == ODISP) {
gettok(false);
skipnewline();
if (tok.kind != 'I')
error("expected identifier");
lhs->rhs = makenode(NULL);
- } else if (tok.u.id == OCALL) {
+ } else if (tok.kind == OCALL) {
gettok(false);
if (tok.kind != ')')
lhs->rhs = exprlist(false, NULL), lastis = savedis;
expect(')', true, "expected ')'");
continue;
- } else if (tok.u.id == OARRAY) {
+ } else if (tok.kind == OARRAY) {
gettok(false);
lhs->rhs = exprlist(false, NULL), lastis = savedis;
expect(']', true, "expected ']'");
@@ -1983,15 +2000,15 @@ atom(int flags) {
}
/* 'not'-suffix for the binary 'is'-operator (i.e. 'is not') */
- while (tok.kind == 'K' && tok.u.id == KIS) {
+ while (tok.kind == KIS) {
lhs = makenode(lhs);
gettok(false);
lhs->kind = 'O';
- if (tok.kind == 'K' && tok.u.id == KNOT)
- gettok(false), lhs->u.id = ONEQ;
+ if (tok.kind == KNOT)
+ gettok(false), lhs->kind = ONEQ;
else
- lhs->u.id = OEQU;
+ lhs->kind = OEQU;
lastis = lhs;
lhs->rhs = expr(PRELAT);
@@ -2005,23 +2022,19 @@ expr(int minprec) {
Node *lhs = atom(0), *last = NULL;
/* only binary expr */
- while (tok.kind == 'O' && ops[tok.u.id].prec >= minprec) {
+ while (getprec(tok.kind) >= minprec) {
lhs = makenode(lhs);
gettok(false);
skipnewline();
- if (ops[lhs->u.id].rassoc)
- lhs->rhs = expr(ops[lhs->u.id].prec);
- else
- lhs->rhs = expr(ops[lhs->u.id].prec + 1);
+ lhs->rhs = expr(getprec(lhs->kind) + !israssoc(lhs->kind));
- switch (ops[lhs->u.id].prec) {
+ switch (getprec(lhs->kind)) {
case PRELAT:
if (last) {
lhs = makenode(lhs);
lhs->rhs = lhs->lhs;
- lhs->kind = 'O';
- lhs->u.id = OLAND;
+ lhs->kind = OLAND;
lhs->lhs = lhs->rhs->lhs;
lhs->rhs->lhs = last->rhs; /* copy */
@@ -2044,22 +2057,21 @@ todeclaration(Node *curr, Node **ty) {
if (*ty) {
if (curr->kind == 'I') {
Node *decl = makenode(*ty);
- curr->kind = 'A';
- curr->u.decl.id = ADECL;
+ curr->kind = ADECL;
decl->rhs = curr;
curr = decl;
- } else if (curr->kind == 'O' && curr->u.id == OASS &&
+ } else if (curr->kind == OASS &&
curr->lhs && curr->lhs->kind == 'I')
{
curr->kind = 'A';
- curr->u.decl.id = ADECL;
- curr->u.decl.init = curr->rhs;
+ curr->kind = ADECL;
+ curr->u.payload = curr->rhs;
curr->rhs = curr->lhs;
curr->lhs = *ty;
}
}
- if (curr->kind == 'A' && curr->u.id == ADECL)
+ if (curr->kind == ADECL)
*ty = curr->lhs;
return curr;
@@ -2078,10 +2090,10 @@ exprlist(bool isparam, Node *paramtype) {
head = expr(PSTART), tail = head;
}
- if (isparam && (tail->kind != 'A' || tail->u.id != ADECL))
+ if (isparam && tail->kind != ADECL)
error("expected declaration");
- if ((isdeclaration = tail->kind == 'A' && tail->u.id == ADECL)) {
+ if ((isdeclaration = tail->kind == ADECL)) {
paramtype = tail->lhs;
}
@@ -2101,11 +2113,10 @@ exprlist(bool isparam, Node *paramtype) {
/* curr = todeclaration(curr, ¶mtype); */
}
- if ((paramtype || isparam) &&
- (curr->kind != 'A' || curr->u.id != ADECL))
+ if ((paramtype || isparam) && curr->kind != ADECL)
error("expected declaration");
- if (curr->kind == 'A' && curr->u.id == ADECL) {
+ if (curr->kind == ADECL) {
paramtype = tail->lhs;
isdeclaration = true;
}
@@ -2252,24 +2263,19 @@ Node *foldexpr(Node *expr)
for (c = expr; c; c = c->next) {
#if 1
- switch (c->kind)
- {
- case 'I':
- c->u.declref.ref = finddeclaration(c->u.id);
- if (c->u.declref.ref) {
- c->kind = 'A';
- c->u.declref.id = ADECLREF;
+ if (c->kind == 'I') {
+ Decl *declref = finddeclaration(c->u.key);
+ if (declref) {
+ c->kind = ADECLREF;
+ c->u.declref = declref;
} else {
- error("'%s' undeclared", getstring(idents, c->u.id));
+ error("'%s' undeclared", getstring(idents, c->u.key));
}
continue;
- case 'A':
- if (c->u.id == AIF && c->u.cond.cond) {
- c->u.cond.cond = foldexpr(c->u.cond.cond);
- }
- break;
- default:
- break;
+ }
+
+ if (c->kind == AIF && c->u.payload) {
+ c->u.payload = foldexpr(c->u.payload);
}
if (c->lhs)