Aria

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

commit 68d74a51b8354194ab20dcc3f0229190f8218033
parent 30635f0a904334e2f7fc4482f78c9638c561743e
Author: m21c <ho*******@gmail.com>
Date:   Sat, 27 Jun 2026 22:15:06 +0200

worked on toplevel use

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