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