commit df475c4c0239af35fe211baaa64a6a30165fca45
parent d9f5d116423c707a253e4a7940158002ce47b480
Author: m21c <ho*******@gmail.com>
Date: Sun, 3 Oct 2021 16:23:02 +0200
fixed implcit type declaration after comma
Diffstat:
| M | compiler.c | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
1 file changed, 53 insertions(+), 32 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -268,7 +268,7 @@ struct Decl {
DeclKind kind;
SrcLoc loc;
- Type *type;
+ Type *type, *typemodule;
int key;
@@ -2023,7 +2023,7 @@ static Node *
typecheck(Env *env, Node *expr);
static Node *
-declaration(Source *source, Type *ty)
+declaration(Source *source, Type *ty, bool tryreadtype)
{
bool selfparam = false;
Type *module = NULL;
@@ -2034,6 +2034,16 @@ declaration(Source *source, Type *ty)
EnvKind context;
*/
+ if (tryreadtype) {
+ decl = finddeclaration(source, source->currenv, source->tok.u.key);
+
+ if (decl && decl->kind == DTYPE) {
+ gettok(source);
+ ty = gettype(source, decl->type);
+ tryreadtype = false;
+ }
+ }
+
if (!ty)
return NULL;
@@ -2045,11 +2055,30 @@ declaration(Source *source, Type *ty)
context = source->currenv->kind;
*/
+redodeclaration:
skipnewline(source);
/* variable name */
if (getkind(source) == 'I') {
- decl = finddeclaration(source, source->currenv, source->tok.u.key);
+ int key = source->tok.u.key;
+ SrcLoc loc = source->tok.loc;
+ EnvKind envkind = source->currenv->kind;
+
+ gettok(source);
+
+ if (tryreadtype && (envkind == SSTRUCT || envkind == SUNION)) {
+ if (!isbasicdelimiter(getkind(source)) &&
+ getkind(source) != '(')
+ {
+ decl = defertypedeclaration(source, key);
+ decl->loc = loc;
+ ty = gettype(source, decl->type);
+ tryreadtype = false;
+ goto redodeclaration;
+ }
+ }
+
+ decl = finddeclaration(source, source->currenv, key);
if (decl && decl->kind != DFUNCTION && decl->kind != DPARAM &&
decl->kind != DVAR)
@@ -2059,15 +2088,15 @@ declaration(Source *source, Type *ty)
goto readvarmodule;
}
- decl = makedecl(source, source->tok.u.key, DVAR);
+ decl = makedecl(source, key, DVAR);
+ decl->loc = loc;
decl->type = ty;
- gettok(source);
/* module for variable */
} else if (getkind(source) == 'T') {
module = source->tok.type;
+ gettok(source);
readvarmodule:
- gettok(source);
module = gettype(source, module);
if (getkind(source) == ODISP || getkind(source) == ':') {
@@ -2085,6 +2114,7 @@ declaration(Source *source, Type *ty)
if (getkind(source) == 'I') {
decl = makedecl(source, source->tok.u.key, DVAR);
decl->type = ty;
+ decl->typemodule = module;
gettok(source);
} else {
error(getloc(source), "expected identifier");
@@ -2223,7 +2253,7 @@ readident(Source *source, int flags)
}
if (decl && decl->kind == DTYPE) {
- lhs = declaration(source, gettype(source, decl->type));
+ lhs = declaration(source, gettype(source, decl->type), false);
return lhs;
}
@@ -2383,7 +2413,7 @@ readatom(Source *source, int flags)
skipnewline(source);
expect(source, ')', "expected ')'");
- lhs = declaration(source, gettype(source, ty));
+ lhs = declaration(source, gettype(source, ty), false);
assert(lhs);
return lhs;
@@ -2403,7 +2433,7 @@ readatom(Source *source, int flags)
do {
Type *type = source->tok.type;
gettok(source);
- lhs = declaration(source, gettype(source, type));
+ lhs = declaration(source, gettype(source, type), false);
} while (0);
break;
@@ -2421,7 +2451,7 @@ readatom(Source *source, int flags)
case KVAR:
gettok(source);
- lhs = declaration(source, prim + TINFER);
+ lhs = declaration(source, prim + TINFER, false);
break;
case KFALSE:
@@ -2708,7 +2738,7 @@ exprlist(Source *source, bool isparam, Type *paramtype)
/* tail = todeclaration(tail, ¶mtype); */
if (paramtype && getkind(source) == 'I') {
- lhs = declaration(source, paramtype);
+ lhs = declaration(source, paramtype, false);
} else {
lhs = readexpr(source, PASSIGN);
}
@@ -2748,26 +2778,8 @@ exprlist(Source *source, bool isparam, Type *paramtype)
gettok(source);
if (getkind(source) == 'I' && isdeclaration) {
- Decl *decl = finddeclaration(source, source->currenv, source->tok.u.key);
-
- if (decl && decl->kind == DTYPE) {
- Type *type;
- gettok(source);
-
- /* FIXME(m21c): this still does not fix it
- * entirely. in records with
- * implicit forwad-declaration
- * it wouldn't recognize it as
- * Type. it would have to check
- * it based on the next token. */
-
- type = gettype(source, decl->type);
- rhs = declaration(source, type);
- } else {
- assert(paramtype);
- rhs = declaration(source, paramtype);
- typetuple = false;
- }
+ rhs = declaration(source, paramtype, true);
+ typetuple = false;
} else {
rhs = readexpr(source, PASSIGN);
typetuple &= rhs->kind == 'T';
@@ -4036,11 +4048,20 @@ printdeclaration(FILE *out, Decl *decl, int indent)
n += printtype(out, decl->type, indent);
}
+ if (decl->typemodule) {
+ n += fprintf(out, " ");
+ n += printtype(out, decl->typemodule, indent);
+ n += highlight(out, HLDELIM);
+ n += fprintf(out, ".");
+ } else {
+ n += fprintf(out, " ");
+ }
+
n += highlight(out,
decl->kind == DFUNCTION ? HLFUNCTIONDECL :
decl->kind == DPARAM ? HLPARAMDECL :
HLDECL);
- n += fprintf(out, " %s", getstring(idents, decl->key));
+ n += fprintf(out, "%s", getstring(idents, decl->key));
if (decl->kind == DFUNCTION) {
Decl *param, *head = NULL;