commit 917733ec3da6966cc2962d6194ba7716347d3b6d
parent 0521d59eb791de93d2d95650d229f28d324c15e7
Author: m21c <ho*******@gmail.com>
Date: Mon, 12 Jul 2021 22:08:50 +0200
re-organized source-code
Diffstat:
| M | .gitignore | | | 1 | + |
| M | aria.c | | | 827 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
2 files changed, 428 insertions(+), 400 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -8,5 +8,6 @@ debug*.cmd
debug*.sh
*.txt
+*.todo
*.exe
\ No newline at end of file
diff --git a/aria.c b/aria.c
@@ -7,70 +7,102 @@
#include <stdbool.h>
#include <string.h>
-/* utility function */
-static int
-mystrncasecmp(const char *str1, const char *str2, size_t max_len) {
- char tmp1[] = {'\0', '\0'};
- char tmp2[] = {'\0', '\0'};
- char c1, c2;
- int result;
- size_t i;
+/* - forward declarations - */
+typedef
+struct Node Node;
- if (max_len == 0) {
- size_t len1 = strlen(str1);
- size_t len2 = strlen(str2);
- max_len = len1 > len2 ? len1 : len2;
- }
+typedef
+struct Type Type;
- for (i = 0; i < max_len; ++i) {
- c1 = tolower(str1[i]);
- c2 = tolower(str2[i]);
- if (c1 == '\0' && c2 == '\0') return 0;
- tmp1[0] = c1;
- tmp2[0] = c2;
- result = strcmp(tmp1, tmp2);
- if (result != 0) return result;
- }
+typedef
+struct Decl Decl;
- return 0;
-}
+typedef
+struct Env Env;
-static int
-mystrcasecmp(const char *str1, const char *str2) {
- char tmp1[] = {'\0', '\0'};
- char tmp2[] = {'\0', '\0'};
- char c1, c2;
- int result;
- size_t i;
- for (i = 0;; ++i) {
- c1 = tolower(str1[i]);
- c2 = tolower(str2[i]);
- if (c1 == '\0' && c2 == '\0') return 0;
- tmp1[0] = c1;
- tmp2[0] = c2;
- result = strcmp(tmp1, tmp2);
- if (result != 0) return result;
- }
+/* - enumerations & constants - */
- return 0;
-}
+enum {
+ PUNSUF = 10,
+ PUNARY = 9,
+ PMUL = 8,
+ PADD = 7,
+ PRANGE = 6,
+ PRELAT = 5,
+ PAND = 4,
+ POR = 3,
+ PASSIGN = 2,
-/* - forward declarations - */
+ PSTART = 1
+};
-typedef
-struct Node Node;
+typedef enum Kind {
+ ANNOT = '@',
+ SEMIDELIM = ';', COMMADELIM = ',', COLONDELIM = ':',
+ LCURLDELIM = '{', /*LSQRDELIM = '[',*/ LPARDELIM = '(',
+ RCURLDELIM = '}', RSQRDELIM = ']', RPARDELIM = ')',
+ CHAR = 'C',
+ IDENT = 'I',
+ NUMBER = 'N',
+ STRING = 'S',
+ TYPE = 'T',
-typedef
-struct Decl Decl;
+ LASTCHAR = '~',
-typedef
-struct Env Env;
+ /* 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,
+ KUSE, KNOT, KAND, KOR, KIS,
+ KEXTERN, KINTERN, KSTATIC, KCONST, KVAR,
+ KBREAK, KCONTINUE, KGOTO, KRETURN,
+ KIF, KELSE, KCASE, KOF, KDO,
+ KFOR, KLOOP, KWHILE, KUNTIL,
+
+ /* Operators */
+ OSUFINC, OSUFDEC, OARRAY, OCALL, ODISP,
+ OLPTR, OINC, ODEC, OBNOT, OLNOT, OFLIP, /*ORPTR,*/ 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 */
+ ASTMT, ADO, ADECL, ADECLREF, ALOOP, ALOOPUNTIL, AWHILE, AFOR, ACONTINUE,
+ ABREAK, ASCOPE, ARETURN, AGOTO, ALABEL, AIF, ASWITCH, ACASE,
+ ACONV,
+ ADEREF, AADDR,
+
+ MAXKINDS
+} Kind;
+
+#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)
+
+bool isatomnode(Kind kind)
+{
+ return kind == 'I' || kind == ADECLREF || kind == 'N' || kind == 'S' ||
+ kind == 'C';
+}
-/* - type struct - */
typedef enum {
TERRTYPE = 1, TUNDEFINED,
@@ -106,225 +138,149 @@ typedef enum {
/* TODO(m21c): maybe add long double type ? */
typedef
-struct Type Type;
-
-struct Type {
- TypeKind kind;
-
- size_t size, align;
-
- union {
- struct {
- int offset, size;
- } bit;
- struct {
- size_t length;
- size_t elemsize;
- } array;
- Node *val;
- } u;
-
- Type *target;
-};
-
-Type prim[] = {
- [TERRTYPE] = {TERRTYPE, 0, 0, {0}, NULL},
- [TUNDEFINED] = {TUNDEFINED, 0, 0, {0}, NULL},
+enum DeclKind {
+ DMODULE = 0,
+ DTYPE, /* NOTE(m21c): maybe be the same as void-module ? */
+ DVAR,
+ DPARAM,
+ DFUNCTION,
+ /*
+ DMACRO,
+ DENFOLD
+ */
+} DeclKind;
- [TVOID] = {TVOID, 0, 0, {0}, NULL},
+typedef
+enum EnvKind {
+ STOPLEVEL = 0,
+ SPARAMLIST,
+ SFUNCTION,
+ SSCOPE,
+ /*
+ SUNION,
+ SSTRUCT,
+ SENUM,
+ */
+} EnvKind;
- [TBOOL] = {TBOOL, 1, 1, {0}, NULL},
+enum {
+ QINTERN = 0x0001,
+ QEXTERN = 0x0002,
- [TINFER] = {TINFER, 4, 4, {0}, NULL},
- [TUINFER] = {TUINFER, 4, 4, {0}, NULL},
+ QSTATIC = 0x0010,
- [TS8] = {TS8, 1, 1, {0}, NULL},
- [TU8] = {TU8, 1, 1, {0}, NULL},
- [TS16] = {TS16, 2, 2, {0}, NULL},
- [TU16] = {TU16, 2, 2, {0}, NULL},
- [TS32] = {TS32, 4, 4, {0}, NULL},
- [TU32] = {TU32, 4, 4, {0}, NULL},
- [TS64] = {TS64, 8, 8, {0}, NULL},
- [TU64] = {TU64, 8, 8, {0}, NULL},
+ QCONST = 0x0200,
- [TF32] = {TF32, 4, 4, {0}, NULL},
- [TF64] = {TF64, 8, 8, {0}, NULL},
+ QVAR = 0x1000,
- [TPTR] = {TPTR, 8, 8, {0}, NULL},
- [TARRAY] = {TARRAY, 0, 0, {0}, NULL},
+ /* masks */
+ QALL = QINTERN | QEXTERN | QSTATIC | QCONST | QVAR,
+ QVISIB = QEXTERN | QINTERN,
+ QSTORAGE = QSTATIC,
+ QTYPE = QCONST,
+ QINFER = QVAR,
};
-Type typebuf[4096];
-int typetop;
-Type *
-maketype(void) {
- return typebuf + typetop++;
-}
-
-/* - pre-lexer - */
-
-char line[4096];
-int currline, lastline;
-long linepos;
-bool handlereplprompt;
+/* - type definitions - */
-void
-tryprompt(FILE *in, const char ch) {
- if (handlereplprompt) {
- fprintf(stdout, "\e[35m%c \e[0m", ch);
- } else if (in == stdin) {
- handlereplprompt = true;
- }
-}
-
-bool
-mygetline(FILE *in) {
- int i, l, c;
-
- tryprompt(in, '.');
- c = getc(in);
-
- linepos = ftell(in);
-
-advance:
- ++currline;
+struct Node {
+ Kind kind;
- i = 0, l = 0;
- while (c == '\r' || c == '\n') {
- tryprompt(in, '.');
- l = c, c = getc(in);
+ Type *type;
- if (l == '\r' && c == '\n')
- c = getc(in);
+ union {
+ int key;
- ++currline;
- }
+ double d;
+ uint64_t u;
+ int64_t s;
- lastline = currline;
+ Node *payload;
+ Decl *declref;
+ Env *env;
+ } u;
- while (c != EOF && c != '\n' && c != '\r') {
- line[i++] = c;
- c = getc(in);
+ Node *lhs, *rhs;
+ Node *prev, *next;
+};
- if (c == '\\') {
- int x = getc(in);
- if (x == '\n') {
- tryprompt(in, '\\');
- c = getc(in);
+struct Type {
+ TypeKind kind;
- ++currline;
- } else if (x == '\r') {
- int y;
+ size_t size, align;
- tryprompt(in, '\\');
- y = getc(in);
+ union {
+ struct {
+ int offset, size;
+ } bit;
+ struct {
+ size_t length;
+ size_t elemsize;
+ } array;
+ Node *val;
+ } u;
- c = (y == '\n') ? getc(in) : y;
- ++currline;
- } else if (x == EOF) {
- c = x;
- } else {
- ungetc(x, in);
- }
- }
- }
+ Type *target;
+};
- if (c == '\r') {
- int x;
+struct Decl {
+ DeclKind kind;
- tryprompt(in, '.');
- x = getc(in);
- if (x != '\n')
- ungetc(x, in);
- }
+ Type *type;
- if (c != EOF && i == 0)
- goto advance;
+ Env *env, *functionenv;
+ Node *content; /* init or function body */
- line[i] = 0;
- return c != EOF || i;
-}
+ int key;
+ Decl *prev, *next;
+};
-/* - lexer - */
+struct Env {
+ EnvKind kind;
-enum {
- PUNSUF = 10,
- PUNARY = 9,
- PMUL = 8,
- PADD = 7,
- PRANGE = 6,
- PRELAT = 5,
- PAND = 4,
- POR = 3,
- PASSIGN = 2,
+ uint8_t keycache[64];
- PSTART = 1
-};
+ Decl *head, *tail;
-typedef enum Kind {
- ANNOT = '@',
- SEMIDELIM = ';', COMMADELIM = ',', COLONDELIM = ':',
- LCURLDELIM = '{', /*LSQRDELIM = '[',*/ LPARDELIM = '(',
- RCURLDELIM = '}', RSQRDELIM = ']', RPARDELIM = ')',
- CHAR = 'C',
- IDENT = 'I',
- NUMBER = 'N',
- STRING = 'S',
- TYPE = 'T',
+ Node *stmts;
+ Decl *funcdecl; /* for SFUNCTION */
- LASTCHAR = '~',
+ Env *below;
- /* 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,
- KUSE, KNOT, KAND, KOR, KIS,
- KEXTERN, KINTERN, KSTATIC, KCONST, KVAR,
- KBREAK, KCONTINUE, KGOTO, KRETURN,
- KIF, KELSE, KCASE, KOF, KDO,
- KFOR, KLOOP, KWHILE, KUNTIL,
+ bool pending;
+ Env *pendingnext, *pendingprev;
+};
- /* Operators */
- OSUFINC, OSUFDEC, OARRAY, OCALL, ODISP,
- OLPTR, OINC, ODEC, OBNOT, OLNOT, OFLIP, /*ORPTR,*/ 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,
+/* - look-up tables - */
- /* Ast */
- ASTMT, ADO, ADECL, ADECLREF, ALOOP, ALOOPUNTIL, AWHILE, AFOR, ACONTINUE,
- ABREAK, ASCOPE, ARETURN, AGOTO, ALABEL, AIF, ASWITCH, ACASE,
- ACONV,
- ADEREF, AADDR,
+Type prim[] = {
+ [TERRTYPE] = {TERRTYPE, 0, 0, {0}, NULL},
+ [TUNDEFINED] = {TUNDEFINED, 0, 0, {0}, NULL},
- MAXKINDS
-} Kind;
+ [TVOID] = {TVOID, 0, 0, {0}, NULL},
-#define KSTART KVOID
-#define OSTART OSUFINC
-#define ASTART ASTMT
+ [TBOOL] = {TBOOL, 1, 1, {0}, NULL},
-#define iskeyword(kind) ((kind) >= KSTART && (kind) < OSTART)
-#define isoperator(kind) ((kind) >= OSTART && (kind) < ASTART)
-#define isastnode(kind) ((kind) >= ASTART && (kind) < MAXKINDS)
+ [TINFER] = {TINFER, 4, 4, {0}, NULL},
+ [TUINFER] = {TUINFER, 4, 4, {0}, NULL},
-bool isatomnode(Kind kind)
-{
- return kind == 'I' || kind == ADECLREF || kind == 'N' || kind == 'S' ||
- kind == 'C';
-}
+ [TS8] = {TS8, 1, 1, {0}, NULL},
+ [TU8] = {TU8, 1, 1, {0}, NULL},
+ [TS16] = {TS16, 2, 2, {0}, NULL},
+ [TU16] = {TU16, 2, 2, {0}, NULL},
+ [TS32] = {TS32, 4, 4, {0}, NULL},
+ [TU32] = {TU32, 4, 4, {0}, NULL},
+ [TS64] = {TS64, 8, 8, {0}, NULL},
+ [TU64] = {TU64, 8, 8, {0}, NULL},
+
+ [TF32] = {TF32, 4, 4, {0}, NULL},
+ [TF64] = {TF64, 8, 8, {0}, NULL},
+
+ [TPTR] = {TPTR, 8, 8, {0}, NULL},
+ [TARRAY] = {TARRAY, 0, 0, {0}, NULL},
+};
int keywordlengths[OSTART - KSTART];
@@ -478,48 +434,189 @@ const uint8_t opinfo[] = {
[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),
+ [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] & 0x1f))
+
+
+
+/* utility function */
+
+#define lengthof(array) ((int) sizeof(array) / (int) sizeof(*(array)))
+
+static int
+mystrncasecmp(const char *str1, const char *str2, size_t max_len) {
+ char tmp1[] = {'\0', '\0'};
+ char tmp2[] = {'\0', '\0'};
+ char c1, c2;
+ int result;
+
+ size_t i;
+
+ if (max_len == 0) {
+ size_t len1 = strlen(str1);
+ size_t len2 = strlen(str2);
+ max_len = len1 > len2 ? len1 : len2;
+ }
+
+ for (i = 0; i < max_len; ++i) {
+ c1 = tolower(str1[i]);
+ c2 = tolower(str2[i]);
+ if (c1 == '\0' && c2 == '\0') return 0;
+ tmp1[0] = c1;
+ tmp2[0] = c2;
+ result = strcmp(tmp1, tmp2);
+ if (result != 0) return result;
+ }
+
+ return 0;
+}
+
+static int
+mystrcasecmp(const char *str1, const char *str2) {
+ char tmp1[] = {'\0', '\0'};
+ char tmp2[] = {'\0', '\0'};
+ char c1, c2;
+ int result;
+
+ size_t i;
+
+ for (i = 0;; ++i) {
+ c1 = tolower(str1[i]);
+ c2 = tolower(str2[i]);
+ if (c1 == '\0' && c2 == '\0') return 0;
+ tmp1[0] = c1;
+ tmp2[0] = c2;
+ result = strcmp(tmp1, tmp2);
+ if (result != 0) return result;
+ }
+
+ return 0;
+}
+
+
+
+/* - pre-lexer - */
+
+char line[4096];
+int currline, lastline;
+long linepos;
+
+bool handlereplprompt;
+
+void
+tryprompt(FILE *in, const char ch) {
+ if (handlereplprompt) {
+ fprintf(stdout, "\e[35m%c \e[0m", ch);
+ } else if (in == stdin) {
+ handlereplprompt = true;
+ }
+}
+
+bool
+mygetline(FILE *in) {
+ int i, l, c;
+
+ tryprompt(in, '.');
+ c = getc(in);
+
+ linepos = ftell(in);
+
+advance:
+ ++currline;
+
+ i = 0, l = 0;
+ while (c == '\r' || c == '\n') {
+ tryprompt(in, '.');
+ l = c, c = getc(in);
+
+ if (l == '\r' && c == '\n')
+ c = getc(in);
+
+ ++currline;
+ }
+
+ lastline = currline;
- [ORANGE] = opentry(2, false, PRANGE),
+ while (c != EOF && c != '\n' && c != '\r') {
+ line[i++] = c;
+ c = getc(in);
- [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),
+ if (c == '\\') {
+ int x = getc(in);
+ if (x == '\n') {
+ tryprompt(in, '\\');
+ c = getc(in);
- [OLAND] = opentry(2, false, PAND),
+ ++currline;
+ } else if (x == '\r') {
+ int y;
- [OLOR] = opentry(2, false, POR),
+ tryprompt(in, '\\');
+ y = getc(in);
- [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),
+ c = (y == '\n') ? getc(in) : y;
+ ++currline;
+ } else if (x == EOF) {
+ c = x;
+ } else {
+ ungetc(x, in);
+ }
+ }
+ }
- [MAXKINDS] = 0
-};
+ if (c == '\r') {
+ int x;
-#define getnumops(kind) (opinfo[kind] >> 6)
-#define israssoc(kind) ((opinfo[kind] >> 5) & 0x01)
-#define getprec(kind) ((opinfo[kind] & 0x1f))
+ tryprompt(in, '.');
+ x = getc(in);
+ if (x != '\n')
+ ungetc(x, in);
+ }
-#define lengthof(array) ((int) sizeof(array) / (int) sizeof(*(array)))
+ if (c != EOF && i == 0)
+ goto advance;
+
+ line[i] = 0;
+ return c != EOF || i;
+}
-/* keyword map */
+/* - keyword map - */
#define KEYWORD_MAP_SIZE 128
const char *keywordkeys[KEYWORD_MAP_SIZE];
@@ -575,7 +672,7 @@ getkeyword(const char *str, int n) {
return -1;
}
-/* string map */
+/* - string map - */
typedef
struct StringEntry {
@@ -696,27 +793,6 @@ getstringkey(StringMap *map, const char *str, int n) {
/* node-structure & global vars for lexer and subsequent phases */
-struct Node {
- Kind kind;
-
- Type *type;
-
- union {
- int key;
-
- double d;
- uint64_t u;
- int64_t s;
-
- Node *payload;
- Decl *declref;
- Env *env;
- } u;
-
- Node *lhs, *rhs;
- Node *prev, *next;
-};
-
FILE *filein;
const char *filename;
const int tabwidth = 8;
@@ -725,7 +801,7 @@ char stringbuf[1024];
int currcol, lastcol, lastindent, lastkind;
Node tok;
-/* error reporting */
+/* - error reporting - */
int
warn(const char *fmt, ...) {
@@ -757,7 +833,7 @@ error(const char *fmt, ...) {
return n;
}
-/* actual lexer ( gettok() ) */
+/* - lexer - */
#define nextindent(indent) \
((indent) + tabwidth - ((indent) % tabwidth))
@@ -1111,64 +1187,37 @@ skipwhite:
#define skipnewline() \
(tok.kind == '\n' ? (void) gettok(false) : (void) 0)
-/* - environment & declaration */
-typedef
-enum DeclKind {
- DMODULE = 0,
- DTYPE, /* NOTE(m21c): maybe be the same as void-module ? */
- DVAR,
- DPARAM,
- DFUNCTION,
- /*
- DMACRO,
- DENFOLD
- */
-} DeclKind;
-struct Decl {
- DeclKind kind;
+/* - ast-node - */
- Type *type;
+Node nodebuf[4096];
+int nodetop;
- Env *env, *functionenv;
- Node *content; /* init or function body */
+Node *
+makenode(Node *lhs) {
+ Node *node = nodebuf + nodetop++;
+ *node = tok;
+ node->lhs = lhs;
- int key;
- Decl *prev, *next;
-};
+ return node;
+}
-typedef
-enum EnvKind {
- STOPLEVEL = 0,
- SPARAMLIST,
- SFUNCTION,
- SSCOPE,
- /*
- SUNION,
- SSTRUCT,
- SENUM,
- */
-} EnvKind;
-struct Env {
- EnvKind kind;
- uint8_t keycache[64];
+/* - type-strcut - */
- Decl *head, *tail;
+Type typebuf[4096];
+int typetop;
- Node *stmts;
- Decl *funcdecl; /* for SFUNCTION */
+Type *
+maketype(void) {
+ return typebuf + typetop++;
+}
- Env *below;
- bool pending;
- Env *pendingnext, *pendingprev;
-};
-Decl declbuf[4096];
-int decltop;
+/* - environment - */
Env envbuf[4096];
int envtop;
@@ -1196,43 +1245,6 @@ finddeclinenv(int key, Env *env) {
}
Decl *
-makedecl(int key, DeclKind kind) {
- const int cacheindex = (key >> 3) & 0x3f;
- const int cachebit = 1 << (key & 0x03);
-
- Decl *probe, *decl = declbuf + decltop++;
-
- decl->kind = kind;
- decl->key = key;
- decl->type = prim + TVOID;
- decl->functionenv = NULL;
-
- assert(currenv);
-
- probe = finddeclinenv(key, currenv);
-
- if (probe) {
- error("'%s' already declared", getstring(idents, key));
- }
-
- currenv->keycache[cacheindex] |= cachebit;
-
- decl->env = currenv;
-
- if (currenv->tail) {
- currenv->tail->next = decl;
- decl->prev = currenv->tail;
- } else {
- assert(currenv->head == NULL);
- currenv->head = decl;
- }
-
- currenv->tail = decl;
-
- return decl;
-}
-
-Decl *
finddeclaration(int key) {
const int cacheindex = (key >> 3) & 0x3f;
const int cachebit = 1 << (key & 0x03);
@@ -1323,20 +1335,52 @@ getfuncenv(void) {
return NULL;
}
-/* - ast-node - */
-Node nodebuf[4096];
-int nodetop;
-Node *
-makenode(Node *lhs) {
- Node *node = nodebuf + nodetop++;
- *node = tok;
- node->lhs = lhs;
+/* - declaration - */
- return node;
+Decl declbuf[4096];
+int decltop;
+
+Decl *
+makedecl(int key, DeclKind kind) {
+ const int cacheindex = (key >> 3) & 0x3f;
+ const int cachebit = 1 << (key & 0x03);
+
+ Decl *probe, *decl = declbuf + decltop++;
+
+ decl->kind = kind;
+ decl->key = key;
+ decl->type = prim + TVOID;
+ decl->functionenv = NULL;
+
+ assert(currenv);
+
+ probe = finddeclinenv(key, currenv);
+
+ if (probe) {
+ error("'%s' already declared", getstring(idents, key));
+ }
+
+ currenv->keycache[cacheindex] |= cachebit;
+
+ decl->env = currenv;
+
+ if (currenv->tail) {
+ currenv->tail->next = decl;
+ decl->prev = currenv->tail;
+ } else {
+ assert(currenv->head == NULL);
+ currenv->head = decl;
+ }
+
+ currenv->tail = decl;
+
+ return decl;
}
+
+
/* - parser - */
bool
@@ -1357,24 +1401,6 @@ expect(int kind, bool nexthaslhs, const char *fmt, ...) {
return true;
}
-enum {
- QINTERN = 0x0001,
- QEXTERN = 0x0002,
-
- QSTATIC = 0x0010,
-
- QCONST = 0x0200,
-
- QVAR = 0x1000,
-
- /* masks */
- QALL = QINTERN | QEXTERN | QSTATIC | QCONST | QVAR,
- QVISIB = QEXTERN | QINTERN,
- QSTORAGE = QSTATIC,
- QTYPE = QCONST,
- QINFER = QVAR,
-};
-
int
qualifiers(int allowmask) {
int flags = 0, mask = allowmask;
@@ -2694,7 +2720,8 @@ foldexpr(Node *expr) {
/* - print ast - */
-typedef enum Highlight {
+typedef
+enum Highlight {
HLNONE = 0,
HLDELIM = 1,
HLUNKNOWN = 2,