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:
| M | compiler.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(+);