@@ -270,9 +270,10 @@ mut:
270270}
271271
272272struct FastcSourceHeader {
273- module_name string
274- imports map [string ]string
275- has_globals bool
273+ module_name string
274+ imports map [string ]string
275+ blank_imports []string
276+ has_globals bool
276277}
277278
278279struct FastcSourceFile {
377378// error; FastC never retries through an AST-based backend.
378379pub fn generate (source string , path string , prefs & pref.Preferences) ! string {
379380 header := fastc_scan_source_header (source, path, prefs)!
380- if header.imports.len > 0 {
381+ if header.imports.len > 0 || header.blank_imports.len > 0 {
381382 return error ('fastc parser does not support imports through the single-source API in ${path }' )
382383 }
383384 return generate_source_files ([
@@ -704,9 +705,10 @@ fn fastc_resolve_source_files(paths []string, prefs &pref.Preferences) ![]FastcS
704705 mut header := fastc_scan_source_header (source, path, prefs)!
705706 if queued.module_name != '' {
706707 header = FastcSourceHeader{
707- module_name: queued.module_name
708- imports: header.imports
709- has_globals: header.has_globals
708+ module_name: queued.module_name
709+ imports: header.imports
710+ blank_imports: header.blank_imports
711+ has_globals: header.has_globals
710712 }
711713 }
712714 sources << FastcSourceFile{
@@ -715,7 +717,7 @@ fn fastc_resolve_source_files(paths []string, prefs &pref.Preferences) ![]FastcS
715717 header: header
716718 }
717719 mut discovered_imports := map [string ]bool {}
718- for imported_module in header.imports. values ( ) {
720+ for imported_module in fastc_header_imported_modules (header ) {
719721 if discovered_imports[imported_module] {
720722 continue
721723 }
@@ -741,6 +743,12 @@ fn fastc_resolve_source_files(paths []string, prefs &pref.Preferences) ![]FastcS
741743 return sources
742744}
743745
746+ fn fastc_header_imported_modules (header FastcSourceHeader) []string {
747+ mut modules := header.imports.values ()
748+ modules << header.blank_imports
749+ return modules
750+ }
751+
744752fn fastc_sources_in_dependency_order (sources []FastcSourceFile) ! []FastcSourceFile {
745753 mut module_order := []string {}
746754 for source_file in sources {
@@ -827,8 +835,7 @@ fn fastc_append_module_sources(module_name string, sources []FastcSourceFile, mu
827835 if source_file.header.module_name != module_name {
828836 continue
829837 }
830- imports := source_file.header.imports.clone ()
831- for dependency in imports.values () {
838+ for dependency in fastc_header_imported_modules (source_file.header) {
832839 if dependency != module_name && dependency ! in dependencies {
833840 dependencies << dependency
834841 }
@@ -861,6 +868,7 @@ fn fastc_scan_source_header(source string, path string, prefs &pref.Preferences)
861868 scan.init (file, source)
862869 mut module_name := ''
863870 mut imports := map [string ]string {}
871+ mut blank_imports := []string {}
864872 mut has_globals := false
865873 mut brace_depth := 0
866874 mut tok := scan.scan ()
@@ -913,7 +921,8 @@ fn fastc_scan_source_header(source string, path string, prefs &pref.Preferences)
913921 }
914922 import_path , alias , selected_names , next_token :=
915923 fastc_scan_import (mut scan, tok, path)!
916- fastc_register_import_alias (import_path, alias, path, mut imports)!
924+ fastc_register_import_alias (import_path, alias, path, mut imports, mut
925+ blank_imports)!
917926 fastc_register_selective_imports (import_path, selected_names, path, mut imports)!
918927 tok = next_token
919928 }
@@ -923,7 +932,7 @@ fn fastc_scan_source_header(source string, path string, prefs &pref.Preferences)
923932 continue
924933 }
925934 import_path , alias , selected_names , next_token := fastc_scan_import (mut scan, tok, path)!
926- fastc_register_import_alias (import_path, alias, path, mut imports)!
935+ fastc_register_import_alias (import_path, alias, path, mut imports, mut blank_imports )!
927936 fastc_register_selective_imports (import_path, selected_names, path, mut imports)!
928937 tok = next_token
929938 }
@@ -935,18 +944,21 @@ fn fastc_scan_source_header(source string, path string, prefs &pref.Preferences)
935944 imports['driver' ] = imports['fastcdriver' ]
936945 }
937946 return FastcSourceHeader{
938- module_name: module_name
939- imports: imports
940- has_globals: has_globals
947+ module_name: module_name
948+ imports: imports
949+ blank_imports: blank_imports
950+ has_globals: has_globals
941951 }
942952}
943953
944- fn fastc_register_import_alias (import_path string , alias string , path string , mut imports map [string ]string ) ! {
945- if alias != '_' {
946- if existing_module := imports[alias] {
947- if existing_module != import_path {
948- return error ('fastc parser cannot reuse import alias `${alias }` for `${import_path }` after `${existing_module }` in ${path }' )
949- }
954+ fn fastc_register_import_alias (import_path string , alias string , path string , mut imports map [string ]string , mut blank_imports []string ) ! {
955+ if alias == '_' {
956+ blank_imports << import_path
957+ return
958+ }
959+ if existing_module := imports[alias] {
960+ if existing_module != import_path {
961+ return error ('fastc parser cannot reuse import alias `${alias }` for `${import_path }` after `${existing_module }` in ${path }' )
950962 }
951963 }
952964 imports[alias] = import_path
@@ -1024,6 +1036,19 @@ fn collect_declared_types(source string, path string, module_name string, prefs
10241036 mut previous_tok := token.Token.unknown
10251037 mut tok := scan.scan ()
10261038 for tok != .eof {
1039+ if brace_depth == 0 && tok == .dollar {
1040+ mut lookahead := scan
1041+ if lookahead.scan () == .key_if {
1042+ selected := fastc_scan_selected_comptime_branch (mut scan, scan.scan (), path, prefs)!
1043+ if selected.source != '' {
1044+ collect_declared_types (selected.source, path, module_name, prefs, mut
1045+ declared_types, mut declared_kinds)!
1046+ }
1047+ tok = selected.tok
1048+ previous_tok = .unknown
1049+ continue
1050+ }
1051+ }
10271052 if brace_depth == 0 && tok == .attribute {
10281053 mut attribute_depth := 1
10291054 mut is_typedef := false
@@ -1760,6 +1785,26 @@ fn fastc_emit_source_type_declarations(source_file FastcSourceFile, prefs &pref.
17601785 mut next_enum_is_flag := false
17611786 mut tok := scan.scan ()
17621787 for tok != .eof {
1788+ if depth == 0 && tok == .dollar {
1789+ mut lookahead := scan
1790+ if lookahead.scan () == .key_if {
1791+ selected := fastc_scan_selected_comptime_branch (mut scan, scan.scan (),
1792+ source_file.path, prefs)!
1793+ if selected.source != '' {
1794+ selected_source := FastcSourceFile{
1795+ path: source_file.path
1796+ source: selected.source
1797+ header: source_file.header
1798+ }
1799+ fastc_emit_source_type_declarations (selected_source, prefs, declared_types,
1800+ declared_kinds, constants, public_constants, mut struct_fields, mut
1801+ struct_field_info, mut composite_types, mut out)!
1802+ }
1803+ tok = selected.tok
1804+ next_enum_is_flag = false
1805+ continue
1806+ }
1807+ }
17631808 if depth == 0 && tok == .attribute {
17641809 tok , next_enum_is_flag = fastc_scan_type_attribute (mut scan)!
17651810 continue
@@ -3128,6 +3173,18 @@ fn collect_interface_method_signatures(source string, path string, header FastcS
31283173 mut tok := scan.scan ()
31293174 mut depth := 0
31303175 for tok != .eof {
3176+ if depth == 0 && tok == .dollar {
3177+ mut lookahead := scan
3178+ if lookahead.scan () == .key_if {
3179+ selected := fastc_scan_selected_comptime_branch (mut scan, scan.scan (), path, prefs)!
3180+ if selected.source != '' {
3181+ collect_interface_method_signatures (selected.source, path, header, prefs,
3182+ declared_types, mut functions, mut interface_methods)!
3183+ }
3184+ tok = selected.tok
3185+ continue
3186+ }
3187+ }
31313188 if depth != 0 || tok != .key_interface {
31323189 if tok == .lcbr {
31333190 depth++
0 commit comments