Aria

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

commit 18f42c96e78f5b8ee31e00d09f244892bf4bb009
parent aebdaed7fd4a6ee42805f01a347373319e57eefe
Author: m21c <ho*******@gmail.com>
Date:   Thu,  1 Apr 2021 17:07:51 +0200

started implementing semantic-analysis

Diffstat:
Maria.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); */