commit e6889688789016e98b0b76f6a4ae7ec8856535e4
parent 4414790f9d6106b74a3f7c3f24e24bd4de5a90b3
Author: m21c <ho*******@gmail.com>
Date: Thu, 2 Feb 2023 05:14:17 +0100
worked on annotations
Diffstat:
| M | compiler.c | | | 263 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
1 file changed, 227 insertions(+), 36 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -44,7 +44,14 @@ struct Decl Decl;
typedef
struct Env Env;
+typedef
+struct AnnotParam AnnotParam;
+
+typedef
+struct Annot Annot;
+typedef
+struct Docket Docket;
typedef
struct Gist Gist;
@@ -403,6 +410,12 @@ enum Qualifier {
QINFER = QVAR
} Qualifier;
+typedef
+enum AnnotParamKind {
+ NSTATEEXPR,
+ NPARAM,
+ NEXPR
+} AnnotParamKind;
typedef
enum BlockKind {
@@ -542,6 +555,31 @@ struct Source {
Node *lastis;
} Source;
+struct AnnotParam {
+ AnnotParamKind kind;
+
+ int key;
+
+ Node *node;
+
+ AnnotParam *prev, *next;
+};
+
+struct Annot {
+ int key;
+ SrcLoc loc;
+
+ AnnotParam *head, *tail;
+
+ Annot *prev, *next;
+};
+
+struct Docket {
+ Node *node;
+ Decl *decl;
+
+ Annot *head, *tail;
+};
struct Gist {
Decl *decl;
@@ -1698,6 +1736,43 @@ maketype(SrcLoc *loc, Type *orig, Type *target)
/* SECTION: - annotation - */
+Annot annotbuf[4096];
+int annottop;
+
+Docket docketbuf[4096];
+int dockettop;
+
+static Annot *
+makeannot(SrcLoc *loc, int key)
+{
+ Annot *annot;
+
+ assert(annottop < lengthof(annotbuf));
+
+ annot = annotbuf + annottop;
+
+ annot->key = key;
+ annot->loc = *loc;
+
+ /* TODO(m21c): implement initialization. */
+
+ return annot;
+}
+
+static Docket *
+makedocket(Node *node)
+{
+ Docket *docket;
+
+ assert(dockettop < lengthof(docketbuf));
+
+ docket = docketbuf + dockettop;
+
+ /* TODO(m21c): implement initialization. */
+
+ return docket;
+}
+
/* SECTION: - environment - */
@@ -2034,61 +2109,115 @@ expect(Source *source, int kind, const char *fmt, ...)
return true;
}
-static int
-qualifiers(Source *source, int allowmask)
+static AnnotParam *
+readannotparam(Source *source)
{
- int flags = 0, mask = allowmask;
+ bool hasident = false;
- while (iskeyword(getkind(source))) {
- int f, m;
+ while (getkind(source)) {
+ int count = 1;
switch (getkind(source)) {
- case KEXTERN:
- f = QEXTERN, m = ~QVISIB;
- break;
+ case IDENT:
+ if (!hasident) {
+ int key = source->tok.u.key;
+ const char *ident = getstring(idents, key);
+ printf("Annotation Parameter: %s\n", ident);
- case KINTERN:
- f = QINTERN, m = ~QVISIB;
- break;
+ hasident = true;
+ }
- case KSTATIC:
- f = QSTATIC, m = ~QSTORAGE;
+ gettok(source);
break;
- case KCONST:
- f = QCONST, m = 0;
- break;
+ case COMMADELIM: case RPARDELIM:
+ goto finish;
- /* TODO(m21c): remove this */
- case KVAR:
- f = QVAR, m = ~(QTYPE | QINFER);
- break;
+ case LPARDELIM:
+ gettok(source);
+ while (getkind(source) && count > 0) {
+ switch (getkind(source)) {
+ case LPARDELIM:
+ ++count;
+ break;
+ case RPARDELIM:
+ --count;
+ break;
+ default:
+ break;
+ }
+ gettok(source);
+ }
+
+ if(!getkind(source))
+ goto finish;
+ /* FALLTHROUGH */
default:
- goto finish;
+ gettok(source);
}
+ }
- if (f & ~allowmask) {
- const char *str = nodestrings[getkind(source)];
+finish:
+ return NULL;
+}
- error(getloc(source), "invalid qualifier '%s'", str);
- } else if (f & flags & QTYPE) {
- const char *str = nodestrings[getkind(source)];
+static void
+readannots(Source *source)
+{
+ Docket *docket = NULL;
- warn(getloc(source), "redundant qualifier '%s'", str);
- } else if (f & ~mask) {
- const char *str = nodestrings[getkind(source)];
+ while (getkind(source) == ANNOT) {
+ SrcLoc loc = source->tok.loc;
+ int key = 0;
- error(getloc(source), "redundant qualifier '%s'", str);
- }
+ Annot *annot = NULL;
- flags |= f & allowmask & mask;
- mask &= m;
gettok(source);
- }
-finish:
- return flags;
+ key = source->tok.u.key;
+ if (!expect(source, IDENT, "expected annotation-identifier."))
+ return;
+
+ annot = makeannot(&loc, key);
+
+ if (getkind(source) == LPARDELIM) {
+ int count;
+
+ gettok(source);
+ for (count = 0; getkind(source); ++count) {
+ AnnotParam *param = readannotparam(source);
+
+ if (param)
+ listappend(annot, param);
+
+ if (getkind(source) == COMMADELIM) {
+ gettok(source);
+ continue;
+ }
+
+ if (getkind(source) != RPARDELIM) {
+ error(getloc(source),
+ "expected ',' or ')'.");
+ } else {
+ gettok(source);
+ }
+
+ break;
+ }
+ }
+
+ if (docket == NULL) {
+ docket = makedocket(NULL);
+ /* TODO(m21c): add docket to source */
+ }
+
+ listappend(docket, annot);
+
+ skipnewline(source);
+
+ printf("Annotation: '%s'\n", getstring(idents, key));
+ }
}
static bool
@@ -2175,6 +2304,10 @@ stmtlist(Source *source, int indent, EnvKind envkind,
if (checkend(source, !!tail, needindent, "expected expression"))
break;
+ if (getkind(source) == LINEDELIM)
+ gettok(source);
+
+ readannots(source);
stmt = exprlist(source, false, NULL);
stmt = tokennode(source, stmt);
stmt->kind = ASTMT;
@@ -2207,6 +2340,63 @@ stmtlist(Source *source, int indent, EnvKind envkind,
return head;
}
+static int
+qualifiers(Source *source, int allowmask)
+{
+ int flags = 0, mask = allowmask;
+
+ while (iskeyword(getkind(source))) {
+ int f, m;
+
+ switch (getkind(source)) {
+ case KEXTERN:
+ f = QEXTERN, m = ~QVISIB;
+ break;
+
+ case KINTERN:
+ f = QINTERN, m = ~QVISIB;
+ break;
+
+ case KSTATIC:
+ f = QSTATIC, m = ~QSTORAGE;
+ break;
+
+ case KCONST:
+ f = QCONST, m = 0;
+ break;
+
+ /* TODO(m21c): remove this */
+ case KVAR:
+ f = QVAR, m = ~(QTYPE | QINFER);
+ break;
+
+ default:
+ goto finish;
+ }
+
+ if (f & ~allowmask) {
+ const char *str = nodestrings[getkind(source)];
+
+ error(getloc(source), "invalid qualifier '%s'", str);
+ } else if (f & flags & QTYPE) {
+ const char *str = nodestrings[getkind(source)];
+
+ warn(getloc(source), "redundant qualifier '%s'", str);
+ } else if (f & ~mask) {
+ const char *str = nodestrings[getkind(source)];
+
+ error(getloc(source), "redundant qualifier '%s'", str);
+ }
+
+ flags |= f & allowmask & mask;
+ mask &= m;
+ gettok(source);
+ }
+
+finish:
+ return flags;
+}
+
static Node *
readexpr(Source *source, int minprec);
@@ -5468,6 +5658,7 @@ main(int argc, char **argv)
tok.u.id, currcol - lastcol, line + lastcol);*/
Node *ast;
+ readannots(source);
ast = exprlist(source, false, NULL);
/* ast = readexpr(source, PSTART); */
/*