Aria

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

commit d63479aedd94770553f2633a887df6e3960c5334
parent fdebc8899fa35fe3c051d4d6a588f3b8f7b7025d
Author: m21c <ho*******@gmail.com>
Date:   Fri, 27 Jun 2025 21:23:22 +0200

refactored main / toplevel

Diffstat:
Mcompiler.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; } // }}}