Aria

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

commit 39c53cc7fa3a88942d83ca9852340efd78d7225b
parent 551ac80fec6b0c7862a669bbe1e7b3af4c11584f
Author: m21c  <ho*******@gmail.com>
Date:   Thu,  5 Aug 2021 22:27:38 +0200

worked declaration parsing (refactoring)

Diffstat:
Mcompiler.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, &paramtype); */ 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);