Aria

A low-level systems programming language
git clone git://git.m21c.me/Aria.git
Log | Files | Refs | LICENSE

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:
Mcompiler.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, &paramtype); */ - 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, &paramtype); */ } @@ -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); }