Aria

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

commit d9755153f789f89bbe8f49183565ed14961affa2
parent 0ad38dae916ab3d590ccb4a79be39c3c05b6146f
Author: m21c  <ho*******@gmail.com>
Date:   Sun,  3 Oct 2021 19:44:00 +0200

fixed typecheck for implicit var/function forward declaration

Diffstat:
Mcompiler.c | 67++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/compiler.c b/compiler.c @@ -1896,8 +1896,8 @@ checkend(Source *source, bool hastail, int needindent, gettok(source); /* NOTE(m21c): used for REPL. it allows having - * semicolons on line-endings and nultiple - * adjacent semecolons in REPL-mode. */ + * semicolons on line-endings and nultiple + * adjacent semecolons in REPL-mode. */ if (getkind(source) == ';' || getkind(source) == '\n') { /* TODO(m21c): output an error-message if not in REPL-mode */ } @@ -1954,9 +1954,9 @@ stmtlist(Source *source, int indent, EnvKind envkind, if (reuseenv) { assert(env == NULL); env = source->currenv; + } - popenv(source); - } else if (head) { + if (head) { head = tokennode(source, head); head->kind = ASCOPE; head->u.env = env; @@ -1965,7 +1965,7 @@ stmtlist(Source *source, int indent, EnvKind envkind, popenv(source); } else { popenv(source); - /* deleteenv(env); */ + /* if (!reuseenv) deleteenv(env); */ } return head; @@ -2114,6 +2114,7 @@ redodeclaration: } else { error(getloc(source), "expected identifier"); } + /* just return a node for the type */ } else { result = tokennode(source, NULL); result->kind = 'T'; @@ -2262,7 +2263,7 @@ readident(Source *source, int flags) } else { deferfuncenv(source, key); lhs->kind = 'I'; - lhs->type = prim + TERRTYPE; + lhs->type = prim + TVOID; lhs->u.key = key; } @@ -3101,9 +3102,36 @@ typecheckdecl(Env *env, Decl *decl) } static Node * -typecheck(Env *env, Node *expr) +resolvepending(Env *env, Node *expr) { + Decl *decl; + + assert(expr->kind == 'I'); + + decl = finddeclaration(NULL, env, expr->u.key); + + if (!decl) { + error(&expr->loc, "'%s' undeclared", + getstring(idents, expr->u.key)); + return expr; + } + + if (decl->kind != DVAR && decl->kind != DFUNCTION) { + error(&expr->loc, "'%s' is not a variable nor a function", + getstring(idents, expr->u.key)); + return expr; + } + expr->kind = ADECLREF; + expr->u.declref = decl; + expr->type = decl->type; + + return typecheck(env, expr); +} + +static Node * +typecheck(Env *env, Node *expr) +{ Node *lhs = expr->lhs, *rhs = expr->rhs; switch (getnumops(expr->kind)) { @@ -3385,6 +3413,11 @@ typecheck(Env *env, Node *expr) expr->lhs = typecheck(env, expr->lhs); expr->lhs = conv(expr->lhs); + return expr; + + case 'I': + return resolvepending(env, expr); + default: return expr; } @@ -3437,26 +3470,6 @@ foldexpr(Env *env, Node *expr) } switch ((int) expr->kind) { - case IDENT: - do { - Decl *declref = finddeclaration(NULL, env, expr->u.key); - - if (declref) { - expr->kind = ADECLREF; - expr->u.declref = declref; - expr->type = declref->type; - } else if (env->kind != STOPLEVEL) { - /* TODO(m21c): recreate Env-stack after parsing-pass */ - error( - &expr->loc, - "'%s' undeclared", - getstring(idents, expr->u.key) - ); - } - } while (0); - - return expr; - case OADD: case OSUB: if (lhs->kind == 'N' && rhs->kind == 'N') { if (expr->kind == OADD) evalbinary(+);