diff --git a/cli/src/main.rs b/cli/src/main.rs index 0be3741de3..239f10a31b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -16,7 +16,7 @@ use roc_gen::llvm::build::{ use roc_gen::llvm::convert::basic_type_from_layout; use roc_load::file::{LoadedModule, LoadingProblem}; use roc_module::symbol::Symbol; -use roc_mono::expr::{Expr, Procs}; +use roc_mono::expr::{Env, Expr, PartialProc, Procs}; use roc_mono::layout::Layout; use std::time::SystemTime; @@ -220,6 +220,8 @@ async fn build_file( Ok(binary_path) } +// TODO this should probably use more helper functions +#[allow(clippy::cognitive_complexity)] fn gen( arena: &Bump, loaded: LoadedModule, @@ -275,17 +277,22 @@ fn gen( } } + let mut decls_by_id = loaded.declarations_by_id; + let home_decls = decls_by_id + .remove(&loaded.module_id) + .expect("Root module ID not found in loaded declarations_by_id"); + // We use a loop label here so we can break all the way out of a nested // loop inside DeclareRec if we find the expr there. // // https://doc.rust-lang.org/1.30.0/book/first-edition/loops.html#loop-labels - 'find_expr: for decl in loaded.declarations { + 'find_expr: for decl in home_decls.iter() { use roc_can::def::Declaration::*; match decl { Declare(def) => { if def.pattern_vars.contains_key(&main_symbol) { - main_expr = Some(def.loc_expr); + main_expr = Some(def.loc_expr.clone()); break 'find_expr; } @@ -294,7 +301,7 @@ fn gen( DeclareRec(defs) => { for def in defs { if def.pattern_vars.contains_key(&main_symbol) { - main_expr = Some(def.loc_expr); + main_expr = Some(def.loc_expr.clone()); break 'find_expr; } @@ -347,20 +354,74 @@ fn gen( ptr_bytes, }; let mut procs = Procs::default(); - let mut ident_ids = env.interns.all_ident_ids.remove(&home).unwrap(); - - // Populate Procs and get the low-level Expr from the canonical Expr let mut mono_problems = std::vec::Vec::new(); - let main_body = Expr::new( - &arena, - &mut subs, - &mut mono_problems, - loc_expr.value, - &mut procs, + let mut ident_ids = env.interns.all_ident_ids.remove(&home).unwrap(); + let mut mono_env = Env { + arena, + subs: &mut subs, + problems: &mut mono_problems, home, - &mut ident_ids, - ptr_bytes, - ); + ident_ids: &mut ident_ids, + pointer_size: ptr_bytes, + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + + // Add modules' decls to Procs + for (_, mut decls) in decls_by_id + .drain() + .chain(std::iter::once((loaded.module_id, home_decls))) + { + for decl in decls.drain(..) { + use roc_can::def::Declaration::*; + use roc_can::expr::Expr::*; + use roc_can::pattern::Pattern::*; + + match decl { + Declare(def) => match def.loc_pattern.value { + Identifier(symbol) => { + match def.loc_expr.value { + Closure(annotation, _, _, loc_args, boxed_body) => { + let (loc_body, ret_var) = *boxed_body; + + procs.insert_closure( + &mut mono_env, + Some(symbol), + annotation, + loc_args, + loc_body, + ret_var, + ); + } + body => { + let proc = PartialProc { + annotation: def.expr_var, + // This is a 0-arity thunk, so it has no arguments. + patterns: bumpalo::collections::Vec::new_in(arena), + body, + }; + + procs.user_defined.insert(symbol, proc); + procs.module_thunks.insert(symbol); + } + }; + } + other => { + todo!("TODO gracefully handle Declare({:?})", other); + } + }, + DeclareRec(_defs) => { + todo!("TODO support DeclareRec"); + } + InvalidCycle(_loc_idents, _regions) => { + todo!("TODO handle InvalidCycle"); + } + } + } + } + + // Populate Procs further and get the low-level Expr from the canonical Expr + let main_body = Expr::new(&mut mono_env, loc_expr.value, &mut procs); // Put this module's ident_ids back in the interns, so we can use them in env. env.interns.all_ident_ids.insert(home, ident_ids); diff --git a/cli/src/repl.rs b/cli/src/repl.rs index ce6df93395..6f3c072b49 100644 --- a/cli/src/repl.rs +++ b/cli/src/repl.rs @@ -246,16 +246,17 @@ pub fn gen(src: &str, target: Triple, opt_level: OptLevel) -> Result<(String, St // Populate Procs and get the low-level Expr from the canonical Expr let mut mono_problems = Vec::new(); - let main_body = roc_mono::expr::Expr::new( - &arena, - &mut subs, - &mut mono_problems, - loc_expr.value, - &mut procs, + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, home, - &mut ident_ids, - ptr_bytes, - ); + ident_ids: &mut ident_ids, + pointer_size: ptr_bytes, + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let main_body = roc_mono::expr::Expr::new(&mut mono_env, loc_expr.value, &mut procs); // Put this module's ident_ids back in the interns, so we can use them in Env. env.interns.all_ident_ids.insert(home, ident_ids); diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index 09a51ce1b7..55ed8dc92f 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -35,8 +35,7 @@ pub fn standard_stdlib() -> StdLib { } } -/// Keep this up to date by hand! -/// +/// Keep this up to date by hand! It's the number of builtin aliases that are imported by default. const NUM_BUILTIN_IMPORTS: usize = 7; /// These can be shared between definitions, they will get instantiated when converted to Type diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index 00d7266c9e..85929ff2b8 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -3,8 +3,8 @@ use crate::expr::Expr; use crate::expr::Recursive; use roc_collections::all::SendMap; use roc_module::ident::TagName; +use roc_module::operator::CalledVia; use roc_module::symbol::Symbol; -use roc_parse::operator::CalledVia; use roc_region::all::{Located, Region}; use roc_types::subs::{VarStore, Variable}; diff --git a/compiler/can/src/expr.rs b/compiler/can/src/expr.rs index 1289a61730..22d627824d 100644 --- a/compiler/can/src/expr.rs +++ b/compiler/can/src/expr.rs @@ -10,9 +10,9 @@ use crate::procedure::References; use crate::scope::Scope; use roc_collections::all::{ImSet, MutMap, MutSet, SendMap}; use roc_module::ident::{Lowercase, TagName}; +use roc_module::operator::CalledVia; use roc_module::symbol::Symbol; use roc_parse::ast; -use roc_parse::operator::CalledVia; use roc_parse::pattern::PatternType::*; use roc_problem::can::{PrecedenceProblem, Problem, RuntimeError}; use roc_region::all::{Located, Region}; diff --git a/compiler/can/src/operator.rs b/compiler/can/src/operator.rs index 297b3d4bcf..6e005d9396 100644 --- a/compiler/can/src/operator.rs +++ b/compiler/can/src/operator.rs @@ -1,10 +1,10 @@ use bumpalo::collections::Vec; use bumpalo::Bump; use roc_module::ident::ModuleName; +use roc_module::operator::BinOp::Pizza; +use roc_module::operator::{BinOp, CalledVia}; use roc_parse::ast::Expr::{self, *}; use roc_parse::ast::{AssignedField, Def, Pattern, WhenBranch}; -use roc_parse::operator::BinOp::Pizza; -use roc_parse::operator::{BinOp, CalledVia}; use roc_region::all::{Located, Region}; // BinOp precedence logic adapted from Gluon by Markus Westerlind, MIT licensed @@ -201,7 +201,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a }) } UnaryOp(loc_arg, loc_op) | Nested(UnaryOp(loc_arg, loc_op)) => { - use roc_parse::operator::UnaryOp::*; + use roc_module::operator::UnaryOp::*; let region = loc_op.region; let op = loc_op.value; @@ -327,7 +327,7 @@ fn binop_to_function(binop: BinOp) -> (&'static str, &'static str) { } fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a Located> { - use roc_parse::operator::Associativity::*; + use roc_module::operator::Associativity::*; use std::cmp::Ordering; let mut infixes = Infixes::new(loc_expr); diff --git a/compiler/fmt/src/expr.rs b/compiler/fmt/src/expr.rs index a25a394d7b..74faab0577 100644 --- a/compiler/fmt/src/expr.rs +++ b/compiler/fmt/src/expr.rs @@ -4,9 +4,8 @@ use crate::spaces::{ add_spaces, fmt_comments_only, fmt_condition_spaces, fmt_spaces, is_comment, newline, INDENT, }; use bumpalo::collections::{String, Vec}; +use roc_module::operator::{self, BinOp}; use roc_parse::ast::{AssignedField, Base, CommentOrNewline, Expr, Pattern, WhenBranch}; -use roc_parse::operator; -use roc_parse::operator::BinOp; use roc_region::all::Located; pub fn fmt_expr<'a>( diff --git a/compiler/gen/tests/helpers/eval.rs b/compiler/gen/tests/helpers/eval.rs index 34f9dd5b44..69208d006c 100644 --- a/compiler/gen/tests/helpers/eval.rs +++ b/compiler/gen/tests/helpers/eval.rs @@ -63,7 +63,17 @@ macro_rules! assert_llvm_evals_to { // Populate Procs and get the low-level Expr from the canonical Expr let mut mono_problems = Vec::new(); - let main_body = Expr::new(&arena, &mut subs, &mut mono_problems, loc_expr.value, &mut procs, home, &mut ident_ids, ptr_bytes); + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, + home, + ident_ids: &mut ident_ids, + pointer_size: ptr_bytes, + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let main_body = Expr::new(&mut mono_env, loc_expr.value, &mut procs); // Put this module's ident_ids back in the interns, so we can use them in Env. env.interns.all_ident_ids.insert(home, ident_ids); @@ -215,7 +225,17 @@ macro_rules! assert_opt_evals_to { // Populate Procs and get the low-level Expr from the canonical Expr let mut mono_problems = Vec::new(); - let main_body = Expr::new(&arena, &mut subs, &mut mono_problems, loc_expr.value, &mut procs, home, &mut ident_ids, ptr_bytes); + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, + home, + ident_ids: &mut ident_ids, + pointer_size: ptr_bytes, + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let main_body = Expr::new(&mut mono_env, loc_expr.value, &mut procs); // Put this module's ident_ids back in the interns, so we can use them in Env. env.interns.all_ident_ids.insert(home, ident_ids); @@ -361,7 +381,17 @@ macro_rules! emit_expr { let mut ident_ids = env.interns.all_ident_ids.remove(&home).unwrap(); // Populate Procs and get the low-level Expr from the canonical Expr - let main_body = Expr::new(&arena, &mut subs, loc_expr.value, &mut procs, home, &mut ident_ids, $crate::helpers::eval::POINTER_SIZE); + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, + home, + ident_ids: &mut ident_ids, + pointer_size: ptr_bytes, + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let main_body = Expr::new(&mut mono_env, loc_expr.value, &mut procs); // Put this module's ident_ids back in the interns, so we can use them in Env. env.interns.all_ident_ids.insert(home, ident_ids); diff --git a/compiler/gen/tests/helpers/mod.rs b/compiler/gen/tests/helpers/mod.rs index b3bfae3e2c..60f955af4a 100644 --- a/compiler/gen/tests/helpers/mod.rs +++ b/compiler/gen/tests/helpers/mod.rs @@ -282,7 +282,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut }) .collect(); - //load builtin values + // load builtin values let (_introduced_rigids, constraint) = constrain_imported_values(imports, constraint, &var_store); diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 6b7687f70c..659bb90e04 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -53,7 +53,7 @@ pub struct LoadedModule { pub solved: Solved, pub can_problems: Vec, pub type_problems: Vec, - pub declarations: Vec, + pub declarations_by_id: MutMap>, pub exposed_vars_by_symbol: Vec<(Symbol, Variable)>, pub src: Box, } @@ -417,10 +417,6 @@ pub async fn load<'a>( .into_inner() .expect("Unwrapping mutex for module_ids"); - let declarations = declarations_by_id - .remove(&module_id) - .expect("declarations_by_id was missing root module_id entry"); - let interns = Interns { module_ids, all_ident_ids: constrained_ident_ids, @@ -432,7 +428,7 @@ pub async fn load<'a>( solved, can_problems, type_problems, - declarations, + declarations_by_id, exposed_vars_by_symbol, src, }); diff --git a/compiler/load/tests/test_load.rs b/compiler/load/tests/test_load.rs index 058673bd7a..b54c1fd199 100644 --- a/compiler/load/tests/test_load.rs +++ b/compiler/load/tests/test_load.rs @@ -81,16 +81,18 @@ mod test_load { } } - fn expect_types(loaded_module: LoadedModule, expected_types: HashMap<&str, &str>) { + fn expect_types(mut loaded_module: LoadedModule, expected_types: HashMap<&str, &str>) { let home = loaded_module.module_id; let mut subs = loaded_module.solved.into_inner(); assert_eq!(loaded_module.can_problems, Vec::new()); assert_eq!(loaded_module.type_problems, Vec::new()); - let num_decls = loaded_module.declarations.len(); + let mut num_decls = 0; + + for decl in loaded_module.declarations_by_id.remove(&home).unwrap() { + num_decls += 1; - for decl in loaded_module.declarations { match decl { Declare(def) => expect_def( &loaded_module.interns, @@ -135,14 +137,17 @@ mod test_load { subs_by_module, ) .await; - let loaded_module = loaded.expect("Test module failed to load"); + + let mut loaded_module = loaded.expect("Test module failed to load"); assert_eq!(loaded_module.can_problems, Vec::new()); assert_eq!(loaded_module.type_problems, Vec::new()); let def_count: usize = loaded_module - .declarations - .iter() + .declarations_by_id + .remove(&loaded_module.module_id) + .unwrap() + .into_iter() .map(|decl| decl.def_count()) .sum(); diff --git a/compiler/load/tests/test_uniq_load.rs b/compiler/load/tests/test_uniq_load.rs index 785b98ebe1..ee3360632e 100644 --- a/compiler/load/tests/test_uniq_load.rs +++ b/compiler/load/tests/test_uniq_load.rs @@ -76,16 +76,18 @@ mod test_uniq_load { } } - fn expect_types(loaded_module: LoadedModule, expected_types: HashMap<&str, &str>) { + fn expect_types(mut loaded_module: LoadedModule, expected_types: HashMap<&str, &str>) { let home = loaded_module.module_id; let mut subs = loaded_module.solved.into_inner(); assert_eq!(loaded_module.can_problems, Vec::new()); assert_eq!(loaded_module.type_problems, Vec::new()); - let num_decls = loaded_module.declarations.len(); + let mut num_decls = 0; + + for decl in loaded_module.declarations_by_id.remove(&home).unwrap() { + num_decls += 1; - for decl in loaded_module.declarations { match decl { Declare(def) => expect_def( &loaded_module.interns, @@ -130,14 +132,17 @@ mod test_uniq_load { subs_by_module, ) .await; - let loaded_module = loaded.expect("Test module failed to load"); + + let mut loaded_module = loaded.expect("Test module failed to load"); assert_eq!(loaded_module.can_problems, Vec::new()); assert_eq!(loaded_module.type_problems, Vec::new()); let def_count: usize = loaded_module - .declarations - .iter() + .declarations_by_id + .remove(&loaded_module.module_id) + .unwrap() + .into_iter() .map(|decl| decl.def_count()) .sum(); diff --git a/compiler/module/src/lib.rs b/compiler/module/src/lib.rs index 78777141ce..b8a460f173 100644 --- a/compiler/module/src/lib.rs +++ b/compiler/module/src/lib.rs @@ -12,6 +12,7 @@ #![allow(clippy::large_enum_variant)] pub mod ident; +pub mod operator; pub mod symbol; #[macro_use] diff --git a/compiler/parse/src/operator.rs b/compiler/module/src/operator.rs similarity index 100% rename from compiler/parse/src/operator.rs rename to compiler/module/src/operator.rs diff --git a/compiler/mono/src/expr.rs b/compiler/mono/src/expr.rs index 62734a1f2c..e460d6434e 100644 --- a/compiler/mono/src/expr.rs +++ b/compiler/mono/src/expr.rs @@ -27,7 +27,8 @@ pub struct Proc<'a> { #[derive(Clone, Debug, PartialEq, Default)] pub struct Procs<'a> { - user_defined: MutMap>, + pub user_defined: MutMap>, + pub module_thunks: MutSet, anonymous: MutMap>>, specializations: MutMap>)>, builtin: MutSet, @@ -42,6 +43,66 @@ impl<'a> Procs<'a> { self.anonymous.insert(symbol, proc); } + pub fn insert_closure( + &mut self, + env: &mut Env<'a, '_>, + name: Option, + annotation: Variable, + loc_args: std::vec::Vec<(Variable, Located)>, + loc_body: Located, + ret_var: Variable, + ) -> Symbol { + // turn record/tag patterns into a when expression, e.g. + // + // foo = \{ x } -> body + // + // becomes + // + // foo = \r -> when r is { x } -> body + // + // conversion of one-pattern when expressions will do the most optimal thing + + let (arg_vars, arg_symbols, body) = patterns_to_when(env, loc_args, ret_var, loc_body); + + match name { + Some(symbol) => { + // a named closure + self.insert_user_defined( + symbol, + PartialProc { + annotation, + patterns: arg_symbols, + body: body.value, + }, + ); + + symbol + } + None => { + // an anonymous closure. These will always be specialized already + // by the surrounding context + let symbol = env.fresh_symbol(); + + let opt_proc = specialize_proc_body( + env, + self, + annotation, + ret_var, + symbol, + &arg_vars, + &arg_symbols, + annotation, + body.value, + ) + .ok(); + + self.insert_anonymous(symbol, opt_proc); + + symbol + } + } + } + fn insert_specialization( &mut self, hash: ContentHash, @@ -96,8 +157,8 @@ pub struct Env<'a, 'i> { pub home: ModuleId, pub ident_ids: &'i mut IdentIds, pub pointer_size: u32, - symbol_counter: usize, pub jump_counter: &'a mut u64, + pub symbol_counter: usize, } impl<'a, 'i> Env<'a, 'i> { @@ -203,27 +264,11 @@ pub enum MonoProblem { #[allow(clippy::too_many_arguments)] impl<'a> Expr<'a> { pub fn new( - arena: &'a Bump, - subs: &'a mut Subs, - problems: &mut std::vec::Vec, + env: &mut Env<'a, '_>, can_expr: roc_can::expr::Expr, procs: &mut Procs<'a>, - home: ModuleId, - ident_ids: &mut IdentIds, - pointer_size: u32, ) -> Self { - let mut env = Env { - arena, - subs, - problems, - home, - ident_ids, - pointer_size, - symbol_counter: 0, - jump_counter: arena.alloc(0), - }; - - from_can(&mut env, can_expr, procs, None) + from_can(env, can_expr, procs, None) } } @@ -426,61 +471,24 @@ fn from_can<'a>( Int(_, num) => Expr::Int(num), Float(_, num) => Expr::Float(num), Str(string) | BlockStr(string) => Expr::Str(env.arena.alloc(string)), - Var(symbol) => Expr::Load(symbol), + Var(symbol) => { + if procs.module_thunks.contains(&symbol) { + let partial_proc = procs.get_user_defined(symbol).unwrap(); + let fn_var = partial_proc.annotation; + let ret_var = partial_proc.annotation; + + // This is a top-level declaration, which will code gen to a 0-arity thunk. + call_by_name(env, procs, fn_var, ret_var, symbol, std::vec::Vec::new()) + } else { + Expr::Load(symbol) + } + } LetRec(defs, ret_expr, _, _) => from_can_defs(env, defs, *ret_expr, procs), LetNonRec(def, ret_expr, _, _) => from_can_defs(env, vec![*def], *ret_expr, procs), Closure(annotation, _, _, loc_args, boxed_body) => { let (loc_body, ret_var) = *boxed_body; - - // turn record/tag patterns into a when expression, e.g. - // - // foo = \{ x } -> body - // - // becomes - // - // foo = \r -> when r is { x } -> body - // - // conversion of one-pattern when expressions will do the most optimal thing - - let (arg_vars, arg_symbols, body) = patterns_to_when(env, loc_args, ret_var, loc_body); - - let symbol = match name { - Some(symbol) => { - // a named closure - procs.insert_user_defined( - symbol, - PartialProc { - annotation, - patterns: arg_symbols, - body: body.value, - }, - ); - symbol - } - None => { - // an anonymous closure. These will always be specialized already - // by the surrounding context - let symbol = env.fresh_symbol(); - - let opt_proc = specialize_proc_body( - env, - procs, - annotation, - ret_var, - symbol, - &arg_vars, - &arg_symbols, - annotation, - body.value, - ) - .ok(); - - procs.insert_anonymous(symbol, opt_proc); - - symbol - } - }; + let symbol = procs.insert_closure(env, name, annotation, loc_args, loc_body, ret_var); Expr::FunctionPointer(symbol) } diff --git a/compiler/mono/tests/test_mono.rs b/compiler/mono/tests/test_mono.rs index 8269fb347c..6c46c5639f 100644 --- a/compiler/mono/tests/test_mono.rs +++ b/compiler/mono/tests/test_mono.rs @@ -53,16 +53,17 @@ mod test_mono { // Populate Procs and Subs, and get the low-level Expr from the canonical Expr let mut mono_problems = Vec::new(); - let mono_expr = Expr::new( - &arena, - &mut subs, - &mut mono_problems, - loc_expr.value, - &mut procs, + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, home, - &mut ident_ids, + ident_ids: &mut ident_ids, pointer_size, - ); + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs); // Put this module's ident_ids back in the interns interns.all_ident_ids.insert(home, ident_ids); diff --git a/compiler/mono/tests/test_opt.rs b/compiler/mono/tests/test_opt.rs index 6cdde4c792..b93aff0e58 100644 --- a/compiler/mono/tests/test_opt.rs +++ b/compiler/mono/tests/test_opt.rs @@ -42,16 +42,17 @@ mod test_opt { // Populate Procs and Subs, and get the low-level Expr from the canonical Expr let mut mono_problems = Vec::new(); - let mono_expr = Expr::new( - &arena, - &mut subs, - &mut mono_problems, - loc_expr.value, - &mut procs, + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, home, - &mut ident_ids, + ident_ids: &mut ident_ids, pointer_size, - ); + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs); let unexpected_calls = extract_named_calls(&mono_expr, &mut calls); let expected = CallProblems::default(); @@ -193,16 +194,17 @@ mod test_opt { // Populate Procs and Subs, and get the low-level Expr from the canonical Expr let mut mono_problems = Vec::new(); - let mono_expr = Expr::new( - &arena, - &mut subs, - &mut mono_problems, - loc_expr.value, - &mut procs, + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, home, - &mut ident_ids, + ident_ids: &mut ident_ids, pointer_size, - ); + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs); assert_eq!(mono_expr, expected); } diff --git a/compiler/parse/src/ast.rs b/compiler/parse/src/ast.rs index d24ea05ad7..b7386146ad 100644 --- a/compiler/parse/src/ast.rs +++ b/compiler/parse/src/ast.rs @@ -1,10 +1,9 @@ use crate::header::ModuleName; use crate::ident::Ident; -use crate::operator::CalledVia; -use crate::operator::{BinOp, UnaryOp}; use bumpalo::collections::String; use bumpalo::collections::Vec; use bumpalo::Bump; +use roc_module::operator::{BinOp, CalledVia, UnaryOp}; use roc_region::all::{Loc, Region}; #[derive(Clone, Debug, PartialEq)] diff --git a/compiler/parse/src/expr.rs b/compiler/parse/src/expr.rs index b09240a658..87acc8649c 100644 --- a/compiler/parse/src/expr.rs +++ b/compiler/parse/src/expr.rs @@ -7,7 +7,6 @@ use crate::blankspace::{ use crate::ident::{global_tag_or_ident, ident, lowercase_ident, Ident}; use crate::keyword; use crate::number_literal::number_literal; -use crate::operator::{BinOp, CalledVia, UnaryOp}; use crate::parser::{ self, allocated, char, fail, not, not_followed_by, optional, sep_by1, string, then, unexpected, unexpected_eof, Either, Fail, FailReason, ParseResult, Parser, State, @@ -16,6 +15,7 @@ use crate::type_annotation; use bumpalo::collections::string::String; use bumpalo::collections::Vec; use bumpalo::Bump; +use roc_module::operator::{BinOp, CalledVia, UnaryOp}; use roc_region::all::{Located, Region}; pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> { diff --git a/compiler/parse/src/lib.rs b/compiler/parse/src/lib.rs index 6920568252..af7f71fbcf 100644 --- a/compiler/parse/src/lib.rs +++ b/compiler/parse/src/lib.rs @@ -21,7 +21,6 @@ pub mod ident; pub mod keyword; pub mod module; pub mod number_literal; -pub mod operator; pub mod pattern; pub mod problems; pub mod string_literal; diff --git a/compiler/parse/tests/test_parse.rs b/compiler/parse/tests/test_parse.rs index c66e250cc0..7c71a92415 100644 --- a/compiler/parse/tests/test_parse.rs +++ b/compiler/parse/tests/test_parse.rs @@ -18,6 +18,8 @@ mod test_parse { use crate::helpers::parse_with; use bumpalo::collections::vec::Vec; use bumpalo::{self, Bump}; + use roc_module::operator::BinOp::*; + use roc_module::operator::{CalledVia, UnaryOp}; use roc_parse::ast::AssignedField::*; use roc_parse::ast::CommentOrNewline::*; use roc_parse::ast::Expr::{self, *}; @@ -27,9 +29,6 @@ mod test_parse { }; use roc_parse::header::ModuleName; use roc_parse::module::{interface_header, module_defs}; - use roc_parse::operator::BinOp::*; - use roc_parse::operator::CalledVia; - use roc_parse::operator::UnaryOp; use roc_parse::parser::{Fail, FailReason, Parser, State}; use roc_region::all::{Located, Region}; use std::{f64, i64}; diff --git a/compiler/problem/src/can.rs b/compiler/problem/src/can.rs index 0035b7a5b8..5f83be28b0 100644 --- a/compiler/problem/src/can.rs +++ b/compiler/problem/src/can.rs @@ -1,8 +1,8 @@ use inlinable_string::InlinableString; use roc_collections::all::MutSet; use roc_module::ident::{Ident, Lowercase, TagName}; +use roc_module::operator::BinOp; use roc_module::symbol::{ModuleId, Symbol}; -use roc_parse::operator::BinOp; use roc_parse::pattern::PatternType; use roc_region::all::{Located, Region}; diff --git a/compiler/reporting/src/report.rs b/compiler/reporting/src/report.rs index 25cb34c2a9..124bec113a 100644 --- a/compiler/reporting/src/report.rs +++ b/compiler/reporting/src/report.rs @@ -299,7 +299,7 @@ impl<'a> RocDocAllocator<'a> { pub fn binop( &'a self, - content: roc_parse::operator::BinOp, + content: roc_module::operator::BinOp, ) -> DocBuilder<'a, Self, Annotation> { self.text(content.to_string()).annotate(Annotation::BinOp) } diff --git a/compiler/reporting/tests/test_reporting.rs b/compiler/reporting/tests/test_reporting.rs index 23225fffef..7b0bc1bc03 100644 --- a/compiler/reporting/tests/test_reporting.rs +++ b/compiler/reporting/tests/test_reporting.rs @@ -90,16 +90,17 @@ mod test_reporting { let pointer_size = std::mem::size_of::() as u32; // Populate Procs and Subs, and get the low-level Expr from the canonical Expr - let _mono_expr = Expr::new( - &arena, - &mut subs, - &mut mono_problems, - loc_expr.value, - &mut procs, + let mut mono_env = roc_mono::expr::Env { + arena: &arena, + subs: &mut subs, + problems: &mut mono_problems, home, - &mut ident_ids, + ident_ids: &mut ident_ids, pointer_size, - ); + symbol_counter: 0, + jump_counter: arena.alloc(0), + }; + let _mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs); } Ok((unify_problems, can_problems, mono_problems, home, interns)) diff --git a/examples/hello-world/Hello.roc b/examples/hello-world/Hello.roc index ef6ba9f212..0d3d072597 100644 --- a/examples/hello-world/Hello.roc +++ b/examples/hello-world/Hello.roc @@ -1,3 +1,8 @@ app Hello provides [ main ] imports [] -main = "Hello, World!" +greeting = + hi = "Hello, World!" + + hi + +main = greeting