diff --git a/compiler/can/src/module.rs b/compiler/can/src/module.rs index 134b00d781..1c3277fff0 100644 --- a/compiler/can/src/module.rs +++ b/compiler/can/src/module.rs @@ -97,6 +97,7 @@ pub fn canonicalize_module_defs<'a>( let first_char = ident.as_inline_str().chars().next().unwrap(); if first_char.is_lowercase() { + // this is a value definition let expr_var = var_store.fresh(); match scope.import(ident, symbol, region) { @@ -116,6 +117,15 @@ pub fn canonicalize_module_defs<'a>( } } } else { + // This is a type alias + + // the same scheme as with identifiers won't work here, e.g. + // + // Task : Effect + // + // really is not the same as + // + // Task a : Effect a panic!("TODO add type aliases to type alias dictionary, based on exposed types"); } } diff --git a/compiler/gen_dev/tests/gen_num.rs b/compiler/gen_dev/tests/gen_num.rs index 7b73fe1d37..24be18721f 100644 --- a/compiler/gen_dev/tests/gen_num.rs +++ b/compiler/gen_dev/tests/gen_num.rs @@ -1,5 +1,6 @@ #[macro_use] extern crate pretty_assertions; + #[macro_use] extern crate indoc; diff --git a/compiler/gen_dev/tests/helpers/eval.rs b/compiler/gen_dev/tests/helpers/eval.rs index 0108211709..7f6f8ea55c 100644 --- a/compiler/gen_dev/tests/helpers/eval.rs +++ b/compiler/gen_dev/tests/helpers/eval.rs @@ -75,7 +75,6 @@ pub fn helper<'a>( println!("{:?}", exposed_to_host); println!("=================================\n"); */ - debug_assert_eq!(exposed_to_host.len(), 1); let main_fn_symbol = exposed_to_host.keys().copied().nth(0).unwrap(); diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 0175e0bb77..b46279c9c2 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -13,14 +13,16 @@ use roc_constrain::module::{ constrain_imports, pre_constrain_imports, ConstrainableImports, Import, }; use roc_constrain::module::{constrain_module, ExposedModuleTypes, SubsByModule}; -use roc_module::ident::{Ident, Lowercase, ModuleName, TagName}; -use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol}; +use roc_module::ident::{Ident, Lowercase, ModuleName, QualifiedModuleName, TagName}; +use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, PackageModuleIds, Symbol}; use roc_mono::ir::{ CapturedSymbols, ExternalSpecializations, PartialProc, PendingSpecialization, Proc, Procs, }; use roc_mono::layout::{Layout, LayoutCache}; use roc_parse::ast::{self, Attempting, StrLiteral, TypeAnnotation}; -use roc_parse::header::{ExposesEntry, ImportsEntry, PlatformHeader, TypedIdent}; +use roc_parse::header::{ + ExposesEntry, ImportsEntry, PackageEntry, PackageOrPath, PlatformHeader, To, TypedIdent, +}; use roc_parse::module::module_defs; use roc_parse::parser::{self, Fail, Parser}; use roc_region::all::{Located, Region}; @@ -101,6 +103,7 @@ impl Dependencies { pub fn add_module( &mut self, module_id: ModuleId, + opt_effect_module: Option, dependencies: &MutSet, goal_phase: Phase, ) -> MutSet<(ModuleId, Phase)> { @@ -143,7 +146,8 @@ impl Dependencies { // all the dependencies can be loaded for dep in dependencies { // TODO figure out how to "load" (because it doesn't exist on the file system) the Effect module - if !format!("{:?}", dep).contains("Effect") { + + if Some(*dep) != opt_effect_module { output.insert((*dep, LoadHeader)); } } @@ -346,6 +350,7 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) -> // Provide mutexes of ModuleIds and IdentIds by module, // so other modules can populate them as they load. module_ids: Arc::clone(&state.arc_modules), + package_module_ids: Arc::clone(&state.arc_package_modules), ident_ids_by_module: Arc::clone(&state.ident_ids_by_module), mode: state.stdlib.mode, } @@ -541,6 +546,7 @@ struct ModuleHeader<'a> { exposed_ident_ids: IdentIds, deps_by_name: MutMap, imported_modules: MutSet, + imported_package_modules: MutSet, exposes: Vec, exposed_imports: MutMap, src: &'a [u8], @@ -676,6 +682,7 @@ struct State<'a> { pub stdlib: StdLib, pub exposed_types: SubsByModule, pub output_path: Option<&'a str>, + pub opt_effect_module: Option, pub headers_parsed: MutSet, @@ -690,6 +697,7 @@ struct State<'a> { /// From now on, these will be used by multiple threads; time to make an Arc>! pub arc_modules: Arc>, + pub arc_package_modules: Arc>>, pub ident_ids_by_module: Arc>>, @@ -819,11 +827,14 @@ enum BuildTask<'a> { LoadModule { module_name: ModuleName, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, }, LoadPkgConfig { + shorthand: &'a str, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, }, @@ -989,6 +1000,7 @@ pub fn load_and_monomorphize_from_str<'a>( struct LoadStart<'a> { pub arc_modules: Arc>, + pub arc_package_modules: Arc>>, pub ident_ids_by_module: Arc>>, pub root_id: ModuleId, pub root_msg: Msg<'a>, @@ -1001,6 +1013,7 @@ impl<'a> LoadStart<'a> { mode: Mode, ) -> Result { let arc_modules = Arc::new(Mutex::new(ModuleIds::default())); + let arc_package_modules = Arc::new(Mutex::new(PackageModuleIds::default())); let root_exposed_ident_ids = IdentIds::exposed_builtins(0); let ident_ids_by_module = Arc::new(Mutex::new(root_exposed_ident_ids)); @@ -1012,6 +1025,7 @@ impl<'a> LoadStart<'a> { arena, filename, Arc::clone(&arc_modules), + Arc::clone(&arc_package_modules), Arc::clone(&ident_ids_by_module), root_start_time, mode, @@ -1020,6 +1034,7 @@ impl<'a> LoadStart<'a> { Ok(LoadStart { arc_modules, + arc_package_modules, ident_ids_by_module, root_id, root_msg, @@ -1033,6 +1048,7 @@ impl<'a> LoadStart<'a> { mode: Mode, ) -> Result { let arc_modules = Arc::new(Mutex::new(ModuleIds::default())); + let arc_package_modules = Arc::new(Mutex::new(PackageModuleIds::default())); let root_exposed_ident_ids = IdentIds::exposed_builtins(0); let ident_ids_by_module = Arc::new(Mutex::new(root_exposed_ident_ids)); @@ -1045,6 +1061,7 @@ impl<'a> LoadStart<'a> { filename, src, Arc::clone(&arc_modules), + Arc::clone(&arc_package_modules), Arc::clone(&ident_ids_by_module), root_start_time, mode, @@ -1053,6 +1070,7 @@ impl<'a> LoadStart<'a> { Ok(LoadStart { arc_modules, + arc_package_modules, ident_ids_by_module, root_id, root_msg, @@ -1121,6 +1139,7 @@ where { let LoadStart { arc_modules, + arc_package_modules, ident_ids_by_module, root_id, root_msg, @@ -1248,6 +1267,7 @@ where goal_phase, stdlib, output_path: None, + opt_effect_module: None, module_cache: ModuleCache::default(), dependencies: Dependencies::default(), procedures: MutMap::default(), @@ -1256,6 +1276,7 @@ where headers_parsed, loading_started, arc_modules, + arc_package_modules, constrained_ident_ids: IdentIds::exposed_builtins(0), ident_ids_by_module, declarations_by_id: MutMap::default(), @@ -1412,6 +1433,7 @@ fn update<'a>( let work = state.dependencies.add_module( header.module_id, + state.opt_effect_module, &header.imported_modules, state.goal_phase, ); @@ -1499,6 +1521,9 @@ fn update<'a>( module_docs, } => { let module_id = constrained_module.module.module_id; + + state.opt_effect_module = Some(module_id); + log!("made effect module for {:?}", module_id); state .module_cache @@ -1843,19 +1868,15 @@ fn finish<'a>( fn load_pkg_config<'a>( arena: &'a Bump, src_dir: &Path, + shorthand: &'a str, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, ) -> Result, LoadingProblem> { let module_start_time = SystemTime::now(); - let mut filename = PathBuf::from(src_dir); - - filename.push("platform"); - filename.push(PKG_CONFIG_FILE_NAME); - - // End with .roc - filename.set_extension(ROC_FILE_EXTENSION); + let filename = PathBuf::from(src_dir); let file_io_start = SystemTime::now(); let file = fs::read(&filename); @@ -1889,7 +1910,9 @@ fn load_pkg_config<'a>( } Ok((ast::Module::Platform { header }, _parse_state)) => fabricate_effects_module( arena, + shorthand, module_ids, + package_module_ids, ident_ids_by_module, mode, header, @@ -1913,6 +1936,7 @@ fn load_module<'a>( src_dir: &Path, module_name: ModuleName, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, ) -> Result<(ModuleId, Msg<'a>), LoadingProblem> { @@ -1933,6 +1957,7 @@ fn load_module<'a>( arena, filename, module_ids, + package_module_ids, ident_ids_by_module, module_start_time, mode, @@ -1971,6 +1996,7 @@ fn parse_header<'a>( read_file_duration: Duration, filename: PathBuf, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, src_bytes: &'a [u8], @@ -1998,6 +2024,7 @@ fn parse_header<'a>( header.imports.into_bump_slice(), parse_state, module_ids, + package_module_ids, ident_ids_by_module, module_timing, )), @@ -2015,36 +2042,91 @@ fn parse_header<'a>( header.imports.into_bump_slice(), parse_state, module_ids.clone(), + package_module_ids.clone(), ident_ids_by_module.clone(), module_timing, ); - // check whether we can find a Pkg-Config.roc file - let mut pkg_config_roc = pkg_config_dir.clone(); - pkg_config_roc.push("platform"); - pkg_config_roc.push(PKG_CONFIG_FILE_NAME); - pkg_config_roc.set_extension(ROC_FILE_EXTENSION); + match header.to.value { + To::ExistingPackage(existing_package) => { + let opt_base_package = header.packages.iter().find(|loc_package_entry| { + let Located { value, .. } = loc_package_entry; - if pkg_config_roc.as_path().exists() { - let load_pkg_config_msg = load_pkg_config( - arena, - &pkg_config_dir, - module_ids, - ident_ids_by_module, - mode, - )?; + match value { + PackageEntry::Entry { shorthand, .. } => shorthand == &existing_package, + _ => false, + } + }); - Ok(( - module_id, - Msg::Many(vec![app_module_header_msg, load_pkg_config_msg]), - )) - } else { - Ok((module_id, app_module_header_msg)) + match opt_base_package { + Some(Located { + value: + PackageEntry::Entry { + shorthand, + package_or_path: + Located { + value: package_or_path, + .. + }, + .. + }, + .. + }) => { + match package_or_path { + PackageOrPath::Path(StrLiteral::PlainLine(package)) => { + // check whether we can find a Pkg-Config.roc file + let mut pkg_config_roc = pkg_config_dir; + pkg_config_roc.push(package); + pkg_config_roc.push(PKG_CONFIG_FILE_NAME); + pkg_config_roc.set_extension(ROC_FILE_EXTENSION); + + if pkg_config_roc.as_path().exists() { + let load_pkg_config_msg = load_pkg_config( + arena, + &pkg_config_roc, + shorthand, + module_ids, + package_module_ids, + ident_ids_by_module, + mode, + )?; + + Ok(( + module_id, + Msg::Many(vec![ + app_module_header_msg, + load_pkg_config_msg, + ]), + )) + } else { + Ok((module_id, app_module_header_msg)) + } + } + _ => unreachable!(), + } + } + _ => panic!("could not find base"), + } + } + To::NewPackage(package_or_path) => match package_or_path { + PackageOrPath::Package(_, _) => panic!("TODO implement packages"), + PackageOrPath::Path(StrLiteral::PlainLine(_package)) => { + Ok((module_id, app_module_header_msg)) + } + PackageOrPath::Path(StrLiteral::Block(_)) => { + panic!("TODO implement block package path") + } + PackageOrPath::Path(StrLiteral::Line(_)) => { + panic!("TODO implement line package path") + } + }, } } Ok((ast::Module::Platform { header }, _parse_state)) => fabricate_effects_module( arena, + &"", module_ids, + package_module_ids, ident_ids_by_module, mode, header, @@ -2059,6 +2141,7 @@ fn load_filename<'a>( arena: &'a Bump, filename: PathBuf, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, module_start_time: SystemTime, mode: Mode, @@ -2073,6 +2156,7 @@ fn load_filename<'a>( file_io_duration, filename, module_ids, + package_module_ids, ident_ids_by_module, mode, arena.alloc(bytes), @@ -2087,11 +2171,13 @@ fn load_filename<'a>( /// Load a module from a str /// the `filename` is never read, but used for the module name +#[allow(clippy::too_many_arguments)] fn load_from_str<'a>( arena: &'a Bump, filename: PathBuf, src: &'a str, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, module_start_time: SystemTime, mode: Mode, @@ -2104,6 +2190,7 @@ fn load_from_str<'a>( file_io_duration, filename, module_ids, + package_module_ids, ident_ids_by_module, mode, src.as_bytes(), @@ -2126,6 +2213,7 @@ fn send_header<'a>( imports: &'a [Located>], parse_state: parser::State<'a>, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, module_timing: ModuleTiming, ) -> (ModuleId, Msg<'a>) { @@ -2141,16 +2229,18 @@ fn send_header<'a>( } }; - let mut imported: Vec<(ModuleName, Vec, Region)> = Vec::with_capacity(imports.len()); + let mut imported: Vec<(QualifiedModuleName, Vec, Region)> = + Vec::with_capacity(imports.len()); let mut imported_modules: MutSet = MutSet::default(); + let mut imported_package_modules: MutSet = MutSet::default(); let mut scope_size = 0; for loc_entry in imports { - let (module_name, exposed) = exposed_from_import(&loc_entry.value); + let (qualified_module_name, exposed) = exposed_from_import(&loc_entry.value); scope_size += exposed.len(); - imported.push((module_name, exposed, loc_entry.region)); + imported.push((qualified_module_name, exposed, loc_entry.region)); } let num_exposes = exposes.len(); @@ -2167,6 +2257,7 @@ fn send_header<'a>( let ident_ids = { // Lock just long enough to perform the minimal operations necessary. let mut module_ids = (*module_ids).lock(); + let mut package_module_ids = (*package_module_ids).lock(); let mut ident_ids_by_module = (*ident_ids_by_module).lock(); home = module_ids.get_or_insert(&declared_name.as_inline_str()); @@ -2178,16 +2269,30 @@ fn send_header<'a>( // For each of our imports, add an entry to deps_by_name // - // e.g. for `imports [ Foo.{ bar } ]`, add `Foo` to deps_by_name + // e.g. for `imports [ base.Foo.{ bar } ]`, add `Foo` to deps_by_name // // Also build a list of imported_values_to_expose (like `bar` above.) - for (module_name, exposed_idents, region) in imported.into_iter() { - let cloned_module_name = module_name.clone(); - let module_id = module_ids.get_or_insert(&module_name.into()); + for (qualified_module_name, exposed_idents, region) in imported.into_iter() { + let cloned_module_name = qualified_module_name.module.clone(); + let module_id = match qualified_module_name.opt_package { + None => { + let id = module_ids.get_or_insert(&qualified_module_name.module.into()); - deps_by_name.insert(cloned_module_name, module_id); + imported_modules.insert(id); - imported_modules.insert(module_id); + deps_by_name.insert(cloned_module_name, id); + + id + } + Some(package) => { + let id = + package_module_ids.get_or_insert(&(package, cloned_module_name.into())); + + imported_package_modules.insert(id); + + id + } + }; // Add the new exposed idents to the dep module's IdentIds, so // once that module later gets loaded, its lookups will resolve @@ -2250,6 +2355,7 @@ fn send_header<'a>( exposed_ident_ids: ident_ids, module_name: loc_name.value, imported_modules, + imported_package_modules, deps_by_name, exposes: exposed, src: parse_state.bytes, @@ -2370,9 +2476,12 @@ fn run_solve<'a>( } } +#[allow(clippy::too_many_arguments)] fn fabricate_effects_module<'a>( arena: &'a Bump, + shorthand: &'a str, module_ids: Arc>, + package_module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, header: PlatformHeader<'a>, @@ -2398,6 +2507,14 @@ fn fabricate_effects_module<'a>( functions }; + let mut package_module_ids = (*package_module_ids).lock(); + + for exposed in header.exposes { + if let ExposesEntry::Exposed(module_name) = exposed.value { + package_module_ids.get_or_insert(&(shorthand, module_name.into())); + } + } + let exposed_ident_ids = { // Lock just long enough to perform the minimal operations necessary. let mut module_ids = (*module_ids).lock(); @@ -2782,7 +2899,7 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result, Loadi Ok(Msg::Parsed(parsed)) } -fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec) { +fn exposed_from_import<'a>(entry: &ImportsEntry<'a>) -> (QualifiedModuleName<'a>, Vec) { use roc_parse::header::ImportsEntry::*; match entry { @@ -2793,11 +2910,27 @@ fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec) { exposed.push(ident_from_exposed(&loc_entry.value)); } - (module_name.as_str().into(), exposed) + let qualified_module_name = QualifiedModuleName { + opt_package: None, + module: module_name.as_str().into(), + }; + + (qualified_module_name, exposed) } - Package(_package_name, _module_name, _exposes) => { - todo!("TODO support exposing package-qualified module names."); + Package(package_name, module_name, exposes) => { + let mut exposed = Vec::with_capacity(exposes.len()); + + for loc_entry in exposes { + exposed.push(ident_from_exposed(&loc_entry.value)); + } + + let qualified_module_name = QualifiedModuleName { + opt_package: Some(package_name), + module: module_name.as_str().into(), + }; + + (qualified_module_name, exposed) } SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => { @@ -3074,6 +3207,7 @@ fn run_task<'a>( LoadModule { module_name, module_ids, + package_module_ids, ident_ids_by_module, mode, } => load_module( @@ -3081,15 +3215,26 @@ fn run_task<'a>( src_dir, module_name, module_ids, + package_module_ids, ident_ids_by_module, mode, ) .map(|(_, msg)| msg), LoadPkgConfig { + shorthand, module_ids, + package_module_ids, ident_ids_by_module, mode, - } => load_pkg_config(arena, src_dir, module_ids, ident_ids_by_module, mode), + } => load_pkg_config( + arena, + src_dir, + shorthand, + module_ids, + package_module_ids, + ident_ids_by_module, + mode, + ), Parse { header } => parse(arena, header), CanonicalizeAndConstrain { parsed, diff --git a/compiler/module/src/ident.rs b/compiler/module/src/ident.rs index f3bcb53561..438fa88060 100644 --- a/compiler/module/src/ident.rs +++ b/compiler/module/src/ident.rs @@ -12,6 +12,11 @@ impl Ident { } } +pub struct QualifiedModuleName<'a> { + pub opt_package: Option<&'a str>, + pub module: ModuleName, +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct ModuleName(InlinableString); diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index fc5a8a9712..c434a01c4c 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -310,6 +310,69 @@ impl fmt::Debug for ModuleId { } } +/// base.Task +/// 1. build mapping from short name to package +/// 2. when adding new modules from package we need to register them in some other map (this module id goes with short name) (shortname, module-name) -> moduleId +/// 3. pass this around to other modules getting headers parsed. when parsing interfaces we need to use this map to reference shortnames +/// 4. throw away short names. stash the module id in the can env under the resolved module name +/// 5. test: + +type PackageModule<'a> = (&'a str, InlinableString); + +#[derive(Debug, Clone)] +pub struct PackageModuleIds<'a> { + by_name: MutMap, ModuleId>, + by_id: Vec>, +} + +impl<'a> PackageModuleIds<'a> { + pub fn get_or_insert(&mut self, module_name: &PackageModule<'a>) -> ModuleId { + match self.by_name.get(module_name) { + Some(id) => *id, + None => { + let by_id = &mut self.by_id; + let module_id = ModuleId(by_id.len() as u32); + + by_id.push(module_name.clone()); + + self.by_name.insert(module_name.clone(), module_id); + + if cfg!(debug_assertions) { + Self::insert_debug_name(module_id, &module_name); + } + + module_id + } + } + } + + #[cfg(debug_assertions)] + fn insert_debug_name(module_id: ModuleId, module_name: &PackageModule) { + let mut names = DEBUG_MODULE_ID_NAMES.lock().expect("Failed to acquire lock for Debug interning into DEBUG_MODULE_ID_NAMES, presumably because a thread panicked."); + + let (_package, module) = module_name; + + names.insert(module_id.0, module.to_string().into()); + } + + #[cfg(not(debug_assertions))] + fn insert_debug_name(_module_id: ModuleId, _module_name: &PackageModule) { + // By design, this is a no-op in release builds! + } + + pub fn get_id(&self, module_name: &PackageModule<'a>) -> Option<&ModuleId> { + self.by_name.get(module_name) + } + + pub fn get_name(&self, id: ModuleId) -> Option<&PackageModule> { + self.by_id.get(id.0 as usize) + } + + pub fn available_modules(&self) -> impl Iterator { + self.by_id.iter() + } +} + /// Stores a mapping between ModuleId and InlinableString. /// /// Each module name is stored twice, for faster lookups. @@ -551,6 +614,18 @@ macro_rules! define_builtins { } } + impl<'a> Default for PackageModuleIds<'a> { + fn default() -> Self { + // +1 because the user will be compiling at least 1 non-builtin module! + let capacity = $total + 1; + + let by_name = HashMap::with_capacity_and_hasher(capacity, default_hasher()); + let by_id = Vec::with_capacity(capacity); + + PackageModuleIds { by_name, by_id } + } + } + impl Symbol { $( $( diff --git a/examples/effect/Main.roc b/examples/effect/Main.roc index 3dfe057496..9295df2d36 100644 --- a/examples/effect/Main.roc +++ b/examples/effect/Main.roc @@ -1,7 +1,9 @@ -app "effect-example" imports [ Effect ] provides [ main ] to "./platform" +app "effect-example" + packages { base: "./thing/platform-dir" } + imports [ base.Task.{ Task, after } ] + provides [ main ] to base - -main : Effect.Effect {} as Fx +main : Task {} main = when if 1 == 1 then True 3 else False 3.14 is True n -> Effect.putLine (Str.fromInt n) diff --git a/examples/effect/platform/Cargo.lock b/examples/effect/thing/platform-dir/Cargo.lock similarity index 100% rename from examples/effect/platform/Cargo.lock rename to examples/effect/thing/platform-dir/Cargo.lock diff --git a/examples/effect/platform/Cargo.toml b/examples/effect/thing/platform-dir/Cargo.toml similarity index 100% rename from examples/effect/platform/Cargo.toml rename to examples/effect/thing/platform-dir/Cargo.toml diff --git a/examples/effect/platform/Pkg-Config.roc b/examples/effect/thing/platform-dir/Pkg-Config.roc similarity index 93% rename from examples/effect/platform/Pkg-Config.roc rename to examples/effect/thing/platform-dir/Pkg-Config.roc index ec2c67ca43..78afc1799e 100644 --- a/examples/effect/platform/Pkg-Config.roc +++ b/examples/effect/thing/platform-dir/Pkg-Config.roc @@ -1,6 +1,6 @@ platform folkertdev/foo requires { main : Effect {} } - exposes [] + exposes [ Task ] packages {} imports [] provides [ mainForHost ] diff --git a/examples/effect/thing/platform-dir/Task.roc b/examples/effect/thing/platform-dir/Task.roc new file mode 100644 index 0000000000..10722f5905 --- /dev/null +++ b/examples/effect/thing/platform-dir/Task.roc @@ -0,0 +1,9 @@ +interface Task + exposes [ Task, putLine, after ] + imports [ Effect ] + +Task a : Effect.Effect a + +putLine = Effect.putLine + +after = Effect.after diff --git a/examples/effect/platform/host.c b/examples/effect/thing/platform-dir/host.c similarity index 100% rename from examples/effect/platform/host.c rename to examples/effect/thing/platform-dir/host.c diff --git a/examples/effect/platform/src/lib.rs b/examples/effect/thing/platform-dir/src/lib.rs similarity index 100% rename from examples/effect/platform/src/lib.rs rename to examples/effect/thing/platform-dir/src/lib.rs