commit d63479aedd94770553f2633a887df6e3960c5334
parent fdebc8899fa35fe3c051d4d6a588f3b8f7b7025d
Author: m21c <ho*******@gmail.com>
Date: Fri, 27 Jun 2025 21:23:22 +0200
refactored main / toplevel
Diffstat:
| M | compiler.c | | | 334 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 248 insertions(+), 86 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -7706,112 +7706,151 @@ finish:
return mygetline(source);
}
-int
-main(int argc, char **argv)
-{
- Env *p;
- Block *block;
+static void
+handlelineending(Source *source);
- Source *source = &testsource;
- source->tabwidth = 8;
+char bundlenamebuffer[1024 * 4];
+int bundlenamelength = 0;
- initkeywords();
- initstrmap(&idents);
- initstrmap(&strings);
+static Node *
+toplevel(Source *source, Block *block)
+{
+ Node *ast;
- auxthen = getstringkey(&idents, "then", 4);
+redo:
+ readannots(source);
+ if (getkind(source) == KBUNDLE) {
+ SrcLoc loc = *getloc(source);
+#if 0
+ int bundlekey = 0;
+ gettok(source);
+ while (getkind(source) == IDENT) {
+ char *name = getstring(idents, source->tok.u.key);
+ int length = getlength(idents, source->tok.u.key);
- if (argc >= 2) {
- initsource(source, argv[1], fopen(argv[1], "rb"));
- assert(source->filein);
- } else {
- highlight(stdout, HLPROMPT);
- printf("> ");
- highlight(stdout, HLNONE);
- initsource(source, "<stdin>", stdin);
- }
+ /* @fixme check name length */
+ memcpy(bundlenamebuffer + bundlenamelength, name, length);
+ bundlenamelength += length;
+ gettok(source);
+ bundlenamebuffer[bundlenamelength] = '\0';
- pushenv(source, STOPLEVEL);
- block = makeblock(BTOPLEVEL, source->currenv);
- appendconduct(block, CSCOPE, NULL);
- while (getkind(source) != 0) {
- /* printf("token:%i:%i: %c '%.*s'\n", lastline, lastcol + 1,
- tok.u.id, currcol - lastcol, line + lastcol);*/
- Node *ast;
+ if (getkind(source) != ODISP)
+ break;
- readannots(source);
- ast = exprlist(source, false, NULL);
- /* ast = readexpr(source, PSTART); */
- /*
- printast(ast, 0);
- printf("\n");
- */
- if (ast->kind != ADECL ||
- !ast->u.payload ||
- ast->u.payload->kind != ASCOPE)
- {
- ast = typecheck(source->currenv, ast);
- ast = foldexpr(source->currenv, ast);
- dataflow(block, ast);
+ gettok(source);
+ bundlenamebuffer[bundlenamelength++] = '_';
+ bundlenamebuffer[bundlenamelength] = '\0';
}
- if (source->filein == stdin) {
- highlight(stdout, HLINFO);
- fputs("= ", stdout);
- highlight(stdout, HLNONE);
+ if (bundlenamelength) {
+ bundlekey = getstringkey(&idents, bundlenamebuffer,
+ bundlenamelength);
+ assert(source->currenv);
+ source->currenv->bundle = makedecl(source, bundlekey,
+ DBUNDLE);
+ source->currenv->loc = loc;
}
+#else
+ Decl *bundle = NULL;
+ gettok(source);
+ while (getkind(source) == IDENT) {
+ const int bundlekey = source->tok.u.key;
- printexpr(stdout, ast, 0);
- highlight(stdout, HLNONE);
+ assert(source->currenv);
+ bundle = makebundle(source, bundlekey, bundle);
- if (source->filein == stdin) {
- highlight(stdout, HLINFO);
- fputs(" : ", stdout);
- printtype(stdout, ast->type, 0);
- highlight(stdout, HLNONE);
+ gettok(source);
+
+ if (getkind(source) != ODISP)
+ break;
+
+ gettok(source);
}
- printf("\n");
- /* deletenode(ast); */
+ if (bundle) {
+ source->currenv->bundle = bundle;
+ source->currenv->loc = loc;
+ } else {
+ /* @note is this correct? */
+ source->currenv->bundle = NULL;
+ }
+#endif
- if (getkind(source) == LINEDELIM) {
- if (source->filein == stdin) {
- highlight(stdout, HLPROMPT);
- printf("> ");
- highlight(stdout, HLNONE);
- source->handlereplprompt = false;
- }
+ handlelineending(source);
+ goto redo;
+ }
+
+ if (getkind(source) == KUSE) {
+ gettok(source);
+ while (getkind(source) == IDENT) {
gettok(source);
- } else if (getkind(source) == SEMIDELIM) {
+
+ if (getkind(source) != ODISP)
+ break;
+
gettok(source);
}
- if (source->lastkind != SEMIDELIM &&
- source->lastkind != LINEDELIM)
- {
- error(getloc(source), "expected new line");
- while (getkind(source) != SEMIDELIM &&
- getkind(source) != LINEDELIM &&
- getkind(source) != 0)
- {
- gettok(source);
- }
+ handlelineending(source);
+ goto redo;
+ }
+ ast = exprlist(source, false, NULL);
+ /* ast = readexpr(source, PSTART); */
+ /*
+ printast(ast, 0);
+ printf("\n");
+ */
+ if (ast->kind != ADECL ||
+ !ast->u.payload ||
+ ast->u.payload->kind != ASCOPE)
+ {
+ ast = typecheck(source->currenv, ast);
+ ast = foldexpr(source->currenv, ast);
+ dataflow(block, ast);
+ }
+ ast = extractnestedfunctions(source->currenv, ast);
- if (source->filein == stdin) {
- highlight(stdout, HLPROMPT);
- printf("> ");
- highlight(stdout, HLNONE);
- source->handlereplprompt = false;
- }
+ return ast;
+}
- if (getkind(source) != 0)
- gettok(source);
- }
+static void
+cgtoplevel(Source *source, Node *ast, CodeGen *cg)
+{
+ if (source->haspendingenv) {
+ assert(source->pendingcount < 512);
+ source->pendingnodes[source->pendingcount++] = ast;
+ source->haspendingenv = false;
+ } else {
+ codegen(cg, ast);
+ if (ast->kind != ADECL || ast->u.declref->kind != DFUNCTION)
+ cgprintf(cg, ";\n");
+ else
+ cgprintf(cg, "\n");
+ /* deletenode(ast); */
}
+}
- highlight(stdout, HLINFO);
- puts("dump pending environments ...");
- highlight(stdout, HLNONE);
+static void
+cgtoplevelfinish(Source *source, CodeGen *cg)
+{
+ int i;
+
+ for (i = 0; i < source->pendingcount; ++i) {
+ Node *ast = source->pendingnodes[i];
+
+ codegen(cg, ast);
+ if (ast->kind != ADECL || ast->u.declref->kind != DFUNCTION)
+ cgprintf(cg, ";\n");
+ else
+ cgprintf(cg, "\n");
+ /* deletenode(ast); */
+ }
+}
+
+static void
+processpendingenvs(Source *source, Block *block)
+{
+ Env *p;
for (p = source->pendingenvhead; p; p = p->pendingnext) {
if (p->stmts) {
@@ -7834,17 +7873,140 @@ main(int argc, char **argv)
}
}
+}
+
+static void
+handlelineending(Source *source)
+{
+ if (getkind(source) == LINEDELIM) {
+ if (source->filein == stdin) {
+ highlight(stdout, HLPROMPT);
+ printf("> ");
+ highlight(stdout, HLNONE);
+ source->handlereplprompt = false;
+ }
+ gettok(source);
+ } else if (getkind(source) == SEMIDELIM) {
+ gettok(source);
+ }
+
+ if (source->lastkind != SEMIDELIM && source->lastkind != LINEDELIM){
+ error(getloc(source), "expected new line");
+ while (getkind(source) != SEMIDELIM &&
+ getkind(source) != LINEDELIM &&
+ getkind(source) != 0)
+ {
+ gettok(source);
+ }
+
+ if (source->filein == stdin) {
+ highlight(stdout, HLPROMPT);
+ printf("> ");
+ highlight(stdout, HLNONE);
+ source->handlereplprompt = false;
+ }
+
+ if (getkind(source) != 0)
+ gettok(source);
+ }
+}
+
+static void
+processfile(Source *source)
+{
+ Block *block;
+ Decl *intrinsic;
+
+ CodeGen cg = {0};
+
+ pushenv(source, STOPLEVEL);
+ block = makeblock(BTOPLEVEL, source->currenv);
+ appendconduct(block, CSCOPE, NULL);
+
+ intrinsic = makedecl(source, getstringkey(&idents, "printf", 6), DFUNCTION);
+ intrinsic->type = maketype(&source->tok.loc, primitive(TFUNCTION), NULL);
+ intrinsic->type->u.rtarget = primitive(TINT);
+
+ cginit(&cg, source->currenv, fopen("out.c", "wb"));
+ while (getkind(source) != 0) {
+ /* printf("token:%i:%i: %c '%.*s'\n", lastline, lastcol + 1,
+ tok.u.id, currcol - lastcol, line + lastcol);*/
+ Node *ast = toplevel(source, block);
+
+ highlight(stdout, HLINFO);
+ printf("number of nested functions: %u\n", extractedtop - 1);
+ highlight(stdout, HLNONE);
+
+ if (source->filein == stdin) {
+ highlight(stdout, HLINFO);
+ fputs("= ", stdout);
+ highlight(stdout, HLNONE);
+ }
+
+ printexpr(stdout, ast, 0);
+ highlight(stdout, HLNONE);
+
+ if (source->filein == stdin) {
+ highlight(stdout, HLINFO);
+ fputs(" : ", stdout);
+ printtype(stdout, ast->type, 0);
+ highlight(stdout, HLNONE);
+ }
+ printf("\n");
+
+ cgtoplevel(source, ast, &cg);
+ handlelineending(source);
+ }
+
+ highlight(stdout, HLINFO);
+ puts("dump pending environments ...");
+ highlight(stdout, HLNONE);
+
+ processpendingenvs(source, block);
+ cgtoplevelfinish(source, &cg);
/* dfpopconduct(); */
popenv(source);
highlight(stdout, HLINFO);
- puts("exiting ...\x1b[0m");
+ printf("exiting with %u errors and %u warnings ...\x1b[0m\n",
+ errorcount, warningcount);
+
+ fclose(cg.out);
+}
+
+int
+main(int argc, char **argv)
+{
+ Source *source = &testsource;
+
+ initkeywords();
+ initstrmap(&idents);
+ initstrmap(&strings);
+
+ auxthen = getstringkey(&idents, "then", 4);
+ auxin = getstringkey(&idents, "in", 2);
+ auxto = getstringkey(&idents, "to", 2);
+ auxstep = getstringkey(&idents, "step", 4);
+
+ auxself = getstringkey(&idents, "self", 4);
+
+ if (argc >= 2) {
+ initsource(source, argv[1], fopen(argv[1], "rb"));
+ assert(source->filein);
+ } else {
+ highlight(stdout, HLPROMPT);
+ printf("> ");
+ highlight(stdout, HLNONE);
+ initsource(source, "<stdin>", stdin);
+ }
+
+ processfile(source);
/* fclose(source->filein); */
/* disposestrmap(&strings); */
/* disposestrmap(&idents); */
- return 0;
+ return !!errorcount;
}
// }}}