Aria

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

commit 6919d066b3c2385a73fecf39cb11ac83cdbd97bb
parent ffe4b33eeddf614bae1c96533e365b1532ba4f09
Author: m21c <ho*******@gmail.com>
Date:   Fri, 12 Jun 2026 09:11:56 +0200

re-organize toplevel cg + prepare toplevel use impl

Diffstat:
Mcompiler.c | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 121 insertions(+), 47 deletions(-)

diff --git a/compiler.c b/compiler.c @@ -623,18 +623,10 @@ struct Source { int pendingcount; /* parser state */ - Node *lastis; -} Source; - -typedef struct FieldExpand FieldExpand; -struct FieldExpand { - Type *type; - Field *field; - FieldExpand *parent; - FieldExpand *prev, *next; -}; + /* stack-alloc save state */ +} Source; struct AnnotParam { AnnotParamKind kind; @@ -5983,6 +5975,40 @@ cginit(CodeGen *cg, Env *toplevel, FILE *out) cgprintf(cg, "\n"); } +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); */ + } +} + +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); */ + } +} + #if 0 static void cgtypetail(CodeGen *cg, Type *type) @@ -7750,7 +7776,7 @@ printexpr(FILE *out, Node *expr, int indent) } } n += printexpr(out, expr->lhs, indent); - n += fprintf(out, "\n"); /* blank line */ + // n += fprintf(out, "\n"); /* blank line */ break; case AENV: @@ -7846,8 +7872,8 @@ finish: // @section toplevel bundle & use {{{ +#if 0 typedef struct String String; - struct String { char *string; int length; @@ -7898,7 +7924,6 @@ beginswith(String name, String beginning) return true; } -#if 0 static String duplicatestring(String s) { @@ -8043,6 +8068,78 @@ handlelineending(Source *source); char bundlenamebuffer[1024 * 4]; int bundlenamelength = 0; +static bool +processtopleveluse(Source *source, SrcLoc *loc, const int bundlepath[], int count) +{ + static const char prefix[] = "arialib/"; + static const char suffix[] = ".co"; + + FILE *importfile = NULL; + const char *filename = NULL; + + int i; + + if (sizeof(prefix) - 1 > sizeof(bundlenamebuffer) - 1) + goto errorlength; + + bundlenamelength = sizeof(prefix) - 1; + memcpy(bundlenamebuffer, prefix, sizeof(prefix) - 1); + + for (i = 0; i < count; ++i) { + const int key = bundlepath[i]; + const char *string = getstring(idents, key); + const int length = getlength(idents, key); + + if (length + bundlenamelength > sizeof(bundlenamebuffer) - 1) + goto errorlength; + + memcpy(bundlenamebuffer + bundlenamelength, string, length); + bundlenamelength += length; + + if (i >= count - 1) + continue; + + if (bundlenamelength + 1 > sizeof(bundlenamebuffer) - 1) + goto errorlength; + + bundlenamebuffer[bundlenamelength++] = '/'; + } + + if (bundlenamelength + sizeof(suffix) - 1 > sizeof(bundlenamebuffer) - 1) + goto errorlength; + + memcpy(bundlenamebuffer + bundlenamelength, suffix, sizeof(suffix) - 1); + bundlenamelength += sizeof(suffix) - 1; + bundlenamebuffer[bundlenamelength] = '\0'; + + filename = calloc(bundlenamelength + 1, sizeof*(bundlenamebuffer)); + + if (!filename) { + error(loc, "out of memory"); + return false; + } + + memcpy(filename, bundlenamebuffer, bundlenamelength); + + importfile = fopen(filename, "r"); + + if (!importfile) { + error(loc, "could not open bundle file '%s'", filename); + return false; + } + + warn(loc, "using bundle '%s'", filename); + + fclose(importfile); + free(filename); + + return true; + +errorlength: + error(loc, "bundle path is too long"); + return false; +} + static Node * toplevel(Source *source, Block *block) { @@ -8112,8 +8209,17 @@ redo: } if (getkind(source) == KUSE) { + int bundlepath[64]; + int bundlepathtop = 0; + + SrcLoc loc = *getloc(source); + gettok(source); while (getkind(source) == IDENT) { + const int bundlekey = source->tok.u.key; + + bundlepath[bundlepathtop++] = bundlekey; + gettok(source); if (getkind(source) != ODISP) @@ -8123,6 +8229,8 @@ redo: } handlelineending(source); + + processtopleveluse(source, &loc, bundlepath, bundlepathtop); goto redo; } ast = exprlist(source, false, NULL); @@ -8145,40 +8253,6 @@ redo: } 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); */ - } -} - -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;