mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
wip
This commit is contained in:
parent
9e02537ebb
commit
0a9989e75f
@ -21,6 +21,7 @@ use inkwell::targets::{
|
||||
use std::path::{Path, PathBuf};
|
||||
use target_lexicon::{Architecture, OperatingSystem, Triple, Vendor};
|
||||
|
||||
// TODO how should imported modules factor into this? What if those use builtins too?
|
||||
// TODO this should probably use more helper functions
|
||||
// TODO make this polymorphic in the llvm functions so it can be reused for another backend.
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
@ -110,7 +111,9 @@ pub fn build(
|
||||
}
|
||||
}
|
||||
}
|
||||
InvalidCycle(_, _) => {}
|
||||
InvalidCycle(_, _) | Builtin(_) => {
|
||||
// These can never contain main.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +184,7 @@ pub fn build(
|
||||
use roc_can::pattern::Pattern::*;
|
||||
|
||||
match decl {
|
||||
Declare(def) => match def.loc_pattern.value {
|
||||
Declare(def) | Builtin(def) => match def.loc_pattern.value {
|
||||
Identifier(symbol) => {
|
||||
match def.loc_expr.value {
|
||||
Closure(annotation, _, _, loc_args, boxed_body) => {
|
||||
|
@ -91,6 +91,7 @@ pub enum Declaration {
|
||||
Vec<Located<Ident>>,
|
||||
Vec<(Region /* pattern */, Region /* expr */)>,
|
||||
),
|
||||
Builtin(Def),
|
||||
}
|
||||
|
||||
impl Declaration {
|
||||
@ -100,6 +101,7 @@ impl Declaration {
|
||||
Declare(_) => 1,
|
||||
DeclareRec(defs) => defs.len(),
|
||||
InvalidCycle(_, _) => 0,
|
||||
Builtin(_) => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1249,6 +1251,10 @@ fn decl_to_let(
|
||||
Declaration::InvalidCycle(symbols, regions) => {
|
||||
Expr::RuntimeError(RuntimeError::CircularDef(symbols, regions))
|
||||
}
|
||||
Declaration::Builtin(_) => {
|
||||
// Builtins should only be added to top-level decls, not to let-exprs!
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||
(Ok(declarations), output) => {
|
||||
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() {
|
||||
@ -193,6 +194,14 @@ pub fn canonicalize_module_defs<'a>(
|
||||
InvalidCycle(identifiers, _) => {
|
||||
panic!("TODO gracefully handle potentially attempting to expose invalid cyclic defs {:?}" , identifiers);
|
||||
}
|
||||
Builtin(def) => {
|
||||
// Builtins cannot be exposed in module declarations.
|
||||
// This should never happen!
|
||||
debug_assert!(def
|
||||
.pattern_vars
|
||||
.iter()
|
||||
.all(|(symbol, _)| !exposed_symbols.contains(symbol)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -880,7 +880,7 @@ pub fn constrain_decls(
|
||||
for decl in decls.iter().rev() {
|
||||
// NOTE: rigids are empty because they are not shared between top-level definitions
|
||||
match decl {
|
||||
Declaration::Declare(def) => {
|
||||
Declaration::Declare(def) | Declaration::Builtin(def) => {
|
||||
constraint = exists_with_aliases(
|
||||
aliases.clone(),
|
||||
Vec::new(),
|
||||
|
@ -70,7 +70,7 @@ pub fn constrain_decls(
|
||||
for decl in decls.iter().rev() {
|
||||
// NOTE: rigids are empty because they are not shared between top-level definitions
|
||||
match decl {
|
||||
Declaration::Declare(def) => {
|
||||
Declaration::Declare(def) | Declaration::Builtin(def) => {
|
||||
sharing::annotate_usage(&def.loc_expr.value, &mut var_usage);
|
||||
}
|
||||
Declaration::DeclareRec(defs) => {
|
||||
@ -87,7 +87,7 @@ pub fn constrain_decls(
|
||||
for decl in decls.iter().rev() {
|
||||
// NOTE: rigids are empty because they are not shared between top-level definitions
|
||||
match decl {
|
||||
Declaration::Declare(def) => {
|
||||
Declaration::Declare(def) | Declaration::Builtin(def) => {
|
||||
constraint = exists_with_aliases(
|
||||
aliases.clone(),
|
||||
Vec::new(),
|
||||
|
@ -19,7 +19,15 @@ mod gen_module {
|
||||
use inkwell::passes::PassManager;
|
||||
use inkwell::types::BasicType;
|
||||
use inkwell::OptimizationLevel;
|
||||
use roc_can::{canonicalize_module_defs, operator};
|
||||
use roc_can::{
|
||||
builtins::builtin_defs,
|
||||
def::Declaration,
|
||||
expected::Expected,
|
||||
expr::{canonicalize_expr, Env},
|
||||
module::canonicalize_module_defs,
|
||||
operator,
|
||||
scope::Scope,
|
||||
};
|
||||
use roc_collections::all::{ImMap, MutMap, MutSet};
|
||||
use roc_gen::llvm::build::{build_proc, build_proc_header};
|
||||
use roc_gen::llvm::convert::basic_type_from_layout;
|
||||
@ -30,7 +38,8 @@ mod gen_module {
|
||||
use roc_parse::blankspace::space0_before;
|
||||
use roc_parse::parser::{self, loc, Parser};
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_types::subs::{Content, Subs, VarStore, Variable};
|
||||
use roc_types::subs::{Subs, VarStore};
|
||||
use roc_types::types::Type;
|
||||
|
||||
static TEST_MODULE_NAME: &str = "Test";
|
||||
|
||||
@ -72,7 +81,10 @@ mod gen_module {
|
||||
region: Region::zero(),
|
||||
value: main_pattern,
|
||||
};
|
||||
let loc_def = ast::Def::Body(&loc_main_pattern, &loc_expr);
|
||||
let loc_def = Located {
|
||||
region: Region::zero(),
|
||||
value: ast::Def::Body(&loc_main_pattern, &loc_expr),
|
||||
};
|
||||
let loc_defs = bumpalo::vec![in arena; loc_def];
|
||||
let module_ids = ModuleIds::default();
|
||||
let home: ModuleId = module_ids.get_or_insert(&TEST_MODULE_NAME.into());
|
||||
@ -85,11 +97,11 @@ mod gen_module {
|
||||
exposed_ident_ids.add(main_fn_name.into());
|
||||
|
||||
// Canonicalize the module.
|
||||
let module_output = canonicalize_module_defs(
|
||||
let mut module_output = canonicalize_module_defs(
|
||||
arena,
|
||||
loc_defs,
|
||||
home,
|
||||
module_ids,
|
||||
&module_ids,
|
||||
exposed_ident_ids,
|
||||
dep_idents,
|
||||
exposed_imports,
|
||||
@ -98,9 +110,26 @@ mod gen_module {
|
||||
)
|
||||
.expect("Error canonicalizing test module");
|
||||
|
||||
// TODO add the builtins as separate (unexposed) Declarations to the module
|
||||
// Add the builtins as Declarations to the module.
|
||||
let module_output = {
|
||||
let builtins = builtin_defs(&var_store);
|
||||
let decls = &mut module_output.declarations;
|
||||
let references = module_output.references;
|
||||
|
||||
// TODO type-check the module
|
||||
decls.reserve(builtins.len());
|
||||
|
||||
for (symbol, builtin_def) in builtins.into_iter() {
|
||||
// Only add decls for builtins that were actually referenced.
|
||||
if references.contains(&symbol) {
|
||||
decls.push(Declaration::Builtin(builtin_def));
|
||||
}
|
||||
}
|
||||
|
||||
// Release the borrows on declarations and references
|
||||
module_output
|
||||
};
|
||||
|
||||
// TODO type-check the module, making sure to use builtin types from std.rs/unique.rs
|
||||
// TODO monomorphize the module
|
||||
// TODO code gen the module
|
||||
|
||||
@ -119,24 +148,6 @@ mod gen_module {
|
||||
&loc_expr.value,
|
||||
);
|
||||
|
||||
let mut with_builtins = loc_expr.value;
|
||||
|
||||
// Add builtin defs (e.g. List.get) directly to the canonical Expr,
|
||||
// since we aren't using modules here.
|
||||
let builtin_defs = roc_can::builtins::builtin_defs(&var_store);
|
||||
|
||||
for def in builtin_defs {
|
||||
with_builtins = Expr::LetNonRec(
|
||||
Box::new(def),
|
||||
Box::new(Located {
|
||||
region: Region::zero(),
|
||||
value: with_builtins,
|
||||
}),
|
||||
var_store.fresh(),
|
||||
SendMap::default(),
|
||||
);
|
||||
}
|
||||
|
||||
let loc_expr = Located {
|
||||
region: loc_expr.region,
|
||||
value: with_builtins,
|
||||
|
@ -67,6 +67,8 @@ impl<'a> Procs<'a> {
|
||||
|
||||
self.add_pending_specialization(name, layout.clone(), pending);
|
||||
|
||||
debug_assert!(!self.partial_procs.contains_key(&name), "Procs was told to insert a value for key {:?}, but there was already an entry for that key! Procs should never attempt to insert duplicates.", name);
|
||||
|
||||
// a named closure
|
||||
self.partial_procs.insert(
|
||||
name,
|
||||
|
Loading…
Reference in New Issue
Block a user