Aria

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

commit 57e2b308acc28de482a3c23710143d81337e42da
parent 6afdc62d5cf0b002c0b42cd7d5e6c30c8237d321
Author: m21c  <ho*******@gmail.com>
Date:   Sat,  2 Oct 2021 23:22:05 +0200

improved environment kinds + added prompt text that contains the environment-path

Diffstat:
Mcompiler.c | 174++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 132 insertions(+), 42 deletions(-)

diff --git a/compiler.c b/compiler.c @@ -172,7 +172,13 @@ enum EnvKind { SPARAMLIST, SFUNCTION, SSCOPE, - SRECORD, + SDO, + SLOOP, + SWHILE, + SIF, + SELSE, + SSTRUCT, + SUNION, /* SUNION, SSTRUCT, @@ -284,7 +290,7 @@ struct Env { Decl *head, *tail; Node *stmts; - Decl *funcdecl; /* for SFUNCTION */ + Decl *envdecl; /* for SFUNCTION, SSTRUCT, SUNION */ Env *below; @@ -626,14 +632,7 @@ mystrcasecmp(const char *str1, const char *str2) /* - pre-lexer - */ static void -tryprompt(Source *source, const char ch) -{ - if (source->handlereplprompt) { - fprintf(stdout, "\e[35m%c \e[0m", ch); - } else if (source->filein == stdin) { - source->handlereplprompt = true; - } -} +tryprompt(Source *source, const char ch); static bool mygetline(Source *source) @@ -1910,7 +1909,7 @@ static Node * exprlist(Source *source, bool isparam, Type *paramtype); static Node * -stmtlist(Source *source, int indent, EnvKind envkind) +stmtlist(Source *source, int indent, EnvKind envkind, Decl *envdecl) { Node *head = NULL, *tail = NULL; int needindent = nextindent(source, indent); @@ -1918,6 +1917,19 @@ stmtlist(Source *source, int indent, EnvKind envkind) Env *env = NULL; /* printf("needident: %d, currindent: %d, lastindent: %d\n", needindent, currindent, lastindent); */ + if (envkind != SFUNCTION || !source->currenv || + source->currenv->kind != SPARAMLIST) + { + /* NOTE(m21c): if there already is a + * paramlist-environment and we want a + * function-environment, we just use + * paramlist as our function-environment. + * Else, we push a new environment */ + env = pushenv(source, envkind); + env->envdecl = envdecl; + } + + for (;;) { Node *stmt; @@ -1925,18 +1937,6 @@ stmtlist(Source *source, int indent, EnvKind envkind) "expected expression")) break; - if (!env && - (envkind != SFUNCTION || !source->currenv || - source->currenv->kind != SPARAMLIST)) - { - /* NOTE(m21c): if there already is a - * paramlist-environment and we want a - * function-environment, we just use - * paramlist as our function-environment. - * Else, we push a new environment */ - env = pushenv(source, envkind); - } - stmt = exprlist(source, false, NULL); stmt = tokennode(source, stmt); @@ -1960,16 +1960,18 @@ stmtlist(Source *source, int indent, EnvKind envkind) env = source->currenv; popenv(source); - } else if (env) { + } else if (head) { head = tokennode(source, head); head->kind = ASCOPE; head->u.env = env; env->stmts = head; popenv(source); + } else { + popenv(source); + /* deleteenv(env); */ } - return head; } @@ -2082,6 +2084,7 @@ declaration(Source *source, Type *ty) int savedtop; functionenv = pushenv(source, SPARAMLIST); + functionenv->envdecl = decl; paramlist = exprlist(source, true, NULL); /* deletenode(paramlist); */ @@ -2097,7 +2100,8 @@ declaration(Source *source, Type *ty) /* function body */ if (getkind(source) != OASS) { - body = stmtlist(source, source->lastindent, SFUNCTION); + body = stmtlist(source, source->lastindent, + SFUNCTION, decl); /* function init (body defined by assigment) */ } else if (getkind(source) == OASS) { @@ -2163,10 +2167,14 @@ readident(Source *source, int flags) SrcLoc loc = source->tok.loc; int key = source->tok.u.key; + EnvKind envkind = source->currenv + ? source->currenv->kind + : STOPLEVEL; + decl = finddeclaration(source, source->currenv, source->tok.u.key); gettok(source); - if (source->currenv->kind == SRECORD && !decl) { + if (!decl && (envkind == SSTRUCT || envkind == SUNION)) { if (!isbasicdelimiter(getkind(source))) { decl = defertypedeclaration(source, key); decl->loc = loc; @@ -2205,7 +2213,14 @@ readrecord(Source *source, bool isunion) Node *recordnode; Decl *module; int indent = source->lastindent; - int key = 0; + + EnvKind envkind = SSTRUCT; + TypeKind typekind = TSTRUCT; + + if (isunion) { + envkind = SUNION; + typekind = TUNION; + } recordnode = tokennode(source, NULL); recordnode->kind = getkind(source); @@ -2217,19 +2232,24 @@ readrecord(Source *source, bool isunion) } else { error(getloc(source), "expected identifier"); } - /* recordnode->rhs = recordbody(source, indent, SSCOPE); */ + + module = makedecl(source, recordnode->lhs->u.key, DTYPE); + + if (module->type->module == module) { + *module->type = prim[TSTRUCT]; + } else { + module->type = maketype(&recordnode->loc, prim + typekind, NULL); + } + + module->type->module = module; + recordnode->type = module->type; /* TODO(m21c): check for new-line and only then read body */ - recordnode->rhs = stmtlist(source, indent, SRECORD); + recordnode->rhs = stmtlist(source, indent, envkind, module); /* TODO(m21c): validate record body, extract declarations, * compute size and align, resolve aliases */ - module = makedecl(source, recordnode->lhs->u.key, DTYPE); - module->type = maketype(&recordnode->loc, prim + TSTRUCT, NULL); - - module->type->module = module; - return recordnode; } @@ -2294,7 +2314,7 @@ readatom(Source *source, int flags) if (getkind(source) == '\n') { /* FIXME(m21c): stmtlist should ignore indentation in * this case! */ - lhs = stmtlist(source, source->lastindent, SSCOPE); + lhs = stmtlist(source, source->lastindent, SSCOPE, NULL); source->lastis = savedis; } else { lhs = exprlist(source, false, NULL); @@ -2435,7 +2455,7 @@ readatom(Source *source, int flags) lhs = tokennode(source, NULL); gettok(source); lhs->kind = ADO; - lhs->lhs = stmtlist(source, indent, SSCOPE); + lhs->lhs = stmtlist(source, indent, SDO, NULL); break; @@ -2444,7 +2464,7 @@ readatom(Source *source, int flags) lhs = tokennode(source, NULL); gettok(source); lhs->kind = ALOOP; - lhs->lhs = stmtlist(source, indent, SSCOPE); + lhs->lhs = stmtlist(source, indent, SLOOP, NULL); if (getkind(source) == KUNTIL && source->lastindent >= indent) { lhs->kind = ALOOPUNTIL; @@ -2463,7 +2483,7 @@ readatom(Source *source, int flags) gettok(source); lhs->kind = AWHILE; lhs->u.payload = readexpr(source, POR); - lhs->lhs = stmtlist(source, indent, SSCOPE); + lhs->lhs = stmtlist(source, indent, SWHILE, NULL); goto joinelse; @@ -2473,16 +2493,16 @@ readatom(Source *source, int flags) gettok(source); lhs->kind = AIF; lhs->u.payload = readexpr(source, POR); - skipnewline(source); + /* skipnewline(source); */ if (getkind(source) == 'I' && source->tok.u.key == auxthen) gettok(source); - lhs->lhs = stmtlist(source, indent, SSCOPE); + lhs->lhs = stmtlist(source, indent, SIF, NULL); joinelse: if (getkind(source) == KELSE && source->lastindent >= indent) { gettok(source); - lhs->rhs = stmtlist(source, indent, SSCOPE); + lhs->rhs = stmtlist(source, indent, SELSE, NULL); } break; @@ -3517,6 +3537,73 @@ foldexpr(Env *env, Node *expr) /* - print ast - */ +static void +promptenvpath(Env* currenv) +{ + const char *envstring = "environment"; + + if (currenv && currenv->kind != STOPLEVEL) { + promptenvpath(currenv->below); + + switch (currenv->kind) { + case SFUNCTION: + case SPARAMLIST: + envstring = "function"; + break; + case SSTRUCT: + envstring = "struct"; + break; + case SUNION: + envstring = "union"; + break; + case SSCOPE: + envstring = "scope"; + break; + case SIF: + envstring = "if"; + break; + case SELSE: + envstring = "else"; + break; + case SDO: + envstring = "do"; + break; + case SLOOP: + envstring = "loop"; + break; + case SWHILE: + envstring = "while"; + break; + default: + break; + } + + if (currenv->envdecl) { + int key = currenv->envdecl->key; + envstring = getstring(idents, key); + } + + fprintf(stdout, "%s/", envstring); + } +} + +static void +tryprompt(Source *source, const char ch) +{ + if (source->handlereplprompt) { + Env *currenv = source->currenv; + if (ch == '.' && currenv && currenv->kind != STOPLEVEL) { + fputs("\e[34m", stdout); + promptenvpath(currenv); + fprintf(stdout, "\n\e[35m%c \e[0m", ch); + } else { + fprintf(stdout, "\e[35m%c \e[0m", ch); + } + } else if (source->filein == stdin) { + source->handlereplprompt = true; + } +} + typedef enum Highlight { HLNONE = 0, @@ -3762,6 +3849,9 @@ printclause(FILE *out, Node *expr, int indent) { int n = 0; + if (!expr) + return 0; + if (isclauseorempty(expr)) { n += fprintf(out, " "); n += printexpr(out, expr, indent);