Aria

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

commit 00c4195d2cfaff27d6fbad0a368d688595d07063
parent 5220505b31fc359c629bfec08b519d54afbc8cee
Author: m21c <ho*******@gmail.com>
Date:   Mon, 29 Mar 2021 22:19:40 +0200

started implementing declarations & environments

Diffstat:
Maria.c | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 82 insertions(+), 7 deletions(-)

diff --git a/aria.c b/aria.c @@ -65,6 +65,9 @@ mystrcasecmp(const char *str1, const char *str2) typedef struct Node Node; +typedef +struct Decl Decl; + /* - type struct - */ enum { @@ -591,6 +594,7 @@ enum { ASTMT, ADO, ADECL, + ADECLREF, ALOOP, ALOOPUNTIL, AWHILE, @@ -610,6 +614,7 @@ const char *astnames[] = { "Statement", "Do", "Declaration", + "Declaration Reference", "Loop", "Loop-Until", "While", @@ -657,6 +662,11 @@ struct Node { int id; Node *init; } decl; + + struct { + int id; + Decl *ref; + } declref; } u; Node *lhs, *rhs; @@ -1071,9 +1081,6 @@ enum DeclKind { } DeclKind; typedef -struct Decl Decl; - -typedef struct Env Env; struct Decl { @@ -1116,17 +1123,43 @@ int envtop; Env *currenv; Decl * +finddeclinenv(int key, Env *env) +{ + const int cacheindex = (key >> 3) & 0x3f; + const int cachebit = 1 << (key & 0x03); + + Decl *decl; + + if (env->keycache[cacheindex] & cachebit == 0) + return NULL; + + for (decl = env->head; decl; decl = decl->next) { + if (decl->key == key) + return decl; + } + + return NULL; +} + +Decl * makedecl(int key, DeclKind kind) { const int cacheindex = (key >> 3) & 0x3f; const int cachebit = 1 << (key & 0x03); - Decl *decl = declbuf + decltop++; + Decl *probe, *decl = declbuf + decltop++; decl->kind = kind; decl->key = key; assert(currenv); + + probe = finddeclinenv(key, currenv); + + if (probe) { + error("'%s' already declared", getstring(idents, key)); + } + currenv->keycache[cacheindex] |= cachebit; decl->env = currenv; @@ -1518,6 +1551,7 @@ declaration(Node *typenode) { Node *result = typenode; if (tok.kind == 'I') { + Decl *decl = makedecl(tok.u.id, DVAR); result = makenode(typenode); result->kind = 'A'; result->u.decl.id = ADECL; @@ -1556,8 +1590,12 @@ declaration(Node *typenode) { expect(')', true, "expected ')'"); if (tok.kind != 'O' || tok.u.id != OASS) { - Node *stmts = stmtlist(lastindent); + Node *stmts; + + pushenv(SFUNCTION); + stmts = stmtlist(lastindent); result->u.decl.init = stmts; + popenv(); } } @@ -1725,7 +1763,9 @@ atom(int flags) { #else gettok(false); if (tok.kind == '\n') { + pushenv(SSCOPE); lhs = stmtlist(lastindent), lastis = savedis; + popenv(); } else { lhs = exprlist(false, NULL), lastis = savedis; if (lhs->kind == 'T') { @@ -1745,6 +1785,22 @@ atom(int flags) { break; case 'I': + lhs = makenode(NULL); + lhs->u.declref.ref = finddeclaration(lhs->u.id); + + if (lhs->u.declref.ref) { + lhs->kind = 'A'; + lhs->u.declref.id = ADECLREF; + } else { + /* NOTE(m21c): debug code */ + error("'%s' undeclared", getstring(idents, lhs->u.id)); + } + gettok(true); + + if (flags & QCONST) { + /* TODO(m21c): const - conversion */ + } + break; case 'T': case 'N': case 'S': @@ -1805,7 +1861,9 @@ atom(int flags) { gettok(false); lhs->kind = 'A'; lhs->u.id = ADO; + pushenv(SSCOPE); lhs->lhs = stmtlist(indent); + popenv(); break; case KLOOP: indent = lastindent; @@ -1813,7 +1871,9 @@ atom(int flags) { gettok(false); lhs->kind = 'A'; lhs->u.id = ALOOP; + pushenv(SSCOPE); lhs->lhs = stmtlist(indent); + popenv(); if (tok.kind == 'K' && tok.u.id == KUNTIL && lastindent >= indent) @@ -1833,7 +1893,9 @@ atom(int flags) { lhs->kind = 'A'; lhs->u.cond.id = AWHILE; lhs->u.cond.cond = expr(POR); + pushenv(SSCOPE); lhs->lhs = stmtlist(indent); + popenv(); goto joinelse; case KIF: indent = lastindent; @@ -1845,13 +1907,17 @@ atom(int flags) { skipnewline(); if (tok.kind == 'I' && tok.u.id == auxthen) gettok(false); + pushenv(SSCOPE); lhs->lhs = stmtlist(indent); + popenv(); joinelse: if (tok.kind == 'K' && tok.u.id == KELSE && lastindent >= indent) { gettok(false); + pushenv(SSCOPE); lhs->rhs = stmtlist(indent); + popenv(); } break; default: @@ -1989,7 +2055,10 @@ exprlist(bool isparam, Node *paramtype) { if (isparam && (tail->kind != 'A' || tail->u.id != ADECL)) error("expected declaration"); - isdeclaration = tail->kind == 'A' && tail->u.id == ADECL; + if ((isdeclaration = tail->kind == 'A' && tail->u.id == ADECL)) { + paramtype = tail->lhs; + } + typetuple = tail->kind == 'T'; while (tok.kind == ',') { @@ -2010,7 +2079,10 @@ exprlist(bool isparam, Node *paramtype) { (curr->kind != 'A' || curr->u.id != ADECL)) error("expected declaration"); - isdeclaration &= curr->kind == 'A' && curr->u.id == ADECL; + if (curr->kind == 'A' && curr->u.id == ADECL) { + paramtype = tail->lhs; + isdeclaration = true; + } tail->next = curr; tail->next->prev = tail; @@ -2044,6 +2116,8 @@ main(int argc, char **argv) { gettok(false); if (tok.kind == '\n') gettok(false); + + pushenv(STOPLEVEL); while (tok.kind != 0) { /* printf("token:%i:%i: %c '%.*s'\n", lastline, lastcol + 1, tok.u.id, currcol - lastcol, line + lastcol);*/ Node *ast; @@ -2070,6 +2144,7 @@ main(int argc, char **argv) { gettok(false); } } + popenv(); /* fclose(filein); */ /* disposestrmap(&strings); */