commit 57a6e101bb5483dd7d2dabe99b284dac5d7e9113
parent b1ba24556d4d0127ac0e7473fe9232c7ea5531e5
Author: m21c <ho*******@gmail.com>
Date: Wed, 2 Feb 2022 17:52:57 +0100
re-organized into node/token kind table
Diffstat:
| M | compiler.c | | | 616 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
1 file changed, 312 insertions(+), 304 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -27,9 +27,182 @@ struct Env Env;
+/* - node kind table - */
+
+#define SENDOFFILE "end-of-file"
+#define SINVALID "invalide token"
+#define SLINEDELIM "line-delimiter"
+
+#define SCHAR "character-literal"
+#define SIDENT "identifier"
+#define SNUMBER "number-literal"
+#define SSTRING "string-literal"
+
+#define SASTMT "statement"
+#define SALOOPUNTIL "loop-until-clause"
+#define SADECL "declaration"
+#define SADECLREF "symbol-reference"
+#define SASWITCH "case-clause"
+#define SACASE "of-clause"
+#define SACONV "conversion"
+
+#define NODETAB \
+ /* tag , string , childs , flags , prec */ \
+ /* Basic */ \
+ entry(ENDOFFILE , SENDOFFILE , 0 , 0 , 0) \
+ entry(INVALID , SINVALID , 0 , 0 , 0) \
+ entry(LINEDELIM , SLINEDELIM , 0 , 0 , 0) \
+ entry(SEMIDELIM , ";" , 0 , 0 , 0) \
+ entry(COMMADELIM , "," , 0 , 0 , 0) \
+ entry(COLONDELIM , ":" , 0 , 0 , 0) \
+ entry(LCURLDELIM , "{" , 0 , 0 , 0) \
+ entry(LSQRDELIM , "[" , 0 , 0 , 0) \
+ entry(LPARDELIM , "(" , 0 , 0 , 0) \
+ entry(RCURLDELIM , "}" , 0 , 0 , 0) \
+ entry(RSQRDELIM , "]" , 0 , 0 , 0) \
+ entry(RPARDELIM , ")" , 0 , 0 , 0) \
+ entry(ANNOT , "@" , 0 , 0 , 0) \
+ entry(CHAR , SCHAR , 0 , 0 , 0) \
+ entry(IDENT , SIDENT , 0 , 0 , 0) \
+ entry(NUMBER , SNUMBER , 0 , 0 , 0) \
+ entry(STRING , SSTRING , 0 , 0 , 0) \
+ entry(TYPE , "type" , 0 , 0 , 0) \
+ /* Keywords */ \
+ entry(KVOID , "void" , 0 , 0 , 0) \
+ entry(KBOOL , "bool" , 0 , 0 , 0) \
+ entry(KU8 , "u8" , 0 , 0 , 0) \
+ entry(KS8 , "s8" , 0 , 0 , 0) \
+ entry(KU16 , "u16" , 0 , 0 , 0) \
+ entry(KS16 , "s16" , 0 , 0 , 0) \
+ entry(KU32 , "u32" , 0 , 0 , 0) \
+ entry(KS32 , "s32" , 0 , 0 , 0) \
+ entry(KU64 , "u64" , 0 , 0 , 0) \
+ entry(KS64 , "s64" , 0 , 0 , 0) \
+ entry(KF32 , "f32" , 0 , 0 , 0) \
+ entry(KF64 , "f64" , 0 , 0 , 0) \
+ entry(KUCHAR , "uchar" , 0 , 0 , 0) \
+ entry(KCHAR , "char" , 0 , 0 , 0) \
+ entry(KUSHORT , "ushort" , 0 , 0 , 0) \
+ entry(KSHORT , "short" , 0 , 0 , 0) \
+ entry(KUINT , "uint" , 0 , 0 , 0) \
+ entry(KINT , "int" , 0 , 0 , 0) \
+ entry(KULONG , "ulong" , 0 , 0 , 0) \
+ entry(KLONG , "long" , 0 , 0 , 0) \
+ entry(KULLONG , "ullong" , 0 , 0 , 0) \
+ entry(KLLONG , "llong" , 0 , 0 , 0) \
+ entry(KFLOAT , "float" , 0 , 0 , 0) \
+ entry(KDOUBLE , "double" , 0 , 0 , 0) \
+ entry(KLDOUBLE , "ldouble" , 0 , 0 , 0) \
+ entry(KUSIZE , "usize" , 0 , 0 , 0) \
+ entry(KSSIZE , "ssize" , 0 , 0 , 0) \
+ entry(KFALSE , "false" , 0 , 0 , 0) \
+ entry(KTRUE , "true" , 0 , 0 , 0) \
+ entry(KNULL , "null" , 0 , 0 , 0) \
+ entry(KUSE , "use" , 0 , 0 , 0) \
+ entry(KNOT , "not" , 0 , 0 , 0) \
+ entry(KAND , "and" , 0 , 0 , 0) \
+ entry(KOR , "or" , 0 , 0 , 0) \
+ entry(KIS , "is" , 0 , 0 , 0) \
+ entry(KSIZEOF , "sizeof" , 0 , 0 , 0) \
+ entry(KALIGNOF , "alignof" , 0 , 0 , 0) \
+ entry(KLENGTHOF , "lengthof" , 0 , 0 , 0) \
+ entry(KBITCAST , "bitcast" , 0 , 0 , 0) \
+ entry(KEXTERN , "extern" , 0 , 0 , 0) \
+ entry(KINTERN , "intern" , 0 , 0 , 0) \
+ entry(KSTATIC , "static" , 0 , 0 , 0) \
+ entry(KCONST , "const" , 0 , 0 , 0) \
+ entry(KVAR , "var" , 0 , 0 , 0) \
+ entry(KBREAK , "break" , 0 , 0 , 0) \
+ entry(KCONTINUE , "continue" , 0 , 0 , 0) \
+ entry(KGOTO , "goto" , 0 , 0 , 0) \
+ entry(KRETURN , "return" , 0 , 0 , 0) \
+ entry(KIF , "if" , 0 , 0 , 0) \
+ entry(KELSE , "else" , 0 , 0 , 0) \
+ entry(KCASE , "case" , 0 , 0 , 0) \
+ entry(KOF , "of" , 0 , 0 , 0) \
+ entry(KDO , "do" , 0 , 0 , 0) \
+ entry(KFOR , "for" , 0 , 0 , 0) \
+ entry(KLOOP , "loop" , 0 , 0 , 0) \
+ entry(KWHILE , "while" , 0 , 0 , 0) \
+ entry(KUNTIL , "until" , 0 , 0 , 0) \
+ entry(KSTRUCT , "struct" , 0 , 0 , 0) \
+ entry(KUNION , "union" , 0 , 0 , 0) \
+ /* Operators */ \
+ entry(OSUFINC , "++" , 1 , FRASSOC , PUNSUF ) \
+ entry(OSUFDEC , "--" , 1 , FRASSOC , PUNSUF ) \
+ entry(OARRAY , "[]" , 1 , FRASSOC , PUNSUF ) \
+ entry(OCALL , "()" , 1 , FRASSOC , PUNSUF ) \
+ entry(ODISP , "." , 1 , FRASSOC , PUNSUF ) \
+ entry(ODEREF , "*" , 1 , 0 , PUNARY ) \
+ entry(OINC , "++" , 1 , 0 , PUNARY ) \
+ entry(ODEC , "--" , 1 , 0 , PUNARY ) \
+ entry(OBNOT , "~" , 1 , 0 , PUNARY ) \
+ entry(OLNOT , "!" , 1 , 0 , PUNARY ) \
+ entry(OFLIP , "!>" , 1 , 0 , PUNARY ) \
+ entry(OADDR , "&" , 1 , 0 , PUNARY ) \
+ entry(OPLUS , "+" , 1 , 0 , PUNARY ) \
+ entry(OMINUS , "-" , 1 , 0 , PUNARY ) \
+ entry(OCAST , "(type)" , 1 , 0 , PUNARY ) \
+ entry(OMUL , "*" , 2 , 0 , PMUL ) \
+ entry(ODIV , "/" , 2 , 0 , PMUL ) \
+ entry(OMOD , "%" , 2 , 0 , PMUL ) \
+ entry(OLSH , "<<" , 2 , 0 , PMUL ) \
+ entry(OARSH , ">>>" , 2 , 0 , PMUL ) \
+ entry(ORSH , ">>" , 2 , 0 , PMUL ) \
+ entry(OBAND , "&" , 2 , 0 , PMUL ) \
+ entry(OADD , "+" , 2 , 0 , PADD ) \
+ entry(OSUB , "-" , 2 , 0 , PADD ) \
+ entry(OBOR , "|" , 2 , 0 , PADD ) \
+ entry(OXOR , "^" , 2 , 0 , PADD ) \
+ entry(ORANGE , ".." , 2 , 0 , PRANGE ) \
+ entry(OLEQ , "<=" , 2 , 0 , PRELAT ) \
+ entry(OLET , "<" , 2 , 0 , PRELAT ) \
+ entry(OGEQ , ">=" , 2 , 0 , PRELAT ) \
+ entry(OGRT , ">" , 2 , 0 , PRELAT ) \
+ entry(ONEQ , "!=" , 2 , 0 , PRELAT ) \
+ entry(OEQU , "==" , 2 , 0 , PRELAT ) \
+ entry(OIDENT , "===" , 2 , 0 , PRELAT ) \
+ entry(OLAND , "&&" , 2 , 0 , PAND ) \
+ entry(OLOR , "||" , 2 , 0 , POR ) \
+ entry(OASS , "=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OMULA , "*=" , 2 , FRASSOC , PASSIGN ) \
+ entry(ODIVA , "/=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OMODA , "%=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OLSHA , "<<=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OARSHA , ">>>=" , 2 , FRASSOC , PASSIGN ) \
+ entry(ORSHA , ">>=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OANDA , "&=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OADDA , "+=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OSUBA , "-=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OORA , "|=" , 2 , FRASSOC , PASSIGN ) \
+ entry(OXORA , "^=" , 2 , FRASSOC , PASSIGN ) \
+ /* Ast */ \
+ entry(ACOMMA , "," , 0 , 0 , 0) \
+ entry(ASTMT , SASTMT , 0 , 0 , 0) \
+ entry(ADECL , SADECL , 0 , 0 , 0) \
+ entry(ADECLREF , SADECLREF , 0 , 0 , 0) \
+ entry(ALOOPUNTIL , SALOOPUNTIL , 0 , 0 , 0) \
+ entry(ASCOPE , "scope" , 0 , 0 , 0) \
+ entry(ALABEL , "label" , 0 , 0 , 0) \
+ entry(ASWITCH , SASWITCH , 0 , 0 , 0) \
+ entry(ACASE , SACASE , 0 , 0 , 0) \
+ entry(ACONV , SACONV , 0 , 0 , 0) \
+ entry(ADEREF , "*" , 0 , 0 , 0) \
+ entry(AADDR , "&" , 0 , 0 , 0) \
+ /* endof NODETAB */
+
+#define isbinaryop(kind) ((kind) >= OMUL && (kind) < ACOMMA)
+
+
+
/* - enumerations & constants - */
typedef
+enum Flags {
+ FRASSOC = 1,
+} Flads;
+
+typedef
enum Precedence {
PUNSUF = 10,
PUNARY = 9,
@@ -46,54 +219,10 @@ enum Precedence {
typedef
enum Kind {
- ANNOT = '@',
- SEMIDELIM = ';', COMMADELIM = ',', COLONDELIM = ':',
- LCURLDELIM = '{', /*LSQRDELIM = '[',*/ LPARDELIM = '(',
- RCURLDELIM = '}', RSQRDELIM = ']', RPARDELIM = ')',
- CHAR = 'C',
- IDENT = 'I',
- NUMBER = 'N',
- STRING = 'S',
- TYPE = 'T',
-
- LASTCHAR = '~',
-
- /* Keywords */
- KVOID, KBOOL,
- KU8, KS8, KU16, KS16, KU32, KS32, KU64, KS64,
- KF32, KF64,
- KUCHAR, KCHAR, KUSHORT, KSHORT, KUINT, KINT, \
- KULONG, KLONG, KULLONG, KLLONG,
- KFLOAT, KDOUBLE, KLDOUBLE,
- KUSIZE, KSSIZE,
- KFALSE, KTRUE, KNULL,
- KUSE, KNOT, KAND, KOR, KIS,
- KSIZEOF, KALIGNOF, KLENGTHOF,
- KBITCAST,
- KEXTERN, KINTERN, KSTATIC, KCONST, KVAR,
- KBREAK, KCONTINUE, KGOTO, KRETURN,
- KIF, KELSE, KCASE, KOF, KDO,
- KFOR, KLOOP, KWHILE, KUNTIL,
- KSTRUCT, KUNION,
-
- /* Operators */
- 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,
-
- /* Ast */
- ACOMMA, ASTMT, ADECL, ADECLREF, ALOOPUNTIL,
- ASCOPE, ALABEL, ASWITCH, ACASE,
- ACONV,
- ADEREF, AADDR,
+ #define entry(tag, string, childs, flags, prec) \
+ tag,
+ NODETAB
+ #undef entry
MAXKINDS
} Kind;
@@ -109,8 +238,8 @@ enum Kind {
static bool
isatomnode(Kind kind)
{
- return kind == 'I' || kind == ADECLREF || kind == 'N' || kind == 'S' ||
- kind == 'C';
+ return kind == IDENT || kind == ADECLREF || kind == NUMBER ||
+ kind == STRING || kind == CHAR;
}
@@ -415,81 +544,11 @@ const int keywordtypeids[] = {
[OSTART] = 0
};
-const char *const nodestrings[] = {
- /* Keywords */
- [KVOID] = "void", [KBOOL] = "bool",
- [KU8] = "u8", [KS8] = "s8",
- [KU16] = "u16", [KS16] = "s16",
- [KU32] = "u32", [KS32] = "s32",
- [KU64] = "u64", [KS64] = "s64",
- [KF32] = "f32", [KF64] = "f64",
- [KUCHAR] = "uchar", [KCHAR] = "char",
- [KUSHORT] = "ushort", [KSHORT] = "short",
- [KUINT] = "uint", [KINT] = "int",
- [KULONG] = "ulong", [KLONG] = "long",
- [KULLONG] = "ullong", [KLLONG] = "llong",
- [KFLOAT] = "float", [KDOUBLE] = "double",
- [KLDOUBLE] = "ldouble", [KUSIZE] = "usize",
- [KSSIZE] = "ssize",
- [KFALSE] = "false", [KTRUE] = "true",
- [KNULL] = "null",
- [KUSE] = "use", [KNOT] = "not",
- [KAND] = "and", [KOR] = "or",
- [KIS] = "is",
- [KSIZEOF] = "sizeof", [KALIGNOF] = "alignof",
- [KLENGTHOF] = "lengthof",
- [KBITCAST] = "bitcast",
- [KEXTERN] = "extern", [KINTERN] = "intern",
- [KSTATIC] = "static", [KCONST] = "const",
- [KVAR] = "var",
- [KBREAK] = "break", [KCONTINUE] = "continue",
- [KGOTO] = "goto", [KRETURN] = "return",
- [KIF] = "if", [KELSE] = "else",
- [KCASE] = "case", [KOF] = "of",
- [KDO] = "do",
- [KFOR] = "for", [KLOOP] = "loop",
- [KWHILE] = "while", [KUNTIL] = "until",
- [KSTRUCT] = "struct", [KUNION] = "union",
- /* Operators */
- [OSUFINC] = "++", [OSUFDEC] = "--",
- [OARRAY] = "[]", [OCALL] = "()",
- [ODISP] = ".",
- [ODEREF] = "*", [OINC] = "++",
- [ODEC] = "--", [OBNOT] = "~",
- [OLNOT] = "!", [OFLIP] = "~=",
- [OADDR] = "&", [OPLUS] = "+",
- [OMINUS] = "-", [OCAST] = "(type)",
- [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] = "^=",
- /* Ast Nodes */
- [ACOMMA] = ",",
- [ASTMT] = "statement",
- [ALOOPUNTIL] = "loop-until-clause",
- [ADECL] = "declaration", [ADECLREF] = "symbol-reference",
- [ASCOPE] = "scope",
- [ALABEL] = "label",
- [ASWITCH] = "case-clause",
- [ACASE] = "of-clause",
- [ACONV] = "conversion",
-
- [MAXKINDS] = NULL
+const char *const nodestrings[MAXKINDS] = {
+ #define entry(tag, string, childs, flags, prec) \
+ string,
+ NODETAB
+ #undef entry
};
/*
@@ -508,64 +567,13 @@ Node kinds:
((uint8_t) ( ((numops) << 6) | ((rassoc) << 5) | (prec) ))
const uint8_t opinfo[] = {
- [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 entry(tag, string, childs, flags, prec) ((uint8_t) ( \
+ ((childs) << 6) | \
+ (!!(flags & FRASSOC) << 5) | \
+ (prec) \
+ )),
+ NODETAB
+ #undef entry
};
#define getnumops(kind) (opinfo[kind] >> 6)
@@ -973,7 +981,7 @@ tokenizealphanumeric(Source *source, register int ch)
source->currloc.column - source->tok.loc.column
);
- if (source->tok.kind != '@' && keyword >= 0 &&
+ if (source->tok.kind != ANNOT && keyword >= 0 &&
source->tok.kind != ODISP)
{
if (keyword == KOR - KSTART || keyword == KAND - KSTART) {
@@ -986,7 +994,7 @@ tokenizealphanumeric(Source *source, register int ch)
source->tok.type = prim + source->tok.u.key;
- return source->tok.kind = 'T';
+ return source->tok.kind = TYPE;
}
return source->tok.kind = keyword + KSTART;
@@ -998,7 +1006,7 @@ tokenizealphanumeric(Source *source, register int ch)
source->currloc.column - source->tok.loc.column
);
- return source->tok.kind = 'I';
+ return source->tok.kind = IDENT;
}
static Type *
@@ -1138,7 +1146,7 @@ advancenum:
source->tok.u.u = 0;
source->tok.type = prim + TINT;
- return source->tok.kind = 'N';
+ return source->tok.kind = NUMBER;
}
source->stringbuf[j++] = source->line[i];
@@ -1171,7 +1179,7 @@ advancenum:
source->tok.type = suffixinttype(source, end);
}
- return source->tok.kind = 'N';
+ return source->tok.kind = NUMBER;
}
static int
@@ -1233,10 +1241,10 @@ tokenizestring(Source *source, register int ch)
stringeol:
error(&source->currloc, "unexpected end-of-line");
- return source->tok.kind = '\n';
+ return source->tok.kind = LINEDELIM;
}
- /* TODO(m21c): read '\''-token as character-literal 'C' */
+ /* TODO(m21c): read '\''-token as character-literal CHAR */
source->tok.u.key = getstringkey(
&strings,
@@ -1244,7 +1252,7 @@ tokenizestring(Source *source, register int ch)
j - source->tok.loc.column
);
- return source->tok.kind = 'S';
+ return source->tok.kind = STRING;
}
static int
@@ -1298,7 +1306,7 @@ skipwhite:
goto skipwhite;
} else {
hasnewline = true;
- return source->tok.kind = '\n';
+ return source->tok.kind = LINEDELIM;
}
}
@@ -1316,16 +1324,6 @@ skipwhite:
if (ch == '"' || ch == '\'')
return tokenizestring(source, ch);
- /* delimiters */
- switch (ch) {
- case ',': case ';': case '@': case ':':
- case '{': case '}':
- case ']': case '[':
- case '(': case ')':
- ++source->currloc.column;
- return source->tok.kind = ch;
- }
-
/* operators */
#define select(ch, then, otherwise) ( \
peekchar(source) == (ch) ? \
@@ -1400,9 +1398,21 @@ skipwhite:
ch = select('=', select('=', OIDENT, OEQU), OASS);
break;
+ /* delimiters */
+ case ',': ch = COMMADELIM; break;
+ case ';': ch = SEMIDELIM; break;
+ case '@': ch = ANNOT; break;
+ case ':': ch = COLONDELIM; break;
+ case '{': ch = LCURLDELIM; break;
+ case '}': ch = RCURLDELIM; break;
+ case '[': ch = LSQRDELIM; break;
+ case ']': ch = RSQRDELIM; break;
+ case '(': ch = LPARDELIM; break;
+ case ')': ch = RPARDELIM; break;
+
default:
error(&source->currloc, "invalid input character '%c'", ch);
- return 'Z';
+ return INVALID;
}
return source->tok.kind = ch;
@@ -1410,16 +1420,16 @@ skipwhite:
}
#define skipnewline(source) \
- ((source)->tok.kind == '\n' ? (void) gettok(source) : (void) 0)
+ ((source)->tok.kind == LINEDELIM ? (void) gettok(source) : (void) 0)
static bool
isbasicdelimiter(Kind kind)
{
switch ((int) kind) {
case 0:
- case '\n': case ',': case ';':
- case ':':
- case ')': case ']': case '}':
+ case LINEDELIM: case COMMADELIM: case SEMIDELIM:
+ case COLONDELIM:
+ case RPARDELIM: case RSQRDELIM: case RCURLDELIM:
case KELSE:
case KUNTIL:
return true;
@@ -1475,8 +1485,8 @@ getunarysuffix(Source *source)
return 0;
switch (kind) {
- case '(': return OCALL;
- case '[': return OARRAY;
+ case LPARDELIM: return OCALL;
+ case LSQRDELIM: return OARRAY;
default:
return 0;
}
@@ -1985,26 +1995,26 @@ static bool
checkend(Source *source, bool hastail, int needindent,
const char *expecterrmsg)
{
- if (getkind(source) == '\n') {
+ if (getkind(source) == LINEDELIM) {
gettok(source);
- if (getkind(source) == ';') {
+ if (getkind(source) == SEMIDELIM) {
error(getloc(source), expecterrmsg);
gettok(source);
return true;
}
}
- if (source->lastkind == '\n' && source->lastindent < needindent)
+ if (source->lastkind == LINEDELIM && source->lastindent < needindent)
return true;
- if (getkind(source) == ';') {
+ if (getkind(source) == SEMIDELIM) {
gettok(source);
/* NOTE(m21c): used for REPL. it allows having
* semicolons on line-endings and nultiple
* adjacent semecolons in REPL-mode. */
- if (getkind(source) == ';' || getkind(source) == '\n') {
+ if (getkind(source) == SEMIDELIM || getkind(source) == LINEDELIM) {
/* TODO(m21c): output an error-message if not in REPL-mode */
}
}
@@ -2012,7 +2022,7 @@ checkend(Source *source, bool hastail, int needindent,
if (isdelimiter(source->tok.kind))
return true;
- if (hastail && source->lastkind != '\n' && source->lastkind != ';')
+ if (hastail && source->lastkind != LINEDELIM && source->lastkind != SEMIDELIM)
error(getloc(source), "expected line delimiter");
return false;
@@ -2089,15 +2099,15 @@ gettype(Source *source, Type *basetype)
advance:
flags = qualifiers(source, QTYPE);
- if (getkind(source) == '[') {
+ if (getkind(source) == LSQRDELIM) {
Type *tmp = maketype(getloc(source), prim + TARRAY, basetype);
basetype = tmp;
gettok(source);
- if (source->tok.kind != ']')
+ if (source->tok.kind != RSQRDELIM)
basetype->u.val = readexpr(source, PASSIGN);
- expect(source, ']', "expect ']'");
+ expect(source, RSQRDELIM, "expect ']'");
goto advance;
}
@@ -2152,7 +2162,7 @@ redodeclaration:
skipnewline(source);
/* variable name */
- if (getkind(source) == 'I') {
+ if (getkind(source) == IDENT) {
int key = source->tok.u.key;
SrcLoc loc = source->tok.loc;
EnvKind envkind = source->currenv->kind;
@@ -2162,7 +2172,7 @@ redodeclaration:
if (tryreadtype && (envkind == SSTRUCT || envkind == SUNION)) {
if (!isbasicdelimiter(getkind(source)) &&
- getkind(source) != '(')
+ getkind(source) != LPARDELIM)
{
decl = defertypedeclaration(source, key);
decl->loc = loc;
@@ -2182,8 +2192,8 @@ redodeclaration:
goto readvarmodule;
}
- if ((getkind(source) == ODISP || getkind(source) == ':') &&
- getkind(source) != '(' && getkind(source) != OASS)
+ if ((getkind(source) == ODISP || getkind(source) == COLONDELIM) &&
+ getkind(source) != LPARDELIM && getkind(source) != OASS)
{
error(&loc, "expected type or module");
}
@@ -2192,15 +2202,15 @@ redodeclaration:
decl->loc = loc;
decl->type = ty;
/* module for variable */
- } else if (getkind(source) == 'T') {
+ } else if (getkind(source) == TYPE) {
module = source->tok.type;
gettok(source);
readvarmodule:
module = gettype(source, module);
- if (getkind(source) == ODISP || getkind(source) == ':') {
- selfparam = getkind(source) == ':';
+ if (getkind(source) == ODISP || getkind(source) == COLONDELIM) {
+ selfparam = getkind(source) == COLONDELIM;
gettok(source);
} else {
error(getloc(source), "expected '.' or ':'");
@@ -2211,7 +2221,7 @@ redodeclaration:
* or Type Module.my_decl - declarations */
/* variable name */
- if (getkind(source) == 'I') {
+ if (getkind(source) == IDENT) {
decl = makedecl(source, source->tok.u.key, DVAR);
decl->type = ty;
decl->typemodule = module;
@@ -2222,21 +2232,21 @@ redodeclaration:
/* just return a node for the type */
} else {
result = tokennode(source, NULL);
- result->kind = 'T';
+ result->kind = TYPE;
result->type = ty;
return result;
}
/* function declaration */
- if (getkind(source) == '(') {
+ if (getkind(source) == LPARDELIM) {
Type *paramtype = NULL;
Env *functionenv = NULL;
Node *body = NULL;
/* function params */
gettok(source);
- if (getkind(source) != ')') {
+ if (getkind(source) != RPARDELIM) {
Decl *param;
Node *paramlist;
@@ -2255,7 +2265,7 @@ redodeclaration:
param->kind = DPARAM;
}
}
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
if (module && ty->kind == TINFER) {
ty = module;
@@ -2368,10 +2378,10 @@ readident(Source *source, int flags)
lhs->u.declref = decl;
} else {
if (deferfuncenv(source, key)) {
- lhs->kind = 'I';
+ lhs->kind = IDENT;
lhs->u.key = key;
} else {
- lhs->kind = 'N';
+ lhs->kind = NUMBER;
lhs->u.u = 0;
}
@@ -2404,7 +2414,7 @@ readrecord(Source *source, bool isunion)
recordnode->kind = getkind(source);
gettok(source);
- if (getkind(source) == 'I') {
+ if (getkind(source) == IDENT) {
recordnode->lhs = tokennode(source, NULL);
gettok(source);
} else {
@@ -2452,7 +2462,6 @@ readatom(Source *source, int flags)
gettok(source);
- lhs->kind = 'O';
if (getkind(source) == KNOT)
gettok(source), lhs->kind = ONEQ;
else
@@ -2486,10 +2495,10 @@ readatom(Source *source, int flags)
/* actual atom */
switch (getkind(source)) {
- case '(':
+ case LPARDELIM:
gettok(source);
- if (getkind(source) == '\n') {
+ if (getkind(source) == LINEDELIM) {
/* FIXME(m21c): stmtlist should ignore indentation in
* this case! */
lhs = stmtlist(source, source->lastindent,
@@ -2499,19 +2508,19 @@ readatom(Source *source, int flags)
lhs = exprlist(source, false, NULL);
source->lastis = savedis;
- if (lhs->kind == 'T') {
+ if (lhs->kind == TYPE) {
/* NOTE(m21c): expecting that the type is also set in lhs->type */
lhs->kind = OCAST;
skipnewline(source);
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
lhs->lhs = readatom(source, 0);
break;
}
if (lhs->kind == ACOMMA &&
- lhs->lhs->kind == 'T' &&
- lhs->rhs->kind == 'T')
+ lhs->lhs->kind == TYPE &&
+ lhs->rhs->kind == TYPE)
{
Type *ty = maketype(&lhs->loc, prim + TTUPLE, NULL);
ty->target = lhs->lhs->type;
@@ -2519,7 +2528,7 @@ readatom(Source *source, int flags)
deletenode(lhs);
skipnewline(source);
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
lhs = declaration(source, gettype(source, ty), false);
@@ -2530,14 +2539,14 @@ readatom(Source *source, int flags)
skipnewline(source);
}
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
break;
- case 'I':
+ case IDENT:
lhs = readident(source, flags);
break;
- case 'T':
+ case TYPE:
do {
Type *type = source->tok.type;
gettok(source);
@@ -2546,9 +2555,9 @@ readatom(Source *source, int flags)
break;
- case 'N':
- case 'S':
- case 'C':
+ case NUMBER:
+ case STRING:
+ case CHAR:
lhs = tokennode(source, NULL);
gettok(source);
@@ -2566,7 +2575,7 @@ readatom(Source *source, int flags)
case KFALSE:
case KTRUE:
lhs = tokennode(source, NULL);
- lhs->kind = 'N';
+ lhs->kind = NUMBER;
lhs->type = prim + TBOOL;
lhs->u.u = (uint64_t) (getkind(source) == KTRUE);
gettok(source);
@@ -2574,7 +2583,7 @@ readatom(Source *source, int flags)
case KNULL:
lhs = tokennode(source, NULL);
- lhs->kind = 'N';
+ lhs->kind = NUMBER;
lhs->type = maketype(&source->tok.loc, prim + TPTR, prim + TVOID);
lhs->u.u = (uint64_t) (getkind(source) == KTRUE);
gettok(source);
@@ -2597,10 +2606,10 @@ readatom(Source *source, int flags)
case KLENGTHOF:
lhs = tokennode(source, NULL);
gettok(source);
- if (getkind(source) == '(') {
+ if (getkind(source) == LPARDELIM) {
gettok(source);
lhs->lhs = exprlist(source, false, NULL);
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
} else {
lhs->lhs = readatom(source, 0);
}
@@ -2610,9 +2619,9 @@ readatom(Source *source, int flags)
case KBITCAST:
lhs = tokennode(source, NULL);
gettok(source);
- expect(source, '(', "expected '('");
+ expect(source, LPARDELIM, "expected '('");
lhs->rhs = exprlist(source, false, NULL);
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
lhs->lhs = readatom(source, 0);
break;
@@ -2622,10 +2631,10 @@ readatom(Source *source, int flags)
lhs->kind = getkind(source);
gettok(source);
- if (getkind(source) == ':') {
+ if (getkind(source) == COLONDELIM) {
gettok(source);
skipnewline(source);
- if (getkind(source) == 'I') {
+ if (getkind(source) == IDENT) {
lhs->lhs = tokennode(source, NULL);
gettok(source);
} else {
@@ -2639,10 +2648,10 @@ readatom(Source *source, int flags)
lhs = tokennode(source, NULL);
gettok(source);
- if (getkind(source) == ':') {
+ if (getkind(source) == COLONDELIM) {
gettok(source);
skipnewline(source);
- if (getkind(source) == 'I') {
+ if (getkind(source) == IDENT) {
lhs->lhs = tokennode(source, NULL);
gettok(source);
} else {
@@ -2695,7 +2704,7 @@ readatom(Source *source, int flags)
lhs->u.payload = readexpr(source, POR);
/* skipnewline(source); */
- if (getkind(source) == 'I' && source->tok.u.key == auxthen)
+ if (getkind(source) == IDENT && source->tok.u.key == auxthen)
gettok(source);
lhs->lhs = stmtlist(source, indent, SIF, NULL, false);
@@ -2711,22 +2720,22 @@ readatom(Source *source, int flags)
joinerror:
error(getloc(source), "expected expression");
lhs = tokennode(source, NULL);
- lhs->kind = 'N';
+ lhs->kind = NUMBER;
lhs->type = prim + TERRTYPE;
lhs->u.u = 0;
gettok(source);
}
/* compound-literal */
- if (getkind(source) == '{' && lhs->kind == 'T') {
+ if (getkind(source) == LCURLDELIM && lhs->kind == TYPE) {
lhs = tokennode(source, lhs);
- lhs->kind = 'A';
+ lhs->kind = 'A'; /* FIXME(m21c): add kind for compound literals */
lhs->type = lhs->lhs->type;
gettok(source);
lhs->rhs = exprlist(source, false, NULL);
- expect(source, '}', "expected '}'");
+ expect(source, RCURLDELIM, "expected '}'");
}
/* unary postfix operators */
@@ -2740,29 +2749,29 @@ readatom(Source *source, int flags)
gettok(source);
skipnewline(source);
- if (getkind(source) != 'I')
+ if (getkind(source) != IDENT)
error(getloc(source), "expected identifier");
lhs->rhs = tokennode(source, NULL);
- } else if (getkind(source) == '(') {
+ } else if (getkind(source) == LPARDELIM) {
gettok(source);
- if (getkind(source) != ')') {
+ if (getkind(source) != RPARDELIM) {
lhs->rhs = exprlist(source, false, NULL);
source->lastis = savedis;
}
- expect(source, ')', "expected ')'");
+ expect(source, RPARDELIM, "expected ')'");
continue;
- } else if (getkind(source) == '[') {
+ } else if (getkind(source) == LSQRDELIM) {
gettok(source);
lhs->rhs = exprlist(source, false, NULL);
source->lastis = savedis;
- expect(source, ']', "expected ']'");
+ expect(source, RSQRDELIM, "expected ']'");
continue;
}
@@ -2833,15 +2842,14 @@ static Node *
todeclaration(Node *curr, Node **ty)
{
if (*ty) {
- if (curr->kind == 'I') {
+ if (curr->kind == IDENT) {
Node *decl = makenode(curr, *ty);
curr->kind = ADECL;
decl->rhs = curr;
curr = decl;
} else if (curr->kind == OASS &&
- curr->lhs && curr->lhs->kind == 'I')
+ curr->lhs && curr->lhs->kind == IDENT)
{
- curr->kind = 'A';
curr->kind = ADECL;
curr->u.payload = curr->rhs;
curr->rhs = curr->lhs;
@@ -2866,7 +2874,7 @@ exprlist(Source *source, bool isparam, Type *paramtype)
/* tail = todeclaration(tail, ¶mtype); */
- if (paramtype && getkind(source) == 'I') {
+ if (paramtype && getkind(source) == IDENT) {
lhs = declaration(source, paramtype, false);
} else {
lhs = readexpr(source, PASSIGN);
@@ -2879,14 +2887,14 @@ exprlist(Source *source, bool isparam, Type *paramtype)
paramtype = lhs->type;
}
- typetuple = lhs->kind == 'T';
+ typetuple = lhs->kind == TYPE;
- while (getkind(source) == ',') {
+ while (getkind(source) == COMMADELIM) {
Node *rhs = NULL;
if (lhs->kind == ACOMMA &&
- lhs->lhs->kind == 'T' &&
- lhs->rhs->kind == 'T')
+ lhs->lhs->kind == TYPE &&
+ lhs->rhs->kind == TYPE)
{
lhs->type = maketype(&lhs->loc, prim + TTUPLE,
lhs->lhs->type);
@@ -2899,19 +2907,19 @@ exprlist(Source *source, bool isparam, Type *paramtype)
lhs->lhs = NULL;
lhs->rhs = NULL;
- lhs->kind = 'T';
+ lhs->kind = TYPE;
}
lhs = tokennode(source, lhs);
lhs->kind = ACOMMA;
gettok(source);
- if (getkind(source) == 'I' && isdeclaration) {
+ if (getkind(source) == IDENT && isdeclaration) {
rhs = declaration(source, paramtype, true);
typetuple = false;
} else {
rhs = readexpr(source, PASSIGN);
- typetuple &= rhs->kind == 'T';
+ typetuple &= rhs->kind == TYPE;
/* rhs = todeclaration(curr, ¶mtype); */
}
@@ -3039,7 +3047,7 @@ wrap(Type *type, Node *node)
if (type->kind == nodetype->kind)
return node;
- if (node->kind == 'N') {
+ if (node->kind == NUMBER) {
/* TODO(m21c): layout correct type-conversions ? */
if (isfloattype(nodetype)) {
if (isfloattype(type)) {
@@ -3201,7 +3209,7 @@ resolvepending(Env *env, Node *expr)
{
Decl *decl;
- assert(expr->kind == 'I');
+ assert(expr->kind == IDENT);
decl = finddeclaration(NULL, env, expr->u.key);
@@ -3315,7 +3323,7 @@ typecheck(Env *env, Node *expr)
case OCAST:
/*
assert(rhs);
- assert(lhs->kind == 'T');
+ assert(lhs->kind == TYPE);
*/
if (arithtuplereorder(env, expr, 1))
@@ -3515,7 +3523,7 @@ typecheck(Env *env, Node *expr)
return expr;
- case 'I':
+ case IDENT:
return resolvepending(env, expr);
joincomma:
@@ -3562,7 +3570,7 @@ typecheck(Env *env, Node *expr)
if (rhs->type->kind == TERRTYPE)
return expr->type = prim + TERRTYPE, expr;
- if (rhs->kind != 'T') {
+ if (rhs->kind != TYPE) {
error(&rhs->loc, "expected type");
expr->type = prim + TERRTYPE;
return expr;
@@ -3607,7 +3615,7 @@ foldexpr(Env *env, Node *expr)
#define evalbinary(op) do { \
- expr->kind = 'N'; \
+ expr->kind = NUMBER; \
if (isfloattype(ty)) \
expr->u.d = maskfloat(ty->size, \
maskfloat(ty->size, lhs->u.d) op \
@@ -3622,7 +3630,7 @@ foldexpr(Env *env, Node *expr)
deletenode(rhs); \
} while (0)
- #define isvalue(expr, value) (expr->kind == 'N' && \
+ #define isvalue(expr, value) (expr->kind == NUMBER && \
((expr->u.u == value && isinttype(ty)) || \
(expr->u.d == value && isarithtype(ty))))
@@ -3637,7 +3645,7 @@ foldexpr(Env *env, Node *expr)
switch ((int) expr->kind) {
case OADD: case OSUB:
- if (lhs->kind == 'N' && rhs->kind == 'N') {
+ if (lhs->kind == NUMBER && rhs->kind == NUMBER) {
if (expr->kind == OADD) evalbinary(+);
else evalbinary(-);
} else if (isvalue(lhs, 0)) {
@@ -3658,7 +3666,7 @@ foldexpr(Env *env, Node *expr)
return expr;
case OMUL: case ODIV: case OMOD:
- if (lhs->kind == 'N' && rhs->kind == 'N') {
+ if (lhs->kind == NUMBER && rhs->kind == NUMBER) {
if (expr->kind == OMUL) {
evalbinary(*);
} else {
@@ -3706,13 +3714,13 @@ foldexpr(Env *env, Node *expr)
return expr;
case OMINUS:
- if (lhs->kind == 'N') {
+ if (lhs->kind == NUMBER) {
if (isfloattype(ty)) {
- expr->kind = 'N';
+ expr->kind = NUMBER;
expr->u.d = maskfloat(ty->size, -lhs->u.d);
deletenode(lhs);
} else if (isinttype(ty)) {
- expr->kind = 'N';
+ expr->kind = NUMBER;
expr->u.u = maskint(ty->size, -lhs->u.u);
deletenode(lhs);
}
@@ -3724,7 +3732,7 @@ foldexpr(Env *env, Node *expr)
return expr;
case OBAND: case OBOR: case OXOR:
- if (lhs->kind == 'N' && rhs->kind == 'N') {
+ if (lhs->kind == NUMBER && rhs->kind == NUMBER) {
assert(
isinttype(lhs->type) ||
lhs->type->kind == TBOOL
@@ -3743,7 +3751,7 @@ foldexpr(Env *env, Node *expr)
expr->u.u = lhs->u.u | rhs->u.u;
else
expr->u.u = lhs->u.u ^ rhs->u.u;
- expr->kind = 'N';
+ expr->kind = NUMBER;
expr->u.u = maskint(ty->size, expr->u.u);
}
@@ -3800,7 +3808,7 @@ foldexpr(Env *env, Node *expr)
}
deletenode(lhs);
- expr->kind = 'N';
+ expr->kind = NUMBER;
return expr;
case ACONV:
@@ -3811,7 +3819,7 @@ foldexpr(Env *env, Node *expr)
return expr;
- case 'T':
+ case TYPE:
error(&expr->loc, "exptected expression, not type");
default:
@@ -4387,13 +4395,13 @@ printexpr(FILE *out, Node *expr, int indent)
} else {
switch (expr->kind)
{
- case 'I':
+ case IDENT:
n += highlight(out, HLUNKNOWN);
n += fprintf(out, "%s?", getstring(idents, expr->u.key));
n += highlight(out, HLNONE);
break;
- case 'N':
+ case NUMBER:
n += highlight(out, HLNUMBER);
switch (expr->type->kind) {
@@ -4441,7 +4449,7 @@ printexpr(FILE *out, Node *expr, int indent)
break;
- case 'S':
+ case STRING:
n += highlight(out, HLSTRING);
n += printstring(out, expr);
break;
@@ -4640,7 +4648,7 @@ initsource(Source *source, const char *filename, FILE *file)
source->implicitenv = envbuf + envtop++;
gettok(source);
- if (getkind(source) == '\n')
+ if (getkind(source) == LINEDELIM)
gettok(source);
}
@@ -4796,7 +4804,7 @@ main(int argc, char **argv)
/* deletenode(ast); */
- if (getkind(source) == '\n') {
+ if (getkind(source) == LINEDELIM) {
if (source->filein == stdin) {
highlight(stdout, HLPROMPT);
printf("> ");
@@ -4804,14 +4812,14 @@ main(int argc, char **argv)
source->handlereplprompt = false;
}
gettok(source);
- } else if (getkind(source) == ';') {
+ } else if (getkind(source) == SEMIDELIM) {
gettok(source);
}
- if (source->lastkind != ';' && source->lastkind != '\n') {
+ if (source->lastkind != SEMIDELIM && source->lastkind != LINEDELIM) {
error(getloc(source), "expected new line");
- while (getkind(source) != ';' &&
- getkind(source) != '\n' && getkind(source) != 0)
+ while (getkind(source) != SEMIDELIM &&
+ getkind(source) != LINEDELIM && getkind(source) != 0)
{
gettok(source);
}