Separate out build_if into a pass
This commit is contained in:
@@ -5,13 +5,11 @@ I have no illusions here, this is not the next big language. What I propose is v
|
|||||||
- **User has full control over compilation!**
|
- **User has full control over compilation!**
|
||||||
- **No dependencies, permissive license, single file that compile both in C and C++!**
|
- **No dependencies, permissive license, single file that compile both in C and C++!**
|
||||||
- **Simpler then C:** core of the language is 4000 loc and entire package 11k loc.
|
- **Simpler then C:** core of the language is 4000 loc and entire package 11k loc.
|
||||||
- **Statically typed, procedural and MODERN:** it's a mix of Go/Odin/Jai with "return to C" as ideal.
|
- **Statically typed, procedural and modern:** it's a mix of Go/Odin/Jai with "return to C" as ideal.
|
||||||
- **Complete:** it supports conditional compilation, modularity via packages etc.
|
- **Complete:** it supports conditional compilation, modularity via packages etc.
|
||||||
- **State of art error handling techniques** like AST poisoning, proper parsing recovery, catches tons of errors without misreporting!
|
- **State of art error handling techniques** like AST poisoning, proper parsing recovery, catches tons of errors without misreporting!
|
||||||
- **Great C integration:** using C libraries feels native, the language compiles easily to C with great debug info.
|
- **Great C integration:** using C libraries feels native, the language compiles easily to C with great debug info.
|
||||||
|
|
||||||
**Library is in beta so I reserve the right to change things!**
|
|
||||||
|
|
||||||
## Example or [you can try the language online](https://krzosa.xyz/playground.html)
|
## Example or [you can try the language online](https://krzosa.xyz/playground.html)
|
||||||
|
|
||||||
``` odin
|
``` odin
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ if not exist build\bld.exe (
|
|||||||
)
|
)
|
||||||
|
|
||||||
rem ubuntu run ./build.sh
|
rem ubuntu run ./build.sh
|
||||||
build\bld.exe
|
build\bld.exe --quick
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ int main(int argc, char **argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageCompiler();
|
// PackageCompiler();
|
||||||
IO_Printf("Compiler packed successfully: lib_compiler.h\n");
|
IO_Printf("Compiler packed successfully: lib_compiler.h\n");
|
||||||
|
|
||||||
if (ShouldRun("test_readme")) {
|
if (ShouldRun("test_readme")) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ bool add_dynamic_array_macro() {
|
|||||||
|
|
||||||
LC_Intern name = LC_ILit("add_dynamic_array_macro");
|
LC_Intern name = LC_ILit("add_dynamic_array_macro");
|
||||||
LC_ParsePackagesUsingRegistry(name);
|
LC_ParsePackagesUsingRegistry(name);
|
||||||
|
LC_BuildIfPass();
|
||||||
if (L->errors) {
|
if (L->errors) {
|
||||||
LC_LangEnd(lang);
|
LC_LangEnd(lang);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ bool generate_type_info() {
|
|||||||
LC_Intern name = LC_ILit("generate_type_info");
|
LC_Intern name = LC_ILit("generate_type_info");
|
||||||
|
|
||||||
LC_ParsePackagesUsingRegistry(name);
|
LC_ParsePackagesUsingRegistry(name);
|
||||||
|
LC_BuildIfPass();
|
||||||
if (L->errors) {
|
if (L->errors) {
|
||||||
LC_LangEnd(lang);
|
LC_LangEnd(lang);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ bool sandbox() {
|
|||||||
|
|
||||||
LC_Intern name = LC_ILit("sandbox");
|
LC_Intern name = LC_ILit("sandbox");
|
||||||
LC_ParsePackagesUsingRegistry(name);
|
LC_ParsePackagesUsingRegistry(name);
|
||||||
|
LC_BuildIfPass();
|
||||||
if (L->errors) {
|
if (L->errors) {
|
||||||
LC_LangEnd(lang);
|
LC_LangEnd(lang);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
thread_local LC_Map DebugASTMap;
|
thread_local LC_Map DebugASTMap;
|
||||||
|
thread_local bool DebugInsideDiscarded;
|
||||||
|
|
||||||
void DebugVerify_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
|
void DebugVerify_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
|
||||||
bool created = LC_InsertWithoutReplace(&DebugASTMap, n, (void *)(intptr_t)100);
|
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) {
|
if (!n->type) {
|
||||||
LC_ReportASTError(n, "typespec doesn't hold 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) {
|
if (should_have_type && !n->type) {
|
||||||
LC_ReportASTError(n, "expression doesn't have 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);
|
LC_ASTWalker walker = LC_GetDefaultWalker(L->arena, VerifyCopy_Walk);
|
||||||
walker.visit_notes = walker.visit_discarded = true;
|
walker.user_data = (void *)©_counter;
|
||||||
walker.user_data = (void *)©_counter;
|
|
||||||
LC_WalkAST(&walker, copy);
|
LC_WalkAST(&walker, copy);
|
||||||
walker.user_data = (void *)&original_counter;
|
walker.user_data = (void *)&original_counter;
|
||||||
LC_WalkAST(&walker, copy);
|
LC_WalkAST(&walker, copy);
|
||||||
@@ -101,13 +101,15 @@ void DebugVerifyAST(LC_ASTRefList packages) {
|
|||||||
LC_MapReserve(&DebugASTMap, 4096);
|
LC_MapReserve(&DebugASTMap, 4096);
|
||||||
|
|
||||||
LC_ASTWalker walker = LC_GetDefaultWalker(L->arena, DebugVerify_WalkAST);
|
LC_ASTWalker walker = LC_GetDefaultWalker(L->arena, DebugVerify_WalkAST);
|
||||||
walker.visit_notes = walker.visit_discarded = true;
|
walker.visit_notes = true;
|
||||||
for (LC_ASTRef *it = packages.first; it; it = it->next) {
|
for (LC_ASTRef *it = packages.first; it; it = it->next) LC_WalkAST(&walker, it->ast);
|
||||||
LC_WalkAST(&walker, it->ast);
|
|
||||||
}
|
|
||||||
LC_WalkAST(&walker, L->tstring->decl->ast);
|
LC_WalkAST(&walker, L->tstring->decl->ast);
|
||||||
LC_WalkAST(&walker, L->tany->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) {
|
for (int i = 0; i < L->ast_count; i += 1) {
|
||||||
LC_AST *it = (LC_AST *)L->ast_arena->memory.data + i;
|
LC_AST *it = (LC_AST *)L->ast_arena->memory.data + i;
|
||||||
if (it == L->builtin_package) continue;
|
if (it == L->builtin_package) continue;
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ void RunTestFile(TestDesc it) {
|
|||||||
|
|
||||||
L->first_package = name;
|
L->first_package = name;
|
||||||
LC_ParsePackagesUsingRegistry(name);
|
LC_ParsePackagesUsingRegistry(name);
|
||||||
|
LC_BuildIfPass();
|
||||||
if (L->errors) {
|
if (L->errors) {
|
||||||
result = Failed_Parse;
|
result = Failed_Parse;
|
||||||
goto end_of_test;
|
goto end_of_test;
|
||||||
|
|||||||
@@ -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_AST *it_copy = LC_CopyAST(arena, it);
|
||||||
LC_DLLAdd(result->afile.fdecl, result->afile.ldecl, it_copy);
|
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;
|
} break;
|
||||||
|
|
||||||
case LC_ASTKind_DeclProc: {
|
case LC_ASTKind_DeclProc: {
|
||||||
|
|||||||
@@ -58,10 +58,6 @@ LC_FUNCTION void LC_WalkAST(LC_ASTWalker *ctx, LC_AST *n) {
|
|||||||
|
|
||||||
case LC_ASTKind_Package: {
|
case LC_ASTKind_Package: {
|
||||||
LC_ASTFor(it, n->apackage.ffile) LC_WalkAST(ctx, it);
|
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;
|
} break;
|
||||||
|
|
||||||
case LC_ASTKind_File: {
|
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;
|
if (ctx->visit_notes == false && it->kind == LC_ASTKind_DeclNote) continue;
|
||||||
LC_WalkAST(ctx, it);
|
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;
|
} break;
|
||||||
|
|
||||||
case LC_ASTKind_DeclProc: {
|
case LC_ASTKind_DeclProc: {
|
||||||
|
|||||||
@@ -369,12 +369,8 @@ struct LC_ASTFile {
|
|||||||
LC_AST *limport;
|
LC_AST *limport;
|
||||||
LC_AST *fdecl;
|
LC_AST *fdecl;
|
||||||
LC_AST *ldecl;
|
LC_AST *ldecl;
|
||||||
LC_AST *fdiscarded;
|
|
||||||
LC_AST *ldiscarded; // @build_if
|
|
||||||
|
|
||||||
LC_Token *doc_comment;
|
LC_Token *doc_comment;
|
||||||
|
|
||||||
bool build_if;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LC_ASTPackage {
|
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_StringList injected_filepaths; // to sidestep regular file finding, implement single file packages etc.
|
||||||
LC_AST *ffile;
|
LC_AST *ffile;
|
||||||
LC_AST *lfile;
|
LC_AST *lfile;
|
||||||
LC_AST *fdiscarded;
|
|
||||||
LC_AST *ldiscarded; // #build_if
|
|
||||||
|
|
||||||
LC_Token *doc_comment;
|
LC_Token *doc_comment;
|
||||||
|
|
||||||
@@ -446,7 +440,7 @@ struct LC_ExprCompoItem {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// clang-format off
|
// 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_ExprIdent { LC_Intern name; LC_Decl *resolved_decl; };
|
||||||
struct LC_ExprUnary { LC_TokenKind op; LC_AST *expr; };
|
struct LC_ExprUnary { LC_TokenKind op; LC_AST *expr; };
|
||||||
struct LC_ExprBinary { LC_TokenKind op; LC_AST *left; LC_AST *right; };
|
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_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_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
|
// clang-format on
|
||||||
|
|
||||||
struct LC_TypeAndVal {
|
struct LC_TypeAndVal {
|
||||||
@@ -650,10 +644,8 @@ struct LC_ASTWalker {
|
|||||||
LC_ASTArray stack;
|
LC_ASTArray stack;
|
||||||
|
|
||||||
int inside_builtin;
|
int inside_builtin;
|
||||||
int inside_discarded;
|
|
||||||
int inside_note;
|
int inside_note;
|
||||||
|
|
||||||
uint8_t visit_discarded;
|
|
||||||
uint8_t visit_notes;
|
uint8_t visit_notes;
|
||||||
uint8_t depth_first;
|
uint8_t depth_first;
|
||||||
uint8_t dont_recurse; // breathfirst only
|
uint8_t dont_recurse; // breathfirst only
|
||||||
@@ -905,6 +897,7 @@ struct LC_Lang {
|
|||||||
LC_Intern first_package;
|
LC_Intern first_package;
|
||||||
LC_ASTRefList ordered_packages;
|
LC_ASTRefList ordered_packages;
|
||||||
LC_StringList package_dirs;
|
LC_StringList package_dirs;
|
||||||
|
LC_ASTRefList discarded;
|
||||||
|
|
||||||
LC_Map interns;
|
LC_Map interns;
|
||||||
LC_Map declared_notes;
|
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)->prev->next = (node)->next; \
|
||||||
(node)->next->prev = (node)->prev; \
|
(node)->next->prev = (node)->prev; \
|
||||||
} \
|
} \
|
||||||
if (node) { \
|
|
||||||
(node)->prev = 0; \
|
|
||||||
(node)->next = 0; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
#define LC_DLLRemove(first, last, node) LC_DLLRemoveMod(first, last, node, next, prev)
|
#define LC_DLLRemove(first, last, node) LC_DLLRemoveMod(first, last, node, next, prev)
|
||||||
|
|
||||||
|
|||||||
@@ -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_FUNCTION void LC_AddOrderedPackageToRefList(LC_AST *n) {
|
||||||
LC_ASTRefList *ordered = &L->ordered_packages;
|
LC_ASTRefList *ordered = &L->ordered_packages;
|
||||||
for (LC_ASTRef *it = ordered->first; it; it = it->next) {
|
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_FUNCTION LC_ASTRefList LC_ResolvePackageByName(LC_Intern name) {
|
||||||
LC_ParsePackagesUsingRegistry(name);
|
LC_ParsePackagesUsingRegistry(name);
|
||||||
|
LC_BuildIfPass();
|
||||||
LC_ASTRefList empty = {0};
|
LC_ASTRefList empty = {0};
|
||||||
if (L->errors) return empty;
|
if (L->errors) return empty;
|
||||||
|
|
||||||
|
|||||||
@@ -776,6 +776,33 @@ LC_FUNCTION LC_AST *LC_ParseNotes(void) {
|
|||||||
return 0;
|
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_FUNCTION bool LC_ResolveBuildIf(LC_AST *build_if) {
|
||||||
LC_ExprCompo *note = &build_if->anote;
|
LC_ExprCompo *note = &build_if->anote;
|
||||||
if (note->size != 1) {
|
if (note->size != 1) {
|
||||||
@@ -785,7 +812,7 @@ LC_FUNCTION bool LC_ResolveBuildIf(LC_AST *build_if) {
|
|||||||
|
|
||||||
LC_ExprCompoItem *item = ¬e->first->ecompo_item;
|
LC_ExprCompoItem *item = ¬e->first->ecompo_item;
|
||||||
if (item->index != NULL || item->name != 0) {
|
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;
|
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_FUNCTION LC_AST *LC_ParseImport(void) {
|
||||||
LC_AST *n = NULL;
|
LC_AST *n = NULL;
|
||||||
LC_Token *import = LC_MatchKeyword(L->kimport);
|
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);
|
LC_AST *n = LC_CreateAST(LC_Get(), LC_ASTKind_File);
|
||||||
n->afile.x = L->parser->x;
|
n->afile.x = L->parser->x;
|
||||||
n->afile.doc_comment = LC_Match(LC_TokenKind_FileDocComment);
|
n->afile.doc_comment = LC_Match(LC_TokenKind_FileDocComment);
|
||||||
n->afile.build_if = LC_ParseHashBuildOn(n);
|
ParseHashBuildIf(n);
|
||||||
|
|
||||||
// Parse imports
|
// Parse imports
|
||||||
while (!LC_Is(LC_TokenKind_EOF)) {
|
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) {
|
if (decl->kind == LC_ASTKind_Error) {
|
||||||
LC_EatUntilNextValidDecl();
|
LC_EatUntilNextValidDecl();
|
||||||
} else {
|
} else {
|
||||||
bool skip = false;
|
if (L->on_decl_parsed) L->on_decl_parsed(false, decl);
|
||||||
|
LC_DLLAdd(n->afile.fdecl, n->afile.ldecl, decl);
|
||||||
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 (package) {
|
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);
|
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;
|
package->apackage.doc_comment = package_doc_comment;
|
||||||
|
LC_AddFileToPackage(package, n);
|
||||||
if (n->afile.build_if) {
|
|
||||||
LC_AddFileToPackage(package, n);
|
|
||||||
} else {
|
|
||||||
LC_DLLAdd(package->apackage.fdiscarded, package->apackage.ldiscarded, n);
|
|
||||||
n->afile.package = package;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
|||||||
Reference in New Issue
Block a user