Aria

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

commit 55b25c1c04fc252550bfdb1dc5da808f8fb14fab
parent 503dcb4b282301c142050c5bbcfe955d29fe8bcf
Author: m21c <ho*******@gmail.com>
Date:   Thu,  1 Apr 2021 23:06:43 +0200

code-cleanup in node kind - layout

Diffstat:
Maria.c | 390+++++++++++++++++++++++++++++++++----------------------------------------------
1 file changed, 161 insertions(+), 229 deletions(-)

diff --git a/aria.c b/aria.c @@ -72,7 +72,7 @@ struct Env Env; /* - type struct - */ enum { - TVOID, TBOOL, + TVOID = 1, TBOOL, TU8, TS8, TU16, TS16, TU32, TS32, TU64, TS64, @@ -211,28 +211,6 @@ advance: /* - lexer - */ -typedef -struct Op { - const char *debugstr; - const char *str; - - int num; - int prec; - bool rassoc; -} Op; - -typedef -struct Keyword { - const char *str; - int len; - - bool isop; - int opid; - - bool istype; - int typeid; -} Keyword; - enum { PUNSUF = 10, PUNARY = 9, @@ -247,90 +225,168 @@ enum { 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, - + ANNOT = '@', + SEMIDELIM = ';', COMMADELIM = ',', COLONDELIM = ':', LCURLDELIM = '{', + 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, + KUCHAR, KCHAR, KUSHORT, KSHORT, KUINT, KINT, \ KULONG, KLONG, KULLONG, KLLONG, - KFLOAT, KDOUBLE, KLDOUBLE, - KUSIZE, KSSIZE, - - KUSE, - KNOT, KAND, KOR, - KIS, - + KUSE, KNOT, KAND, KOR, KIS, KEXTERN, KINTERN, KSTATIC, KCONST, KVAR, - KBREAK, KCONTINUE, KGOTO, KRETURN, KIF, KELSE, KCASE, KOF, KDO, - KFOR, KLOOP, KWHILE, KUNTIL, - OSUFINC = OSTART, - OSUFDEC, OARRAY, OCALL, ODISP, - - ODEREF, OINC, ODEC, OBNOT, OLNOT, OFLIP, OADDR, OPLUS, OMINUS, - OCAST, - + /* 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, + OMULA, ODIVA, OMODA, OLSHA, OARSHA, ORSHA, OANDA, \ OADDA, OSUBA, OORA, OXORA, - ASTMT = ASTART, - ADO, ADECL, ADECLREF, ALOOP, ALOOPUNTIL, AWHILE, AFOR, ACONTINUE, + /* Ast */ + ASTMT, 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" +#define KSTART KVOID +#define OSTART OSUFINC +#define ASTART ASTMT + +#define iskeyword(kind) ((kind) >= KSTART && (kind) < OSTART) +#define isoperator(kind) ((kind) >= OSTART && (kind) < ASTART) +#define isastnode(kind) ((kind) >= ASTART && (kind) < MAXKINDS) + +int keywordlengths[OSTART - KSTART]; + +const int keywordtypeids[] = { + [KVOID] = TVOID, + [KBOOL] = TBOOL, + + [KU8] = TU8, + [KS8] = TS8, + [KU16] = TU16, + [KS16] = TS16, + [KU32] = TU32, + [KS32] = TS32, + [KU64] = TU64, + [KS64] = TS64, + + [KF32] = TF32, + [KF64] = TF64, + + [KUCHAR] = TUCHAR, + [KCHAR] = TCHAR, + [KUSHORT] = TUSHORT, + [KSHORT] = TSHORT, + [KUINT] = TUINT, + [KINT] = TINT, + [KULONG] = TULONG, + [KLONG] = TLONG, + [KULLONG] = TULLONG, + [KLLONG] = TLLONG, + + [KFLOAT] = TFLOAT, + [KDOUBLE] = TDOUBLE, + [KLDOUBLE] = TLDOUBLE, + + [KUSIZE] = TUSIZE, + [KSSIZE] = TSSIZE, + + [OSTART] = 0 +}; + +const char *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", + [KUSE] = "use", [KNOT] = "not", + [KAND] = "and", [KOR] = "or", + [KIS] = "is", + [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", + /* Operators */ + [OSUFINC] = "unary++", [OSUFDEC] = "unary--", + [OARRAY] = "unary[]", [OCALL] = "unary()", + [ODISP] = "unary._", + [ODEREF] = "*unary", [OINC] = "++unary", + [ODEC] = "--unary", [OBNOT] = "~unary", + [OLNOT] = "!unary", [OFLIP] = "~=unary", + [OADDR] = "&unary", [OPLUS] = "+unary", + [OMINUS] = "-unary", [OCAST] = "(type) unary", + [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 */ + [ASTMT] = "statement", [ADO] = "do-clause", + [ADECL] = "declaration", [ADECLREF] = "symbol-reference", + [ALOOP] = "loop-clause", [ALOOPUNTIL] = "loop-until-clause", + [AWHILE] = "while-clause", [AFOR] = "for-clause", + [ACONTINUE] = "continue-statement", [ABREAK] = "break-statement", + [ASCOPE] = "scope", [ARETURN] = "return-statement", + [AGOTO] = "goto-statement", [ALABEL] = "label", + [AIF] = "if-clause", [ASWITCH] = "case-clause", + [ACASE] = "of-clause", + + [MAXKINDS] = NULL }; /* @@ -349,8 +405,6 @@ Node kinds: ((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), @@ -415,125 +469,7 @@ const uint8_t opinfo[] = { #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[] = { - {"void", 0, false, 0, true, TVOID}, - {"bool", 0, false, 0, true, TBOOL}, - - {"u8", 0, false, 0, true, TU8}, - {"s8", 0, false, 0, true, TS8}, - {"u16", 0, false, 0, true, TU16}, - {"s16", 0, false, 0, true, TS16}, - {"u32", 0, false, 0, true, TU32}, - {"s32", 0, false, 0, true, TS32}, - {"u64", 0, false, 0, true, TU64}, - {"s64", 0, false, 0, true, TS64}, - {"f32", 0, false, 0, true, TF32}, - {"f64", 0, false, 0, true, TF64}, - - {"uchar", 0, false, 0, true, TUCHAR}, - {"char", 0, false, 0, true, TCHAR}, - {"ushort", 0, false, 0, true, TUSHORT}, - {"short", 0, false, 0, true, TSHORT}, - {"uint", 0, false, 0, true, TUINT}, - {"int", 0, false, 0, true, TINT}, - {"ulong", 0, false, 0, true, TULONG}, - {"long", 0, false, 0, true, TLONG}, - {"ullong", 0, false, 0, true, TULLONG}, - {"llong", 0, false, 0, true, TLLONG}, - {"float", 0, false, 0, true, TFLOAT}, - {"double", 0, false, 0, true, TDOUBLE}, - {"ldouble", 0, false, 0, true, TLDOUBLE}, - {"usize", 0, false, 0, true, TUSIZE}, - {"ssize", 0, false, 0, true, TSSIZE}, - - {"use", 0, false, 0, false, 0}, - {"not", 0, false, 0, false, 0}, - {"and", 0, true , OLAND, false, 0}, - {"or", 0, true , OLOR, false, 0}, - {"is", 0, false, 0, false, 0}, - - {"extern", 0, false, 0, false, 0}, - {"intern", 0, false, 0, false, 0}, - {"static", 0, false, 0, false, 0}, - {"const", 0, false, 0, false, 0}, - {"var", 0, false, 0, false, 0}, - - {"break", 0, false, 0, false, 0}, - {"continue", 0, false, 0, false, 0}, - {"goto", 0, false, 0, false, 0}, - {"return", 0, false, 0, false, 0}, - {"if", 0, false, 0, false, 0}, - {"else", 0, false, 0, false, 0}, - {"case", 0, false, 0, false, 0}, - {"of", 0, false, 0, false, 0}, - {"do", 0, false, 0, false, 0}, - - {"for", 0, false, 0, false, 0}, - {"loop", 0, false, 0, false, 0}, - {"while", 0, false, 0, false, 0}, - {"until", 0, false, 0, false, 0}, -}; - -#define lengthof(array) ((int) sizeof(array) / (int) sizeof (*(array))) +#define lengthof(array) ((int) sizeof(array) / (int) sizeof(*(array))) #define KEYWORD_MAP_SIZE 128 const char *keywordkeys[KEYWORD_MAP_SIZE]; @@ -550,12 +486,12 @@ strnhash(const char *str, int n) { void initkeywords(void) { int i, j, h; - for (i = 0; i < lengthof(keywords); ++i) { - int n = keywords[i].len = strlen(keywords[i].str); - h = strnhash(keywords[i].str, n) & (lengthof(keywordkeys) - 8); + for (i = 0; i < lengthof(keywordlengths); ++i) { + int n = keywordlengths[i] = strlen(nodestrings[i + KSTART]); + h = strnhash(nodestrings[i + KSTART], n) & (lengthof(keywordkeys) - 8); for (j = 0; j < 8; ++j, ++h) { if (!keywordkeys[h]) { - keywordkeys[h] = keywords[i].str; + keywordkeys[h] = nodestrings[i + KSTART]; keywordvals[h] = i; goto nextkeyword; } @@ -582,7 +518,7 @@ getkeyword(const char *str, int n) { int len; if (!keywordkeys[h]) return -1; - len = keywords[keywordvals[h]].len; + len = keywordlengths[keywordvals[h]]; if (n == len && memcmp(keywordkeys[h], str, n) == 0) return keywordvals[h]; } @@ -829,13 +765,11 @@ skipwhite: keyword = getkeyword(line + lastcol, currcol - lastcol); if (tok.kind != '@' && keyword >= 0 && tok.kind != ODISP) { - if (keywords[keyword].isop) { - return tok.kind = keywords[keyword].opid; - } else if (keywords[keyword].istype) { - /* - tok.u.id = keywords[keyword].typeid; - tok.type = prim + tok.u.id; - */ + if (keyword == KOR - KSTART || keyword == KAND - KSTART) { + return tok.kind = keyword == KOR - KSTART ? OLOR : OLAND; + } else if (keywordtypeids[keyword + KSTART]) { + tok.u.key = keywordtypeids[keyword + KSTART]; + tok.type = prim + tok.u.key; return tok.kind = 'T'; } return tok.kind = keyword + KSTART; @@ -1336,10 +1270,12 @@ printnode(FILE *out, Node *node) { return fprintf(out, "<null>"); switch (node->kind) { + case ADECLREF: + return fprintf(out, "symbol-reference '%s'", getstring(idents, node->u.declref->key)); case 'T': - return fprintf(out, "Type"); + return fprintf(out, "type"); case 'I': - return fprintf(out, "%s", getstring(idents, node->u.key)); + return fprintf(out, "identifier '%s'", getstring(idents, node->u.key)); case 'N': if (node->type->kind == TFLOAT || node->type->kind == TDOUBLE || @@ -1384,10 +1320,8 @@ 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); + if (nodestrings[node->kind]) + return fprintf(out, "%s", nodestrings[node->kind]); } return n; @@ -1400,10 +1334,8 @@ printast(Node *node, int indent) { assert(node); - 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]); + if (node->kind >= OSTART && node->kind != ADECLREF) + n += printf("%s(", nodestrings[node->kind]); else printnode(stdout, node); @@ -1509,7 +1441,7 @@ int qualifiers(int allowmask) { int flags = 0, mask = allowmask; - while (tok.kind >= KSTART && tok.kind < OSTART) { + while (iskeyword(tok.kind)) { int f, m; switch (tok.kind) { @@ -1533,13 +1465,13 @@ qualifiers(int allowmask) { } if (f & ~allowmask) { - const char *str = keywords[tok.kind - KSTART].str; + const char *str = nodestrings[tok.kind]; error("invalid qualifier '%s'", str); } else if (f & flags & QTYPE) { - const char *str = keywords[tok.kind - KSTART].str; + const char *str = nodestrings[tok.kind]; warn("redundant qualifier '%s'", str); } else if (f & ~mask) { - const char *str = keywords[tok.kind - KSTART].str; + const char *str = nodestrings[tok.kind]; error("redundant qualifier '%s'", str); }