mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
First pass at loading modules from cli
This commit is contained in:
parent
62186fdda4
commit
9ca754b8fd
4 changed files with 86 additions and 54 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -871,6 +871,7 @@ dependencies = [
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_constrain",
|
"roc_constrain",
|
||||||
"roc_gen",
|
"roc_gen",
|
||||||
|
"roc_load",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_mono",
|
"roc_mono",
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
|
@ -882,6 +883,7 @@ dependencies = [
|
||||||
"roc_unify",
|
"roc_unify",
|
||||||
"roc_uniq",
|
"roc_uniq",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -31,12 +31,14 @@ roc_uniq = { path = "../compiler/uniq" }
|
||||||
roc_unify = { path = "../compiler/unify" }
|
roc_unify = { path = "../compiler/unify" }
|
||||||
roc_solve = { path = "../compiler/solve" }
|
roc_solve = { path = "../compiler/solve" }
|
||||||
roc_mono = { path = "../compiler/mono" }
|
roc_mono = { path = "../compiler/mono" }
|
||||||
|
roc_load = { path = "../compiler/load", version = "0.1.0" }
|
||||||
roc_gen = { path = "../compiler/gen", version = "0.1.0" }
|
roc_gen = { path = "../compiler/gen", version = "0.1.0" }
|
||||||
roc_reporting = { path = "../compiler/reporting", version = "0.1.0" }
|
roc_reporting = { path = "../compiler/reporting", version = "0.1.0" }
|
||||||
im = "14" # im and im-rc should always have the same version!
|
im = "14" # im and im-rc should always have the same version!
|
||||||
im-rc = "14" # im and im-rc should always have the same version!
|
im-rc = "14" # im and im-rc should always have the same version!
|
||||||
bumpalo = { version = "3.2", features = ["collections"] }
|
bumpalo = { version = "3.2", features = ["collections"] }
|
||||||
inlinable_string = "0.1.0"
|
inlinable_string = "0.1.0"
|
||||||
|
tokio = { version = "0.2", features = ["blocking", "fs", "sync", "rt-threaded"] }
|
||||||
# NOTE: rtfeldman/inkwell is a fork of TheDan64/inkwell which does not change anything.
|
# NOTE: rtfeldman/inkwell is a fork of TheDan64/inkwell which does not change anything.
|
||||||
#
|
#
|
||||||
# The reason for this fork is that the way Inkwell is designed, you have to use
|
# The reason for this fork is that the way Inkwell is designed, you have to use
|
||||||
|
|
|
@ -9,10 +9,12 @@ use inkwell::passes::PassManager;
|
||||||
use inkwell::types::BasicType;
|
use inkwell::types::BasicType;
|
||||||
use inkwell::OptimizationLevel;
|
use inkwell::OptimizationLevel;
|
||||||
use roc_collections::all::ImMap;
|
use roc_collections::all::ImMap;
|
||||||
|
use roc_collections::all::MutMap;
|
||||||
use roc_gen::llvm::build::{
|
use roc_gen::llvm::build::{
|
||||||
build_proc, build_proc_header, get_call_conventions, module_from_builtins,
|
build_proc, build_proc_header, get_call_conventions, module_from_builtins,
|
||||||
};
|
};
|
||||||
use roc_gen::llvm::convert::basic_type_from_layout;
|
use roc_gen::llvm::convert::basic_type_from_layout;
|
||||||
|
use roc_load::file::{load, LoadedModule, LoadingProblem};
|
||||||
use roc_mono::expr::{Expr, Procs};
|
use roc_mono::expr::{Expr, Procs};
|
||||||
use roc_mono::layout::Layout;
|
use roc_mono::layout::Layout;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
@ -20,47 +22,71 @@ use std::time::SystemTime;
|
||||||
use inkwell::targets::{
|
use inkwell::targets::{
|
||||||
CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetTriple,
|
CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetTriple,
|
||||||
};
|
};
|
||||||
use std::fs::File;
|
use std::env::current_dir;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use target_lexicon::{Architecture, OperatingSystem, Triple, Vendor};
|
use target_lexicon::{Architecture, OperatingSystem, Triple, Vendor};
|
||||||
|
use tokio::runtime::Builder;
|
||||||
|
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
let now = SystemTime::now();
|
|
||||||
let argv = std::env::args().collect::<Vec<String>>();
|
let argv = std::env::args().collect::<Vec<String>>();
|
||||||
|
|
||||||
match argv.get(1) {
|
match argv.get(1) {
|
||||||
Some(filename) => {
|
Some(filename) => {
|
||||||
let mut path = Path::new(filename).canonicalize().unwrap();
|
let mut path = Path::new(filename).canonicalize().unwrap();
|
||||||
|
let src_dir = current_dir()?;
|
||||||
|
|
||||||
if !path.is_absolute() {
|
if !path.is_absolute() {
|
||||||
path = std::env::current_dir()?.join(path).canonicalize().unwrap();
|
path = src_dir.join(path).canonicalize().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1: build the .o file for the app
|
// Create the runtime
|
||||||
let mut file = File::open(path.clone())?;
|
let mut rt = Builder::new()
|
||||||
let mut contents = String::new();
|
.thread_name("roc")
|
||||||
|
.threaded_scheduler()
|
||||||
|
.build()
|
||||||
|
.expect("Error spawning initial compiler thread."); // TODO make this error nicer.
|
||||||
|
|
||||||
file.read_to_string(&mut contents)?;
|
// Spawn the root task
|
||||||
|
let loaded = rt.block_on(load_file(src_dir, path));
|
||||||
|
|
||||||
let dest_filename = path.with_extension("o");
|
loaded.expect("TODO gracefully handle LoadingProblem");
|
||||||
|
|
||||||
gen(
|
Ok(())
|
||||||
Path::new(filename).to_path_buf(),
|
}
|
||||||
contents.as_str(),
|
None => {
|
||||||
Triple::host(),
|
println!("Usage: roc FILENAME.roc");
|
||||||
&dest_filename,
|
|
||||||
);
|
|
||||||
|
|
||||||
let end_time = now.elapsed().unwrap();
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn load_file(src_dir: PathBuf, filename: PathBuf) -> Result<(), LoadingProblem> {
|
||||||
|
let compilation_start = SystemTime::now();
|
||||||
|
|
||||||
|
// Step 1: compile the app and generate the .o file
|
||||||
|
let subs_by_module = MutMap::default();
|
||||||
|
let loaded = load(
|
||||||
|
&roc_builtins::std::standard_stdlib(),
|
||||||
|
src_dir,
|
||||||
|
filename.clone(),
|
||||||
|
subs_by_module,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let dest_filename = filename.with_extension("o");
|
||||||
|
|
||||||
|
gen(loaded, filename, Triple::host(), &dest_filename);
|
||||||
|
|
||||||
|
let compilation_end = compilation_start.elapsed().unwrap();
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Finished compilation and code gen in {} ms\n",
|
"Finished compilation and code gen in {} ms\n",
|
||||||
end_time.as_millis()
|
compilation_end.as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
let cwd = dest_filename.parent().unwrap();
|
let cwd = dest_filename.parent().unwrap();
|
||||||
|
@ -91,25 +117,20 @@ fn main() -> io::Result<()> {
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
println!("Usage: roc FILENAME.roc");
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gen(filename: PathBuf, src: &str, target: Triple, dest_filename: &Path) {
|
fn gen(loaded: LoadedModule, filename: PathBuf, target: Triple, dest_filename: &Path) {
|
||||||
use roc_reporting::report::{can_problem, RocDocAllocator, DEFAULT_PALETTE};
|
use roc_reporting::report::{can_problem, RocDocAllocator, DEFAULT_PALETTE};
|
||||||
use roc_reporting::type_error::type_problem;
|
use roc_reporting::type_error::type_problem;
|
||||||
|
|
||||||
// Build the expr
|
// Build the expr
|
||||||
let arena = Bump::new();
|
let arena = Bump::new();
|
||||||
|
|
||||||
|
let src = loaded.src;
|
||||||
let (loc_expr, _output, can_problems, subs, var, constraint, home, interns) =
|
let (loc_expr, _output, can_problems, subs, var, constraint, home, interns) =
|
||||||
uniq_expr_with(&arena, src, &ImMap::default());
|
uniq_expr_with(&arena, &src, &ImMap::default());
|
||||||
|
|
||||||
let mut type_problems = Vec::new();
|
let mut type_problems = Vec::new();
|
||||||
let (content, mut subs) = infer_expr(subs, &mut type_problems, &constraint, var);
|
let (content, mut subs) = infer_expr(subs, &mut type_problems, &constraint, var);
|
||||||
|
|
|
@ -44,6 +44,7 @@ pub struct Module {
|
||||||
pub aliases: MutMap<Symbol, Alias>,
|
pub aliases: MutMap<Symbol, Alias>,
|
||||||
pub rigid_variables: MutMap<Variable, Lowercase>,
|
pub rigid_variables: MutMap<Variable, Lowercase>,
|
||||||
pub imported_modules: MutSet<ModuleId>,
|
pub imported_modules: MutSet<ModuleId>,
|
||||||
|
pub src: Box<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -54,6 +55,7 @@ pub struct LoadedModule {
|
||||||
pub can_problems: Vec<roc_problem::can::Problem>,
|
pub can_problems: Vec<roc_problem::can::Problem>,
|
||||||
pub type_problems: Vec<solve::TypeError>,
|
pub type_problems: Vec<solve::TypeError>,
|
||||||
pub declarations: Vec<Declaration>,
|
pub declarations: Vec<Declaration>,
|
||||||
|
pub src: Box<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -89,6 +91,7 @@ enum Msg {
|
||||||
var_store: VarStore,
|
var_store: VarStore,
|
||||||
},
|
},
|
||||||
Solved {
|
Solved {
|
||||||
|
src: Box<str>,
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
solved_types: MutMap<Symbol, SolvedType>,
|
solved_types: MutMap<Symbol, SolvedType>,
|
||||||
aliases: MutMap<Symbol, Alias>,
|
aliases: MutMap<Symbol, Alias>,
|
||||||
|
@ -393,7 +396,7 @@ pub async fn load<'a>(
|
||||||
subs,
|
subs,
|
||||||
problems,
|
problems,
|
||||||
aliases,
|
aliases,
|
||||||
..
|
src,
|
||||||
} => {
|
} => {
|
||||||
type_problems.extend(problems);
|
type_problems.extend(problems);
|
||||||
|
|
||||||
|
@ -428,6 +431,7 @@ pub async fn load<'a>(
|
||||||
can_problems,
|
can_problems,
|
||||||
type_problems,
|
type_problems,
|
||||||
declarations,
|
declarations,
|
||||||
|
src,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// This was a dependency. Write it down and keep processing messages.
|
// This was a dependency. Write it down and keep processing messages.
|
||||||
|
@ -885,6 +889,7 @@ fn solve_module(
|
||||||
aliases: module.aliases,
|
aliases: module.aliases,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let src = module.src;
|
||||||
let mut subs = Subs::new(var_store.into());
|
let mut subs = Subs::new(var_store.into());
|
||||||
|
|
||||||
for (var, name) in module.rigid_variables {
|
for (var, name) in module.rigid_variables {
|
||||||
|
@ -934,6 +939,7 @@ fn solve_module(
|
||||||
|
|
||||||
// Send the subs to the main thread for processing,
|
// Send the subs to the main thread for processing,
|
||||||
tx.send(Msg::Solved {
|
tx.send(Msg::Solved {
|
||||||
|
src,
|
||||||
module_id: home,
|
module_id: home,
|
||||||
subs: Arc::new(solved_subs),
|
subs: Arc::new(solved_subs),
|
||||||
solved_types,
|
solved_types,
|
||||||
|
@ -1069,6 +1075,7 @@ fn parse_and_constrain(
|
||||||
aliases,
|
aliases,
|
||||||
rigid_variables,
|
rigid_variables,
|
||||||
imported_modules: header.imported_modules,
|
imported_modules: header.imported_modules,
|
||||||
|
src: header.src,
|
||||||
};
|
};
|
||||||
|
|
||||||
(module, ident_ids, constraint, problems)
|
(module, ident_ids, constraint, problems)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue