basic version of editor/module

This commit is contained in:
Folkert 2020-12-27 16:22:34 +01:00
parent 264b6884f0
commit a6ee72dbac
2 changed files with 72 additions and 63 deletions

View file

@ -44,19 +44,24 @@ pub enum Def {
} }
impl Def { impl Def {
pub fn pattern_vars(&self, pool: &Pool) -> impl Iterator<(Symbol, Variable)> { pub fn symbols(&self, pool: &Pool) -> MutSet<Symbol> {
use Def::*; let mut output = MutSet::default();
match self { match self {
AnnotationOnly { .. } => todo!("we lost pattern information!"), Def::AnnotationOnly { .. } => todo!("lost pattern information here ... "),
Value(ValueDef { .. }) => symbols_and_variables_from_pattern(pool, pattern, var).iter(), Def::Value(ValueDef { pattern, .. }) => {
Function(FunctionDef::NoAnnotation { name, expr_var, .. }) => { let pattern2 = &pool[*pattern];
std::iter::once((name, expr_var)) output.extend(symbols_from_pattern(pool, pattern2));
}
Function(FunctionDef::WithAnnotation { name, expr_var, .. }) => {
std::iter::once((name, expr_var))
} }
Def::Function(function_def) => match function_def {
FunctionDef::NoAnnotation { name, .. }
| FunctionDef::WithAnnotation { name, .. } => {
output.insert(*name);
}
},
} }
output
} }
} }
@ -804,7 +809,6 @@ pub struct CanDefs {
pub fn canonicalize_defs<'a>( pub fn canonicalize_defs<'a>(
env: &mut Env<'a>, env: &mut Env<'a>,
mut output: Output, mut output: Output,
var_store: &mut VarStore,
original_scope: &Scope, original_scope: &Scope,
loc_defs: &'a [&'a Located<ast::Def<'a>>], loc_defs: &'a [&'a Located<ast::Def<'a>>],
pattern_type: PatternType, pattern_type: PatternType,

View file

@ -2,11 +2,14 @@
#![allow(dead_code)] #![allow(dead_code)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(unused_variables)] #![allow(unused_variables)]
use crate::def::{canonicalize_defs, sort_can_defs}; use crate::ast::{FunctionDef, ValueDef};
use crate::def::{canonicalize_defs, sort_can_defs, Declaration, Def};
use crate::expr::Env; use crate::expr::Env;
use crate::expr::Output; use crate::expr::Output;
use crate::pool::{Pool, PoolStr, PoolVec}; use crate::pattern::Pattern2;
use crate::pool::{NodeId, Pool, PoolStr, PoolVec};
use crate::scope::Scope; use crate::scope::Scope;
use crate::types::Alias;
use bumpalo::Bump; use bumpalo::Bump;
use roc_can::operator::desugar_def; use roc_can::operator::desugar_def;
use roc_collections::all::{default_hasher, ImMap, ImSet, MutMap, MutSet, SendMap}; use roc_collections::all::{default_hasher, ImMap, ImSet, MutMap, MutSet, SendMap};
@ -18,9 +21,17 @@ use roc_parse::pattern::PatternType;
use roc_problem::can::{Problem, RuntimeError}; use roc_problem::can::{Problem, RuntimeError};
use roc_region::all::{Located, Region}; use roc_region::all::{Located, Region};
use roc_types::subs::{VarStore, Variable}; use roc_types::subs::{VarStore, Variable};
use roc_types::types::{Alias, Type};
pub struct ModuleOutput {} pub struct ModuleOutput {
pub aliases: MutMap<Symbol, NodeId<Alias>>,
pub rigid_variables: MutMap<Variable, Lowercase>,
pub declarations: Vec<Declaration>,
pub exposed_imports: MutMap<Symbol, Variable>,
pub lookups: Vec<(Symbol, Variable, Region)>,
pub problems: Vec<Problem>,
pub ident_ids: IdentIds,
pub references: MutSet<Symbol>,
}
// TODO trim these down // TODO trim these down
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -74,13 +85,13 @@ pub fn canonicalize_module_defs<'a>(
home, home,
arena, arena,
&mut pool, &mut pool,
&mut var_store, var_store,
dep_idents, dep_idents,
module_ids, module_ids,
exposed_ident_ids, exposed_ident_ids,
); );
let mut lookups = Vec::with_capacity(num_deps); let mut lookups = Vec::with_capacity(num_deps);
let mut rigid_variables = MutMap::default(); let rigid_variables = MutMap::default();
// Exposed values are treated like defs that appear before any others, e.g. // Exposed values are treated like defs that appear before any others, e.g.
// //
@ -98,7 +109,7 @@ pub fn canonicalize_module_defs<'a>(
if first_char.is_lowercase() { if first_char.is_lowercase() {
// this is a value definition // this is a value definition
let expr_var = var_store.fresh(); let expr_var = env.var_store.fresh();
match scope.import(ident, symbol, region) { match scope.import(ident, symbol, region) {
Ok(()) => { Ok(()) => {
@ -127,7 +138,6 @@ pub fn canonicalize_module_defs<'a>(
let (defs, _scope, output, symbols_introduced) = canonicalize_defs( let (defs, _scope, output, symbols_introduced) = canonicalize_defs(
&mut env, &mut env,
Output::default(), Output::default(),
var_store,
&scope, &scope,
&desugared, &desugared,
PatternType::TopLevelDef, PatternType::TopLevelDef,
@ -170,41 +180,30 @@ pub fn canonicalize_module_defs<'a>(
(Ok(mut declarations), output) => { (Ok(mut declarations), output) => {
use crate::def::Declaration::*; use crate::def::Declaration::*;
// Record the variables for all exposed symbols.
let mut exposed_vars_by_symbol = Vec::with_capacity(exposed_symbols.len());
for decl in declarations.iter() { for decl in declarations.iter() {
match decl { match decl {
Declare(def) => { Declare(def) => {
for (symbol, variable) in def.pattern_vars(env.pool) { for symbol in def.symbols(env.pool) {
if exposed_symbols.contains(symbol) { if exposed_symbols.contains(&symbol) {
// This is one of our exposed symbols;
// record the corresponding variable!
exposed_vars_by_symbol.push((*symbol, *variable));
// Remove this from exposed_symbols, // Remove this from exposed_symbols,
// so that at the end of the process, // so that at the end of the process,
// we can see if there were any // we can see if there were any
// exposed symbols which did not have // exposed symbols which did not have
// corresponding defs. // corresponding defs.
exposed_symbols.remove(symbol); exposed_symbols.remove(&symbol);
} }
} }
} }
DeclareRec(defs) => { DeclareRec(defs) => {
for def in defs { for def in defs {
for (symbol, variable) in def.pattern_vars(env.pool) { for symbol in def.symbols(env.pool) {
if exposed_symbols.contains(symbol) { if exposed_symbols.contains(&symbol) {
// This is one of our exposed symbols;
// record the corresponding variable!
exposed_vars_by_symbol.push((*symbol, *variable));
// Remove this from exposed_symbols, // Remove this from exposed_symbols,
// so that at the end of the process, // so that at the end of the process,
// we can see if there were any // we can see if there were any
// exposed symbols which did not have // exposed symbols which did not have
// corresponding defs. // corresponding defs.
exposed_symbols.remove(symbol); exposed_symbols.remove(&symbol);
} }
} }
} }
@ -217,9 +216,9 @@ pub fn canonicalize_module_defs<'a>(
// Builtins cannot be exposed in module declarations. // Builtins cannot be exposed in module declarations.
// This should never happen! // This should never happen!
debug_assert!(def debug_assert!(def
.pattern_vars .symbols(env.pool)
.iter() .iter()
.all(|(symbol, _)| !exposed_symbols.contains(symbol))); .all(|symbol| !exposed_symbols.contains(symbol)));
} }
} }
} }
@ -247,17 +246,21 @@ pub fn canonicalize_module_defs<'a>(
// In case this exposed value is referenced by other modules, // In case this exposed value is referenced by other modules,
// create a decl for it whose implementation is a runtime error. // create a decl for it whose implementation is a runtime error.
let mut pattern_vars = SendMap::default(); let mut pattern_vars = SendMap::default();
pattern_vars.insert(symbol, var_store.fresh()); pattern_vars.insert(symbol, env.var_store.fresh());
let runtime_error = RuntimeError::ExposedButNotDefined(symbol); let runtime_error = RuntimeError::ExposedButNotDefined(symbol);
let def = Def {
loc_pattern: Located::new(0, 0, 0, 0, Pattern::Identifier(symbol)), let value_def = {
loc_expr: Located::new(0, 0, 0, 0, Expr::RuntimeError(runtime_error)), let pattern = env.pool.add(Pattern2::Identifier(symbol));
expr_var: var_store.fresh(), ValueDef {
pattern_vars, pattern,
annotation: None, expr_type: None,
expr_var: env.var_store.fresh(),
}
}; };
let def = Def::Value(value_def);
declarations.push(Declaration::Declare(def)); declarations.push(Declaration::Declare(def));
} }
@ -276,26 +279,29 @@ pub fn canonicalize_module_defs<'a>(
references.insert(*symbol); references.insert(*symbol);
} }
for declaration in declarations.iter_mut() { // TODO find captured variables
match declaration { // for declaration in declarations.iter_mut() {
Declare(def) => fix_values_captured_in_closure_def(def, &mut MutSet::default()), // match declaration {
DeclareRec(defs) => { // Declare(def) => fix_values_captured_in_closure_def(def, &mut MutSet::default()),
fix_values_captured_in_closure_defs(defs, &mut MutSet::default()) // DeclareRec(defs) => {
} // fix_values_captured_in_closure_defs(defs, &mut MutSet::default())
InvalidCycle(_, _) | Builtin(_) => {} // }
} // InvalidCycle(_, _) | Builtin(_) => {}
} // }
// }
// TODO this loops over all symbols in the module, we can speed it up by having an // TODO this loops over all symbols in the module, we can speed it up by having an
// iterator over all builtin symbols // iterator over all builtin symbols
for symbol in references.iter() {
if symbol.is_builtin() { // TODO move over the builtins
// this can fail when the symbol is for builtin types, or has no implementation yet // for symbol in references.iter() {
if let Some(def) = builtins::builtin_defs_map(*symbol, var_store) { // if symbol.is_builtin() {
declarations.push(Declaration::Builtin(def)); // // this can fail when the symbol is for builtin types, or has no implementation yet
} // if let Some(def) = builtins::builtin_defs_map(*symbol, var_store) {
} // declarations.push(Declaration::Builtin(def));
} // }
// }
// }
Ok(ModuleOutput { Ok(ModuleOutput {
aliases, aliases,
@ -303,9 +309,8 @@ pub fn canonicalize_module_defs<'a>(
declarations, declarations,
references, references,
exposed_imports: can_exposed_imports, exposed_imports: can_exposed_imports,
problems: env.problems, problems: vec![], // TODO env.problems,
lookups, lookups,
exposed_vars_by_symbol,
ident_ids: env.ident_ids, ident_ids: env.ident_ids,
}) })
} }