commit 18f42c96e78f5b8ee31e00d09f244892bf4bb009
parent aebdaed7fd4a6ee42805f01a347373319e57eefe
Author: m21c <ho*******@gmail.com>
Date: Thu, 1 Apr 2021 17:07:51 +0200
started implementing semantic-analysis
Diffstat:
| M | aria.c | | | 229 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
1 file changed, 222 insertions(+), 7 deletions(-)
diff --git a/aria.c b/aria.c
@@ -66,6 +66,9 @@ struct Node Node;
typedef
struct Decl Decl;
+typedef
+struct Env Env;
+
/* - type struct - */
enum {
@@ -661,6 +664,11 @@ struct Node {
int id;
Decl *ref;
} declref;
+
+ struct {
+ int id;
+ Env *env;
+ } scope;
} u;
Node *lhs, *rhs;
@@ -1074,9 +1082,6 @@ enum DeclKind {
*/
} DeclKind;
-typedef
-struct Env Env;
-
struct Decl {
DeclKind kind;
@@ -1105,7 +1110,14 @@ struct Env {
uint8_t keycache[64];
Decl *head, *tail;
+
+ Node *stmts;
+ Decl *funcdecl; /* for SFUNCTION */
+
Env *below;
+
+ bool pending;
+ Env *pendingnext, *pendingprev;
};
Decl declbuf[4096];
@@ -1116,6 +1128,8 @@ int envtop;
Env *headenv, *currenv;
+Env *pendingenvhead, *pendingenvtail;
+
Decl *
finddeclinenv(int key, Env *env) {
const int cacheindex = (key >> 3) & 0x3f;
@@ -1644,10 +1658,11 @@ Node *
stmtlist(int indent, EnvKind envkind) {
Node *result = NULL, *lhs = NULL;
int needindent = nextindent(indent);
+
+ Env *env;
/* printf("needident: %d, currindent: %d, lastindent: %d\n", needindent, currindent, lastindent); */
pushenv(envkind);
-
for (;;) {
Node *stmt;
@@ -1689,8 +1704,13 @@ stmtlist(int indent, EnvKind envkind) {
lhs = lhs->next;
}
}
+ env = popenv();
- popenv();
+ result = makenode(result);
+ result->kind = 'A';
+ result->u.scope.id = ASCOPE;
+ result->u.scope.env = env;
+ env->stmts = result;
return result;
}
@@ -1794,8 +1814,22 @@ atom(int flags) {
lhs->kind = 'A';
lhs->u.declref.id = ADECLREF;
} else {
- /* NOTE(m21c): debug code */
- error("'%s' undeclared", getstring(idents, lhs->u.id));
+ Env *funcenv = getfuncenv();
+ if (funcenv) {
+ if (!funcenv->pending) {
+ funcenv->pending = true;
+ if (!pendingenvhead) {
+ pendingenvtail = funcenv;
+ pendingenvhead = funcenv;
+ } else {
+ pendingenvtail->pendingnext = funcenv;
+ funcenv->pendingprev = pendingenvtail;
+ pendingenvtail = funcenv;
+ }
+ }
+ } else {
+ error("'%s' undeclared", getstring(idents, lhs->u.id));
+ }
}
gettok(true);
@@ -2085,10 +2119,185 @@ exprlist(bool isparam, Node *paramtype) {
return head;
}
+/* - type-checking & folding - */
+
+Node *
+conv(Node *node)
+{
+ return node;
+}
+
+Node *
+wrap(Type *ty, Node *node)
+{
+ return node;
+}
+
+Type *
+usualarithconv(Type *lt, Type *rt)
+{
+ return lt;
+}
+
+#if 0
+
+typedef
+Node *(*RuleFunc)(Node *expr);
+
+Node *
+emptyrule(Node *expr)
+{
+ return expr;
+}
+
+Node *
+identrule(Node *ident)
+{
+ ident->u.declref.ref = finddeclaration(ident->u.id);
+ if (ident->u.declref.ref) {
+ ident->kind = 'A';
+ ident->u.declref.id = ADECLREF;
+ } else {
+ error("'%s' undeclared", getstring(idents, ident->u.id));
+ }
+
+ return ident;
+}
+
+RuleFunc opfunctable[] = {
+ [OSUFINC] = &emptyrule, [OSUFDEC] = &emptyrule,
+ [OARRAY] = &emptyrule, [OCALL] = &emptyrule,
+ [ODISP] = &emptyrule,
+
+ [ODEREF] = &emptyrule,
+ [OINC] = &emptyrule, [ODEC] = &emptyrule,
+ [OBNOT] = &emptyrule, [OLNOT] = &emptyrule,
+ [OFLIP] = &emptyrule,
+ [OADDR] = &emptyrule,
+ [OPLUS] = &emptyrule, [OMINUS] = &emptyrule,
+ [OCAST] = &emptyrule,
+
+ [OMUL] = &emptyrule, [ODIV] = &emptyrule, [OMOD] = &emptyrule,
+ [OLSH] = &emptyrule, [OARSH] = &emptyrule, [ORSH] = &emptyrule,
+ [OBAND] = &emptyrule,
+
+ [OADD] = &emptyrule, [OSUB] = &emptyrule,
+ [OBOR] = &emptyrule, [OXOR] = &emptyrule,
+
+ [ORANGE] = &emptyrule,
+
+ [OLEQ] = &emptyrule, [OLET] = &emptyrule,
+ [OGEQ] = &emptyrule, [OGRT] = &emptyrule,
+ [ONEQ] = &emptyrule, [OEQU] = &emptyrule,
+ [OIDENT] = &emptyrule,
+
+ [OLAND] = &emptyrule,
+
+ [OLOR] = &emptyrule,
+
+ [OASS] = &emptyrule,
+
+ [OMULA] = &emptyrule, [ODIVA] = &emptyrule, [OMODA] = &emptyrule,
+ [OLSHA] = &emptyrule, [OARSHA] = &emptyrule, [ORSHA] = &emptyrule,
+ [OANDA] = &emptyrule,
+ [OADDA] = &emptyrule, [OSUBA] = &emptyrule,
+ [OORA] = &emptyrule, [OXORA] = &emptyrule,
+};
+
+Node *
+oprules(Node *expr)
+{
+ return opfunctable[expr->u.id](expr);
+}
+
+RuleFunc astfunctable[] = {
+ [ASTMT] = &emptyrule,
+ [ADO] = &emptyrule,
+ [ADECL] = &emptyrule,
+ [ADECLREF] = &emptyrule,
+ [ALOOP] = &emptyrule,
+ [ALOOPUNTIL] = &emptyrule,
+ [AWHILE] = &emptyrule,
+ [AFOR] = &emptyrule,
+ [ACONTINUE] = &emptyrule,
+ [ABREAK] = &emptyrule,
+ [ASCOPE] = &emptyrule,
+ [ARETURN] = &emptyrule,
+ [AGOTO] = &emptyrule,
+ [ALABEL] = &emptyrule,
+ [AIF] = &emptyrule,
+ [ASWITCH] = &emptyrule,
+ [ACASE] = &emptyrule
+};
+
+Node *
+astrules(Node *expr)
+{
+ return astfunctable[expr->u.id](expr);
+}
+
+RuleFunc ruletable[] = {
+ ['A'] = &astrules,
+ ['I'] = &identrule,
+ ['O'] = &oprules,
+
+ [127] = NULL
+};
+
+#endif
+
+Node *foldexpr(Node *expr)
+{
+ Node *c, *n;
+
+ for (c = expr; c; c = c->next) {
+#if 1
+ switch (c->kind)
+ {
+ case 'I':
+ c->u.declref.ref = finddeclaration(c->u.id);
+ if (c->u.declref.ref) {
+ c->kind = 'A';
+ c->u.declref.id = ADECLREF;
+ } else {
+ error("'%s' undeclared", getstring(idents, c->u.id));
+ }
+ continue;
+ case 'A':
+ if (c->u.id == AIF && c->u.cond.cond) {
+ c->u.cond.cond = foldexpr(c->u.cond.cond);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (c->lhs)
+ c->lhs = foldexpr(c->lhs);
+ if (c->rhs)
+ c->rhs = foldexpr(c->rhs);
+#else
+ if (ruletable[c->kind]) {
+ n = ruletable[c->kind](c);
+
+ if (n != c) {
+ n->prev = c->prev;
+ n->next = c->next;
+ /* deletenode(c) */
+ c = n;
+ }
+ }
+#endif
+ }
+
+ return expr;
+}
+
/* - main-routine - */
int
main(int argc, char **argv) {
+ Env *p;
initkeywords();
initstrmap(&idents);
initstrmap(&strings);
@@ -2136,6 +2345,12 @@ main(int argc, char **argv) {
gettok(false);
}
}
+
+ for (p = pendingenvhead; p; p = p->pendingnext) {
+ if (p->stmts)
+ p->stmts = foldexpr(p->stmts);
+ }
+
popenv();
/* fclose(filein); */