Separate out build_if into a pass

This commit is contained in:
Krzosa Karol
2024-04-14 09:14:57 +02:00
parent 5a2e3dcec4
commit 320a13ddfd
13 changed files with 83 additions and 94 deletions

View File

@@ -1,4 +1,5 @@
thread_local LC_Map DebugASTMap;
thread_local bool DebugInsideDiscarded;
void DebugVerify_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
bool created = LC_InsertWithoutReplace(&DebugASTMap, n, (void *)(intptr_t)100);
@@ -23,7 +24,7 @@ void DebugVerify_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
}
}
if (LC_IsType(n) && ctx->inside_discarded == 0) {
if (LC_IsType(n) && DebugInsideDiscarded == false) {
if (!n->type) {
LC_ReportASTError(n, "typespec doesn't hold type");
}
@@ -42,7 +43,7 @@ void DebugVerify_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
}
}
bool should_have_type = parent_is_builtin == false && ctx->inside_note == 0 && ctx->inside_discarded == 0;
bool should_have_type = parent_is_builtin == false && ctx->inside_note == 0 && DebugInsideDiscarded == false;
if (should_have_type && !n->type) {
LC_ReportASTError(n, "expression doesn't have type");
}
@@ -78,8 +79,7 @@ void VerifyASTCopy(LC_ASTRefList packages) {
{
LC_ASTWalker walker = LC_GetDefaultWalker(L->arena, VerifyCopy_Walk);
walker.visit_notes = walker.visit_discarded = true;
walker.user_data = (void *)&copy_counter;
walker.user_data = (void *)&copy_counter;
LC_WalkAST(&walker, copy);
walker.user_data = (void *)&original_counter;
LC_WalkAST(&walker, copy);
@@ -101,13 +101,15 @@ void DebugVerifyAST(LC_ASTRefList packages) {
LC_MapReserve(&DebugASTMap, 4096);
LC_ASTWalker walker = LC_GetDefaultWalker(L->arena, DebugVerify_WalkAST);
walker.visit_notes = walker.visit_discarded = true;
for (LC_ASTRef *it = packages.first; it; it = it->next) {
LC_WalkAST(&walker, it->ast);
}
walker.visit_notes = true;
for (LC_ASTRef *it = packages.first; it; it = it->next) LC_WalkAST(&walker, it->ast);
LC_WalkAST(&walker, L->tstring->decl->ast);
LC_WalkAST(&walker, L->tany->decl->ast);
DebugInsideDiscarded = true;
for (LC_ASTRef *it = L->discarded.first; it; it = it->next) LC_WalkAST(&walker, it->ast);
DebugInsideDiscarded = false;
for (int i = 0; i < L->ast_count; i += 1) {
LC_AST *it = (LC_AST *)L->ast_arena->memory.data + i;
if (it == L->builtin_package) continue;

View File

@@ -277,6 +277,7 @@ void RunTestFile(TestDesc it) {
L->first_package = name;
LC_ParsePackagesUsingRegistry(name);
LC_BuildIfPass();
if (L->errors) {
result = Failed_Parse;
goto end_of_test;

View File

@@ -19,12 +19,6 @@ LC_FUNCTION LC_AST *LC_CopyAST(LC_Arena *arena, LC_AST *n) {
LC_AST *it_copy = LC_CopyAST(arena, it);
LC_DLLAdd(result->afile.fdecl, result->afile.ldecl, it_copy);
}
LC_ASTFor(it, n->afile.fdiscarded) {
LC_AST *it_copy = LC_CopyAST(arena, it);
LC_DLLAdd(result->afile.fdiscarded, result->afile.ldiscarded, it_copy);
}
result->afile.build_if = n->afile.build_if;
} break;
case LC_ASTKind_DeclProc: {

View File

@@ -58,10 +58,6 @@ LC_FUNCTION void LC_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
case LC_ASTKind_Package: {
LC_ASTFor(it, n->apackage.ffile) LC_WalkAST(ctx, it);
ctx->inside_discarded += 1;
if (ctx->visit_discarded) LC_ASTFor(it, n->apackage.fdiscarded) LC_WalkAST(ctx, it);
ctx->inside_discarded -= 1;
} break;
case LC_ASTKind_File: {
@@ -70,10 +66,6 @@ LC_FUNCTION void LC_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
if (ctx->visit_notes == false && it->kind == LC_ASTKind_DeclNote) continue;
LC_WalkAST(ctx, it);
}
ctx->inside_discarded += 1;
if (ctx->visit_discarded) LC_ASTFor(it, n->afile.fdiscarded) LC_WalkAST(ctx, it);
ctx->inside_discarded -= 1;
} break;
case LC_ASTKind_DeclProc: {

View File

@@ -369,12 +369,8 @@ struct LC_ASTFile {
LC_AST *limport;
LC_AST *fdecl;
LC_AST *ldecl;
LC_AST *fdiscarded;
LC_AST *ldiscarded; // @build_if
LC_Token *doc_comment;
bool build_if;
};
struct LC_ASTPackage {
@@ -384,8 +380,6 @@ struct LC_ASTPackage {
LC_StringList injected_filepaths; // to sidestep regular file finding, implement single file packages etc.
LC_AST *ffile;
LC_AST *lfile;
LC_AST *fdiscarded;
LC_AST *ldiscarded; // #build_if
LC_Token *doc_comment;
@@ -446,7 +440,7 @@ struct LC_ExprCompoItem {
};
// clang-format off
union LC_Val { LC_BigInt i; double d; LC_Intern name; };
union LC_Val { LC_BigInt i; double d; LC_Intern name; };
struct LC_ExprIdent { LC_Intern name; LC_Decl *resolved_decl; };
struct LC_ExprUnary { LC_TokenKind op; LC_AST *expr; };
struct LC_ExprBinary { LC_TokenKind op; LC_AST *left; LC_AST *right; };
@@ -487,7 +481,7 @@ struct LC_DeclNote { LC_DeclBase base; LC_AST *expr; bool processed; }; /
struct LC_GlobImport { LC_Intern name; LC_Intern path; bool resolved; LC_Decl *resolved_decl; };
struct LC_ASTRef { LC_ASTRef *next; LC_ASTRef *prev; LC_AST *ast; };
struct LC_ASTRefList { LC_ASTRef *first; LC_ASTRef *last; };
struct LC_ASTRefList { LC_ASTRef *first; LC_ASTRef *last; };
// clang-format on
struct LC_TypeAndVal {
@@ -650,10 +644,8 @@ struct LC_ASTWalker {
LC_ASTArray stack;
int inside_builtin;
int inside_discarded;
int inside_note;
uint8_t visit_discarded;
uint8_t visit_notes;
uint8_t depth_first;
uint8_t dont_recurse; // breathfirst only
@@ -905,6 +897,7 @@ struct LC_Lang {
LC_Intern first_package;
LC_ASTRefList ordered_packages;
LC_StringList package_dirs;
LC_ASTRefList discarded;
LC_Map interns;
LC_Map declared_notes;
@@ -1656,10 +1649,6 @@ LC_FUNCTION wchar_t *LC_ToWidechar(LC_Arena *allocator, LC_String string);
(node)->prev->next = (node)->next; \
(node)->next->prev = (node)->prev; \
} \
if (node) { \
(node)->prev = 0; \
(node)->next = 0; \
} \
} while (0)
#define LC_DLLRemove(first, last, node) LC_DLLRemoveMod(first, last, node, next, prev)

View File

@@ -221,6 +221,36 @@ LC_FUNCTION void LC_ParsePackagesUsingRegistry(LC_Intern name) {
}
}
LC_FUNCTION void LC_BuildIfPass(void) {
LC_ASTFor(n, L->fpackage) {
for (LC_AST *fit = n->apackage.ffile; fit;) {
LC_AST *next = fit->next;
LC_AST *build_if = LC_HasNote(fit, L->ibuild_if);
if (build_if) {
if (!LC_ResolveBuildIf(build_if)) {
LC_DLLRemove(n->apackage.ffile, n->apackage.lfile, fit);
LC_AddASTToRefList(&L->discarded, fit);
fit = next;
continue;
}
}
for (LC_AST *dit = fit->afile.fdecl; dit; dit = dit->next) {
LC_AST *build_if = LC_HasNote(dit, L->ibuild_if);
if (build_if) {
if (!LC_ResolveBuildIf(build_if)) {
LC_DLLRemove(fit->afile.fdecl, fit->afile.ldecl, dit);
LC_AddASTToRefList(&L->discarded, dit);
}
}
}
fit = next;
}
}
}
LC_FUNCTION void LC_AddOrderedPackageToRefList(LC_AST *n) {
LC_ASTRefList *ordered = &L->ordered_packages;
for (LC_ASTRef *it = ordered->first; it; it = it->next) {
@@ -315,6 +345,7 @@ LC_FUNCTION void LC_ResolveAllProcBodies(void) {
LC_FUNCTION LC_ASTRefList LC_ResolvePackageByName(LC_Intern name) {
LC_ParsePackagesUsingRegistry(name);
LC_BuildIfPass();
LC_ASTRefList empty = {0};
if (L->errors) return empty;

View File

@@ -776,6 +776,33 @@ LC_FUNCTION LC_AST *LC_ParseNotes(void) {
return 0;
}
LC_FUNCTION bool ParseHashBuildIf(LC_AST *n) {
LC_Token *t0 = LC_GetI(0);
LC_Token *t1 = LC_GetI(1);
if (t0->kind == LC_TokenKind_Hash && t1->kind == LC_TokenKind_Ident && t1->ident == L->ibuild_if) {
LC_Next();
LC_AST *note = LC_ParseNote();
if (note->kind == LC_ASTKind_Error) {
LC_EatUntilNextValidDecl();
return true;
}
if (!LC_Match(LC_TokenKind_Semicolon)) {
LC_ReportParseError(LC_GetI(-1), "expected ';' semicolon");
LC_EatUntilNextValidDecl();
return true;
}
LC_AST *note_list = LC_CreateAST(t0, LC_ASTKind_NoteList);
LC_DLLAdd(note_list->anote_list.first, note_list->anote_list.last, note);
n->notes = note_list;
return LC_ResolveBuildIf(note);
}
return true;
}
LC_FUNCTION bool LC_ResolveBuildIf(LC_AST *build_if) {
LC_ExprCompo *note = &build_if->anote;
if (note->size != 1) {
@@ -785,7 +812,7 @@ LC_FUNCTION bool LC_ResolveBuildIf(LC_AST *build_if) {
LC_ExprCompoItem *item = &note->first->ecompo_item;
if (item->index != NULL || item->name != 0) {
LC_ReportParseError(LC_GetI(-1), "invalid syntax, #build_if shouldn't have a named or indexed first argument");
LC_ReportParseError(LC_GetI(-1), "invalid syntax, you have passed in a named or indexed argument to #build_if");
return true;
}
@@ -908,34 +935,6 @@ LC_FUNCTION bool LC_EatUntilNextValidDecl(void) {
}
}
LC_FUNCTION bool LC_ParseHashBuildOn(LC_AST *n) {
LC_Token *t0 = LC_GetI(0);
LC_Token *t1 = LC_GetI(1);
if (t0->kind == LC_TokenKind_Hash && t1->kind == LC_TokenKind_Ident && t1->ident == L->ibuild_if) {
LC_Next();
LC_AST *build_if = LC_CreateAST(t1, LC_ASTKind_DeclNote);
build_if->dnote.expr = LC_ParseNote();
if (build_if->dnote.expr->kind == LC_ASTKind_Error) {
LC_EatUntilNextValidDecl();
return true;
}
if (!LC_Match(LC_TokenKind_Semicolon)) {
LC_ReportParseError(LC_GetI(-1), "expected ';' semicolon");
LC_EatUntilNextValidDecl();
return true;
}
LC_AST *note_list = LC_CreateAST(t0, LC_ASTKind_NoteList);
LC_DLLAdd(note_list->anote_list.first, note_list->anote_list.last, build_if);
n->notes = note_list;
return LC_ResolveBuildIf(build_if->dnote.expr);
}
return true;
}
LC_FUNCTION LC_AST *LC_ParseImport(void) {
LC_AST *n = NULL;
LC_Token *import = LC_MatchKeyword(L->kimport);
@@ -965,7 +964,7 @@ LC_FUNCTION LC_AST *LC_ParseFileEx(LC_AST *package) {
LC_AST *n = LC_CreateAST(LC_Get(), LC_ASTKind_File);
n->afile.x = L->parser->x;
n->afile.doc_comment = LC_Match(LC_TokenKind_FileDocComment);
n->afile.build_if = LC_ParseHashBuildOn(n);
ParseHashBuildIf(n);
// Parse imports
while (!LC_Is(LC_TokenKind_EOF)) {
@@ -988,35 +987,15 @@ LC_FUNCTION LC_AST *LC_ParseFileEx(LC_AST *package) {
if (decl->kind == LC_ASTKind_Error) {
LC_EatUntilNextValidDecl();
} else {
bool skip = false;
LC_AST *build_if = LC_HasNote(decl, L->ibuild_if);
if (build_if) {
skip = !LC_ResolveBuildIf(build_if);
}
if (L->on_decl_parsed) {
skip = L->on_decl_parsed(skip, decl);
}
if (skip) {
LC_DLLAdd(n->afile.fdiscarded, n->afile.ldiscarded, decl);
} else {
LC_DLLAdd(n->afile.fdecl, n->afile.ldecl, decl);
}
if (L->on_decl_parsed) L->on_decl_parsed(false, decl);
LC_DLLAdd(n->afile.fdecl, n->afile.ldecl, decl);
}
}
if (package) {
if (package->apackage.doc_comment) LC_ReportParseError(package_doc_comment, "there are more then 1 package doc comments in %s package", (char *)package->apackage.name);
package->apackage.doc_comment = package_doc_comment;
if (n->afile.build_if) {
LC_AddFileToPackage(package, n);
} else {
LC_DLLAdd(package->apackage.fdiscarded, package->apackage.ldiscarded, n);
n->afile.package = package;
}
LC_AddFileToPackage(package, n);
}
return n;