mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge branch 'main' into roc-dev-report-status
This commit is contained in:
commit
ac13ce57c2
845 changed files with 59689 additions and 51567 deletions
|
@ -93,18 +93,18 @@ pub fn format(files: std::vec::Vec<PathBuf>, mode: FormatMode) -> Result<(), Str
|
|||
// the PartialEq implementation is returning `false` even when the Debug-formatted impl is exactly the same.
|
||||
// I don't have the patience to debug this right now, so let's leave it for another day...
|
||||
// TODO: fix PartialEq impl on ast types
|
||||
if format!("{:?}", ast_normalized) != format!("{:?}", reparsed_ast_normalized) {
|
||||
if format!("{ast_normalized:?}") != format!("{reparsed_ast_normalized:?}") {
|
||||
let mut fail_file = file.clone();
|
||||
fail_file.set_extension("roc-format-failed");
|
||||
std::fs::write(&fail_file, buf.as_str()).unwrap();
|
||||
|
||||
let mut before_file = file.clone();
|
||||
before_file.set_extension("roc-format-failed-ast-before");
|
||||
std::fs::write(&before_file, format!("{:#?}\n", ast_normalized)).unwrap();
|
||||
std::fs::write(&before_file, format!("{ast_normalized:#?}\n")).unwrap();
|
||||
|
||||
let mut after_file = file.clone();
|
||||
after_file.set_extension("roc-format-failed-ast-after");
|
||||
std::fs::write(&after_file, format!("{:#?}\n", reparsed_ast_normalized)).unwrap();
|
||||
std::fs::write(&after_file, format!("{reparsed_ast_normalized:#?}\n")).unwrap();
|
||||
|
||||
internal_error!(
|
||||
"Formatting bug; formatting didn't reparse as the same tree\n\n\
|
||||
|
|
|
@ -20,6 +20,7 @@ use roc_load::{ExpectMetadata, Threading};
|
|||
use roc_mono::ir::OptLevel;
|
||||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_packaging::tarball::Compression;
|
||||
use roc_target::Target;
|
||||
use std::env;
|
||||
use std::ffi::{CString, OsStr, OsString};
|
||||
use std::io;
|
||||
|
@ -28,11 +29,8 @@ use std::os::raw::{c_char, c_int};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::time::Instant;
|
||||
use strum::{EnumIter, IntoEnumIterator, IntoStaticStr};
|
||||
use target_lexicon::BinaryFormat;
|
||||
use target_lexicon::{
|
||||
Architecture, Environment, OperatingSystem, Triple, Vendor, X86_32Architecture,
|
||||
};
|
||||
use strum::IntoEnumIterator;
|
||||
use target_lexicon::{Architecture, Triple};
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use tempfile::TempDir;
|
||||
|
||||
|
@ -43,7 +41,6 @@ pub const CMD_BUILD: &str = "build";
|
|||
pub const CMD_RUN: &str = "run";
|
||||
pub const CMD_DEV: &str = "dev";
|
||||
pub const CMD_REPL: &str = "repl";
|
||||
pub const CMD_EDIT: &str = "edit";
|
||||
pub const CMD_DOCS: &str = "docs";
|
||||
pub const CMD_CHECK: &str = "check";
|
||||
pub const CMD_VERSION: &str = "version";
|
||||
|
@ -144,7 +141,8 @@ pub fn build_app() -> Command {
|
|||
|
||||
let build_target_values_parser =
|
||||
PossibleValuesParser::new(Target::iter().map(Into::<&'static str>::into));
|
||||
let app = Command::new("roc")
|
||||
|
||||
Command::new("roc")
|
||||
.version(concatcp!(VERSION, "\n"))
|
||||
.about("Run the given .roc file, if there are no compilation errors.\nYou can use one of the SUBCOMMANDS below to do something else!")
|
||||
.args_conflicts_with_subcommands(true)
|
||||
|
@ -334,23 +332,7 @@ pub fn build_app() -> Command {
|
|||
.arg(flag_linker)
|
||||
.arg(flag_prebuilt)
|
||||
.arg(roc_file_to_run)
|
||||
.arg(args_for_app.trailing_var_arg(true));
|
||||
|
||||
if cfg!(feature = "editor") {
|
||||
app.subcommand(
|
||||
Command::new(CMD_EDIT)
|
||||
.about("Launch the Roc editor (Work In Progress)")
|
||||
.arg(
|
||||
Arg::new(DIRECTORY_OR_FILES)
|
||||
.num_args(0..)
|
||||
.required(false)
|
||||
.value_parser(value_parser!(OsString))
|
||||
.help("(optional) The directory or files to open on launch"),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
app
|
||||
}
|
||||
.arg(args_for_app.trailing_var_arg(true))
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -387,7 +369,7 @@ pub fn test(_matches: &ArgMatches, _triple: Triple) -> io::Result<i32> {
|
|||
#[cfg(not(windows))]
|
||||
pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||
use roc_build::program::report_problems_monomorphized;
|
||||
use roc_load::{ExecutionMode, LoadConfig, LoadMonomorphizedError};
|
||||
use roc_load::{ExecutionMode, FunctionKind, LoadConfig, LoadMonomorphizedError};
|
||||
use roc_packaging::cache;
|
||||
use roc_target::TargetInfo;
|
||||
|
||||
|
@ -416,12 +398,10 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
|||
match matches.value_source(ROC_FILE) {
|
||||
Some(ValueSource::DefaultValue) => {
|
||||
eprintln!(
|
||||
"\nThe current directory ({}) does not contain a {} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n",
|
||||
current_dir_string,
|
||||
DEFAULT_ROC_FILENAME
|
||||
"\nThe current directory ({current_dir_string}) does not contain a {DEFAULT_ROC_FILENAME} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n"
|
||||
)
|
||||
}
|
||||
_ => eprintln!("\nThis file was not found: {}\n\nYou can run `roc help` for more information on how to provide a .roc file.\n", expected_file_path_string),
|
||||
_ => eprintln!("\nThis file was not found: {expected_file_path_string}\n\nYou can run `roc help` for more information on how to provide a .roc file.\n"),
|
||||
}
|
||||
|
||||
process::exit(1);
|
||||
|
@ -431,10 +411,13 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
|||
let target = &triple;
|
||||
let opt_level = opt_level;
|
||||
let target_info = TargetInfo::from(target);
|
||||
// TODO may need to determine this dynamically based on dev builds.
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
|
||||
// Step 1: compile the app and generate the .o file
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
function_kind,
|
||||
// TODO: expose this from CLI?
|
||||
render: roc_reporting::report::RenderTarget::ColorTerminal,
|
||||
palette: roc_reporting::report::DEFAULT_PALETTE,
|
||||
|
@ -565,16 +548,13 @@ pub fn build(
|
|||
match matches.value_source(ROC_FILE) {
|
||||
Some(ValueSource::DefaultValue) => {
|
||||
eprintln!(
|
||||
"\nThe current directory ({}) does not contain a {} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n",
|
||||
current_dir_string,
|
||||
DEFAULT_ROC_FILENAME
|
||||
"\nThe current directory ({current_dir_string}) does not contain a {DEFAULT_ROC_FILENAME} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n"
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let mut error_lines = Vec::new();
|
||||
error_lines.push(format!(
|
||||
"This file was not found: {}",
|
||||
expected_file_path_string
|
||||
"This file was not found: {expected_file_path_string}"
|
||||
));
|
||||
// Add some additional hints if run as `roc [FILENAME]`.
|
||||
if matches.subcommand().is_none() {
|
||||
|
@ -584,8 +564,7 @@ pub fn build(
|
|||
nearest_match(possible_typo, subcommands)
|
||||
{
|
||||
error_lines.push(format!(
|
||||
"Did you mean to use the {} subcommand?",
|
||||
nearest_command
|
||||
"Did you mean to use the {nearest_command} subcommand?"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1150,7 +1129,7 @@ fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<Executab
|
|||
);
|
||||
}
|
||||
|
||||
let path = PathBuf::from(format!("/proc/self/fd/{}", fd));
|
||||
let path = PathBuf::from(format!("/proc/self/fd/{fd}"));
|
||||
|
||||
std::fs::write(&path, binary_bytes)?;
|
||||
|
||||
|
@ -1183,7 +1162,7 @@ fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<Executab
|
|||
Ok(ExecutableFile::OnDisk(temp_dir, app_path_buf))
|
||||
}
|
||||
|
||||
#[cfg(all(target_family = "windows"))]
|
||||
#[cfg(target_family = "windows")]
|
||||
fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<ExecutableFile> {
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
|
@ -1281,83 +1260,3 @@ fn run_wasm<I: Iterator<Item = S>, S: AsRef<[u8]>>(wasm_path: &std::path::Path,
|
|||
fn run_wasm<I: Iterator<Item = S>, S: AsRef<[u8]>>(_wasm_path: &std::path::Path, _args: I) {
|
||||
println!("Running wasm files is not supported on this target.");
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, EnumIter, IntoStaticStr, PartialEq, Eq, Default)]
|
||||
pub enum Target {
|
||||
#[strum(serialize = "system")]
|
||||
#[default]
|
||||
System,
|
||||
#[strum(serialize = "linux32")]
|
||||
Linux32,
|
||||
#[strum(serialize = "linux64")]
|
||||
Linux64,
|
||||
#[strum(serialize = "windows64")]
|
||||
Windows64,
|
||||
#[strum(serialize = "wasm32")]
|
||||
Wasm32,
|
||||
}
|
||||
|
||||
impl Target {
|
||||
pub fn to_triple(self) -> Triple {
|
||||
use Target::*;
|
||||
|
||||
match self {
|
||||
System => Triple::host(),
|
||||
Linux32 => Triple {
|
||||
architecture: Architecture::X86_32(X86_32Architecture::I386),
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Musl,
|
||||
binary_format: BinaryFormat::Elf,
|
||||
},
|
||||
Linux64 => Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Linux,
|
||||
environment: Environment::Musl,
|
||||
binary_format: BinaryFormat::Elf,
|
||||
},
|
||||
Windows64 => Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Windows,
|
||||
environment: Environment::Gnu,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
},
|
||||
Wasm32 => Triple {
|
||||
architecture: Architecture::Wasm32,
|
||||
vendor: Vendor::Unknown,
|
||||
operating_system: OperatingSystem::Wasi,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Wasm,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Target> for Triple {
|
||||
fn from(target: &Target) -> Self {
|
||||
target.to_triple()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Target {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", Into::<&'static str>::into(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Target {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(string: &str) -> Result<Self, Self::Err> {
|
||||
match string {
|
||||
"system" => Ok(Target::System),
|
||||
"linux32" => Ok(Target::Linux32),
|
||||
"linux64" => Ok(Target::Linux64),
|
||||
"windows64" => Ok(Target::Windows64),
|
||||
"wasm32" => Ok(Target::Wasm32),
|
||||
_ => Err(format!("Roc does not know how to compile to {}", string)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,18 @@
|
|||
use roc_build::link::LinkType;
|
||||
use roc_build::program::{check_file, CodeGenBackend};
|
||||
use roc_cli::{
|
||||
build_app, format, test, BuildConfig, FormatMode, Target, CMD_BUILD, CMD_CHECK, CMD_DEV,
|
||||
CMD_DOCS, CMD_EDIT, CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_REPL, CMD_RUN, CMD_TEST,
|
||||
CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_NO_LINK, FLAG_TARGET,
|
||||
FLAG_TIME, GLUE_DIR, GLUE_SPEC, ROC_FILE,
|
||||
build_app, format, test, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK, CMD_DEV, CMD_DOCS,
|
||||
CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_REPL, CMD_RUN, CMD_TEST, CMD_VERSION,
|
||||
DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_NO_LINK, FLAG_TARGET, FLAG_TIME,
|
||||
GLUE_DIR, GLUE_SPEC, ROC_FILE,
|
||||
};
|
||||
use roc_docs::generate_docs_html;
|
||||
use roc_error_macros::user_error;
|
||||
use roc_gen_dev::AssemblyBackendMode;
|
||||
use roc_gen_llvm::llvm::build::LlvmBackendMode;
|
||||
use roc_load::{LoadingProblem, Threading};
|
||||
use roc_load::{FunctionKind, LoadingProblem, Threading};
|
||||
use roc_packaging::cache::{self, RocCacheDir};
|
||||
use roc_target::Target;
|
||||
use std::fs::{self, FileType};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -51,9 +52,7 @@ fn main() -> io::Result<()> {
|
|||
LinkType::Executable,
|
||||
)
|
||||
} else {
|
||||
launch_editor(None)?;
|
||||
|
||||
Ok(0)
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
Some((CMD_RUN, matches)) => {
|
||||
|
@ -122,10 +121,12 @@ fn main() -> io::Result<()> {
|
|||
.get_one::<String>(FLAG_TARGET)
|
||||
.and_then(|s| Target::from_str(s).ok())
|
||||
.unwrap_or_default();
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
roc_linker::generate_stub_lib(
|
||||
input_path,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
&target.to_triple(),
|
||||
function_kind,
|
||||
)
|
||||
}
|
||||
Some((CMD_BUILD, matches)) => {
|
||||
|
@ -200,32 +201,16 @@ fn main() -> io::Result<()> {
|
|||
}
|
||||
|
||||
Err(LoadingProblem::FormattedReport(report)) => {
|
||||
print!("{}", report);
|
||||
print!("{report}");
|
||||
|
||||
Ok(1)
|
||||
}
|
||||
Err(other) => {
|
||||
panic!("build_file failed with error:\n{:?}", other);
|
||||
panic!("build_file failed with error:\n{other:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some((CMD_REPL, _)) => Ok(roc_repl_cli::main()),
|
||||
Some((CMD_EDIT, matches)) => {
|
||||
match matches
|
||||
.get_many::<OsString>(DIRECTORY_OR_FILES)
|
||||
.map(|mut values| values.next())
|
||||
{
|
||||
Some(Some(os_string)) => {
|
||||
launch_editor(Some(Path::new(os_string)))?;
|
||||
}
|
||||
_ => {
|
||||
launch_editor(None)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Exit 0 if the editor exited normally
|
||||
Ok(0)
|
||||
}
|
||||
Some((CMD_DOCS, matches)) => {
|
||||
let root_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||
|
||||
|
@ -272,7 +257,7 @@ fn main() -> io::Result<()> {
|
|||
let format_exit_code = match format(roc_files, format_mode) {
|
||||
Ok(_) => 0,
|
||||
Err(message) => {
|
||||
eprintln!("{}", message);
|
||||
eprintln!("{message}");
|
||||
1
|
||||
}
|
||||
};
|
||||
|
@ -330,13 +315,3 @@ fn roc_files_recursive<P: AsRef<Path>>(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "editor")]
|
||||
fn launch_editor(project_dir_path: Option<&Path>) -> io::Result<()> {
|
||||
roc_editor::launch(project_dir_path)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "editor"))]
|
||||
fn launch_editor(_project_dir_path: Option<&Path>) -> io::Result<()> {
|
||||
panic!("Cannot launch the editor because this build of roc did not include `feature = \"editor\"`!");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue