commit 68d74a51b8354194ab20dcc3f0229190f8218033
parent 30635f0a904334e2f7fc4482f78c9638c561743e
Author: m21c <ho*******@gmail.com>
Date: Sat, 27 Jun 2026 22:15:06 +0200
worked on toplevel use
Diffstat:
| M | compiler.c | | | 113 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
1 file changed, 79 insertions(+), 34 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -30,6 +30,12 @@ typedef unsigned char uchar;
typedef unsigned int uint;
typedef
+struct Source Source;
+
+typedef
+struct Compiler Compiler;
+
+typedef
struct Node Node;
typedef
@@ -610,7 +616,6 @@ struct Env {
SourceArenas *arenas;
};
-typedef
struct Source {
SrcLoc currloc;
@@ -619,6 +624,7 @@ struct Source {
char line[4096];
long linepos;
+ bool hasnewline;
bool handlereplprompt;
/* error-reporting and lexer state */
@@ -646,9 +652,15 @@ struct Source {
/* parser state */
Node *lastis;
+ /* import use */
+ Source *parent;
+ Source *head, *tail;
+ Source *prev, *next;
+ Compiler *compiler;
+
/* stack-alloc save state */
SourceArenas arenas;
-} Source;
+};
struct AnnotParam {
AnnotParamKind kind;
@@ -806,6 +818,22 @@ struct Analysis {
Section *head, *tail;
};
+typedef struct CodeGen CodeGen;
+
+struct CodeGen {
+ FILE *out;
+
+ Env *env;
+ int indent, commacount;
+ bool needsvalue, hasclause;
+ const char *valuename;
+};
+
+struct Compiler {
+ Source *head, *tail;
+ CodeGen cg;
+};
+
// }}}
@@ -1699,7 +1727,6 @@ static int
gettok(Source *source)
{
register int ch = (uchar) peekchar(source);
- static bool hasnewline = false;
source->lastkind = source->tok.kind;
@@ -1710,7 +1737,7 @@ gettok(Source *source)
}
skipwhite:
- if (hasnewline) {
+ if (source->hasnewline) {
if (!mygetline(source)) {
source->lastindent = 0;
return source->tok.kind = 0;
@@ -1750,12 +1777,12 @@ skipwhite:
/* get line */
if (!ch || ch == '#') {
- if (hasnewline) {
+ if (source->hasnewline) {
goto skipwhite;
} else {
/* defer reading new line to next call of gettok()
* and return LINEDELIM */
- hasnewline = true;
+ source->hasnewline = true;
return source->tok.kind = LINEDELIM;
}
}
@@ -1789,7 +1816,7 @@ skipwhite:
goto skipwhite;
}
- hasnewline = false;
+ source->hasnewline = false;
/* identifier or keyword */
if (isalpha(ch) || ch == '_')
@@ -6102,17 +6129,6 @@ extractnestedfunctions(Env *env, Node *expr)
// @section c code generation {{{
-typedef struct CodeGen CodeGen;
-
-struct CodeGen {
- FILE *out;
-
- Env *env;
- int indent, commacount;
- bool needsvalue, hasclause;
- const char *valuename;
-};
-
static void
codegen(CodeGen *cg, Node *expr);
@@ -6138,10 +6154,9 @@ cgprintf(CodeGen *cg, const char *fmt, ...)
}
static void
-cginit(CodeGen *cg, Env *toplevel, FILE *out)
+cginit(CodeGen *cg, FILE *out)
{
cg->out = out;
- cg->env = toplevel;
cg->indent = 0;
cg->commacount = 0;
cg->needsvalue = false;
@@ -6149,7 +6164,6 @@ cginit(CodeGen *cg, Env *toplevel, FILE *out)
cg->valuename = NULL;
assert(cg->out);
- assert(cg->env);
cgprintf(cg, "#include <assert.h>\n");
cgprintf(cg, "#include <stdarg.h>\n");
@@ -8177,7 +8191,8 @@ duplicatestring(String s)
// @section init source {{{
static void
-initsource(Source *source, const char *filename, FILE *file)
+initsource(Source *source, Source *parent, Compiler *compiler,
+ const char *filename, FILE *file)
{
source->filein = file;
source->currloc.filename = filename;
@@ -8193,6 +8208,17 @@ initsource(Source *source, const char *filename, FILE *file)
gettok(source);
if (getkind(source) == LINEDELIM)
gettok(source);
+
+ source->compiler = compiler;
+ source->parent = parent;
+ if (parent)
+ listappend(parent, source);
+}
+
+static void
+disposesource(Source *source)
+{
+ fclose(source->filein);
}
@@ -8303,6 +8329,9 @@ handlelineending(Source *source);
char bundlenamebuffer[1024 * 4];
int bundlenamelength = 0;
+static void
+processfile(Source *source, CodeGen *cg);
+
static bool
processtopleveluse(Source *source, SrcLoc *loc,
const int bundlepath[], int count)
@@ -8312,6 +8341,7 @@ processtopleveluse(Source *source, SrcLoc *loc,
FILE *importfile = NULL;
const char *filename = NULL;
+ Source *curr = NULL;
int i;
@@ -8348,6 +8378,14 @@ processtopleveluse(Source *source, SrcLoc *loc,
bundlenamelength += sizeof(suffix) - 1;
bundlenamebuffer[bundlenamelength] = '\0';
+ /* check for cyclic import */
+ for (curr = source; curr; curr = curr->parent) {
+ if (!strcmp(curr->currloc.filename, bundlenamebuffer)) {
+ error("cyclic import of file '%s'", bundlenamebuffer);
+ return false;
+ }
+ }
+
filename = calloc(bundlenamelength + 1, sizeof*(bundlenamebuffer));
if (!filename) {
@@ -8366,7 +8404,11 @@ processtopleveluse(Source *source, SrcLoc *loc,
warn(loc, "using bundle '%s'", filename);
- fclose(importfile);
+ curr = calloc(1, sizeof*(curr));
+ initsource(curr, source, source->compiler, filename, importfile);
+ processfile(curr, &source->compiler->cg);
+ disposesource(curr);
+
free(filename);
return true;
@@ -8626,19 +8668,19 @@ initintrinsics(Source *source)
}
static void
-processfile(Source *source)
+processfile(Source *source, CodeGen *cg)
{
+ Env *save;
Block *block;
- CodeGen cg = {0};
-
pushenv(source, STOPLEVEL);
block = makeblock(BTOPLEVEL, source->currenv);
appendconduct(block, CSCOPE, NULL);
initintrinsics(source);
- cginit(&cg, source->currenv, fopen("out.c", "wb"));
+ save = cg->env;
+ cg->env = source->currenv;
while (getkind(source) != 0) {
/* printf("token:%i:%i: %c '%.*s'\n", lastline, lastcol + 1,
tok.u.id, currcol - lastcol, line + lastcol);*/
@@ -8665,7 +8707,7 @@ processfile(Source *source)
}
printf("\n");
- cgtoplevel(source, ast, &cg);
+ cgtoplevel(source, ast, cg);
handlelineending(source);
}
@@ -8674,7 +8716,7 @@ processfile(Source *source)
highlight(stdout, HLNONE);
processpendingenvs(source, block);
- cgtoplevelfinish(source, &cg);
+ cgtoplevelfinish(source, cg);
/* dfpopconduct(); */
popenv(source);
@@ -8682,13 +8724,13 @@ processfile(Source *source)
printf("exiting with %u errors and %u warnings ...\n",
errorcount, warningcount);
highlight(stdout, HLNONE);
-
- fclose(cg.out);
+ cg->env = save;
}
int
main(int argc, char **argv)
{
+ Compiler compiler = {};
Source *source = &testsource;
arenas = &source->arenas;
@@ -8704,16 +8746,19 @@ main(int argc, char **argv)
auxself = getstringkey(&idents, "self", 4);
if (argc >= 2) {
- initsource(source, argv[1], fopen(argv[1], "rb"));
+ initsource(source, NULL, &compiler,
+ argv[1], fopen(argv[1], "rb"));
assert(source->filein);
} else {
highlight(stdout, HLPROMPT);
printf("> ");
highlight(stdout, HLNONE);
- initsource(source, "<stdin>", stdin);
+ initsource(source, NULL, &compiler, "<stdin>", stdin);
}
- processfile(source);
+ cginit(&compiler.cg, fopen("out.c", "wb"));
+ processfile(source, &compiler.cg);
+ fclose(compiler.cg.out);
highlight(stdout, HLINFO);
printf("number of nodes: % 6zu\n", arenas->node.top);