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