commit 39c53cc7fa3a88942d83ca9852340efd78d7225b
parent 551ac80fec6b0c7862a669bbe1e7b3af4c11584f
Author: m21c <ho*******@gmail.com>
Date: Thu, 5 Aug 2021 22:27:38 +0200
worked declaration parsing (refactoring)
Diffstat:
| M | compiler.c | | | 168 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
1 file changed, 118 insertions(+), 50 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -1801,16 +1801,15 @@ advance:
}
Node *
-exprlist(Source *source, bool isparam, Type *paramtype);
-
-Node *
stmtlist(Source *source, int indent, EnvKind kind);
-Node *
+void
+paramlist(Source *source, Type *selftype);
+
+Decl *
declaration(Source *source, Type *ty) {
- bool has_self_param = false;
+ bool selfparam = false;
Decl *decl = NULL;
- Node *result = NULL;
/*
EnvKind context;
@@ -1827,21 +1826,18 @@ declaration(Source *source, Type *ty) {
context = source->currenv->kind;
*/
+ /* variable name */
if (getkind(source) == 'I') {
decl = makedecl(source, source->tok.u.key, DVAR);
decl->type = ty;
-
- result = makenode(&source->tok, NULL);
- result->kind = ADECL;
- result->type = ty;
- result->u.declref = decl;
gettok(source, true);
+ /* module for variable */
} else if (getkind(source) == 'T') {
Type *module = gettype(source, getbasetype(source, 0));
if (getkind(source) == ODISP || getkind(source) == ':') {
- has_self_param = getkind(source) == ':';
+ selfparam = getkind(source) == ':';
gettok(source, false);
} else {
error(getloc(source), "expected '.' or ':'");
@@ -1850,41 +1846,30 @@ declaration(Source *source, Type *ty) {
/* TODO(m21c): obtain Decl* for
* Type Module:my_decl
* or Type Module.my_decl - declarations */
+
+ /* variable name */
if (getkind(source) == 'I') {
- /*
- module = makenode(module);
- module->kind = ODISP;
- module->rhs = makenode(NULL);
- */
-
- result = makenode(&source->tok, NULL);
- result->kind = ADECL;
- /*
- result->rhs = module;
- */
gettok(source, true);
} else {
error(getloc(source), "expected identifier");
}
} else {
- result = makenode(&source->tok, NULL);
- result->kind = 'T';
- result->type = ty;
-
- return result;
+ return NULL;
}
+ /* function declaration */
if (getkind(source) == OCALL) {
Env *functionenv = NULL;
- Node *params = NULL;
+ Node *body = NULL;
+ /* function params */
gettok(source, false);
if (getkind(source) != ')') {
Decl *param;
functionenv = pushenv(source, SPARAMLIST);
- params = exprlist(source, true, NULL);
+ paramlist(source, NULL);
for (param = functionenv->head; param;
param = param->next)
@@ -1895,24 +1880,21 @@ declaration(Source *source, Type *ty) {
}
expect(source, ')', true, "expected ')'");
+ /* function body */
if (getkind(source) != OASS) {
- Node *stmts;
+ body = stmtlist(source, source->lastindent, SFUNCTION);
- stmts = stmtlist(source, source->lastindent, SFUNCTION);
- result->lhs = stmts;
+ /* function init (body defined by assigment) */
} else if (getkind(source) == OASS) {
- Node *node;
-
gettok(source, false);
functionenv->kind = SFUNCTION;
- node = expr(source, PASSIGN);
- result->lhs = node;
+ body = expr(source, PASSIGN);
popenv(source);
- } else {
- result->lhs = NULL;
+ /* no function body */
+ } else {
popenv(source);
}
@@ -1922,7 +1904,7 @@ declaration(Source *source, Type *ty) {
decl->contentenv = functionenv;
assert(decl->content == NULL);
- decl->content = result->lhs;
+ decl->content = body;
assert(decl->kind == DVAR);
decl->kind = DFUNCTION;
@@ -1933,22 +1915,105 @@ declaration(Source *source, Type *ty) {
/* TODO(m21c): store the params-node (its initializations)
* somewhere */
- return result;
+ return decl;
}
+ /* variable init */
if (getkind(source) == OASS) {
gettok(source, false);
- result->lhs = expr(source, PASSIGN);
-
assert(decl);
- decl->content = result->lhs;
- } else {
- result->lhs = NULL;
+ decl->content = expr(source, PASSIGN);
+ /* no init */
+ } else {
assert(decl);
decl->content = NULL;
}
+ return decl;
+}
+
+Type *
+gettypetuple(Source *source) {
+ if (getkind(source) == LPARDELIM) {
+ Type *ty;
+
+ gettok(source, false);
+
+ ty = gettypetuple(source);
+
+ if (!ty) {
+ error(&source->tok.loc, "expected type");
+ ty = maketype(&source->tok.loc, prim + TERRTYPE, NULL);
+ }
+
+ while (getkind(source) == ',') {
+ ty = maketype(&source->tok.loc, prim + TTUPLE, ty);
+ gettok(source, false);
+ ty->u.rtarget = gettypetuple(source);
+
+ if (!ty->u.rtarget) {
+ error(&source->tok.loc, "expected type");
+ ty->u.rtarget = maketype(&source->tok.loc, prim + TERRTYPE, NULL);
+ }
+ }
+
+ expect(source, ')', true, "expected ')'");
+ return ty;
+ }
+
+ return gettype(source, getbasetype(source, 0));
+}
+
+void
+paramlist(Source *source, Type *selftype) {
+ Type *ty = gettypetuple(source);
+ Decl *decl;
+
+ if (!selftype && !ty) {
+ error(&source->tok.loc, "expected type");
+ return;
+ }
+
+ if (!ty)
+ ty = selftype;
+
+ decl = declaration(source, ty);
+
+ if (!decl)
+ error(&source->tok.loc, "expected declaration");
+
+ while (getkind(source) == ',') {
+ gettok(source, false);
+
+ ty = gettypetuple(source);
+
+ if (!ty && decl)
+ ty = decl->type;
+
+ decl = declaration(source, ty);
+
+ if (!decl)
+ error(&source->tok.loc, "expected declaration");
+ }
+}
+
+Node *
+declarationnode(Source *source, Type *ty) {
+ Node *result = NULL;
+ Decl *decl = declaration(source, ty);
+
+ if (decl) {
+ result = makenode(&source->tok, decl->content);
+ result->type = decl->type;
+ result->u.declref = decl;
+ result->loc = decl->loc;
+ result->kind = ADECL;
+ } else if (ty) {
+ result = makenode(&source->tok, NULL);
+ result->kind = 'T';
+ }
+
return result;
}
@@ -2033,7 +2098,7 @@ recordbody(Source *source, int indent, EnvKind envkind) {
type = getbasetype(source, 0);
type = gettype(source, type);
- declstmt = declaration(source, type);
+ declstmt = declarationnode(source, type);
declstmt = makenode(declstmt, declstmt);
declstmt->kind = ASTMT;
@@ -2060,6 +2125,9 @@ recordbody(Source *source, int indent, EnvKind envkind) {
}
Node *
+exprlist(Source *source, bool isparam, Type *paramtype);
+
+Node *
stmtlist(Source *source, int indent, EnvKind envkind) {
Node *head = NULL, *tail = NULL;
int needindent = nextindent(source, indent);
@@ -2161,7 +2229,7 @@ atom(Source *source, int flags) {
return lhs;
}
- lhs = declaration(source, gettype(source, getbasetype(source, 0)));
+ lhs = declarationnode(source, gettype(source, getbasetype(source, 0)));
if (lhs)
return lhs;
@@ -2512,7 +2580,7 @@ exprlist(Source *source, bool isparam, Type *paramtype) {
/* tail = todeclaration(tail, ¶mtype); */
if (paramtype && getkind(source) == 'I') {
- lhs = declaration(source, paramtype);
+ lhs = declarationnode(source, paramtype);
} else {
lhs = expr(source, PASSIGN);
}
@@ -2534,7 +2602,7 @@ exprlist(Source *source, bool isparam, Type *paramtype) {
if (getkind(source) == 'I' && isdeclaration) {
assert(paramtype);
- rhs = declaration(source, paramtype);
+ rhs = declarationnode(source, paramtype);
typetuple = false;
} else {
rhs = expr(source, PASSIGN);