commit 00c4195d2cfaff27d6fbad0a368d688595d07063
parent 5220505b31fc359c629bfec08b519d54afbc8cee
Author: m21c <ho*******@gmail.com>
Date: Mon, 29 Mar 2021 22:19:40 +0200
started implementing declarations & environments
Diffstat:
| M | aria.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); */