mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
basic version of editor/module
This commit is contained in:
parent
264b6884f0
commit
a6ee72dbac
2 changed files with 72 additions and 63 deletions
|
@ -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, .. }) => {
|
Def::Function(function_def) => match function_def {
|
||||||
std::iter::once((name, expr_var))
|
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,
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue