Merge branch 'trunk' into str_trim

This commit is contained in:
Dan Gieschen Knutson 2021-10-27 18:01:29 -05:00 committed by GitHub
commit 02117ba512
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 233 additions and 158 deletions

View file

@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: install earthly
run: /bin/sh -c 'wget https://github.com/earthly/earthly/releases/latest/download/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly && /usr/local/bin/earthly bootstrap --with-autocomplete'
run: "sudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/latest/download/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly && /usr/local/bin/earthly bootstrap --with-autocomplete'"
- name: Earthly print version
run: earthly --version
- name: install dependencies, build, run tests, build release

View file

@ -39,3 +39,5 @@ Chelsea Troy <chelsea.dommert@gmail.com>
Shritesh Bhattarai <shr@ite.sh>
Kevin Sjöberg <mail@kevinsjoberg.com>
Viktor Fröberg <vikfroberg@gmail.com>
Locria Cyber <locriacyber@noreply.users.github.com>
Matthias Beyer <mail@beyermatthias.de>

60
Cargo.lock generated
View file

@ -457,14 +457,16 @@ dependencies = [
[[package]]
name = "clap"
version = "3.0.0-beta.1"
source = "git+https://github.com/rtfeldman/clap?branch=master#e1d83a78804a271b053d4d21f69b67f7eb01ad01"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "860643c53f980f0d38a5e25dfab6c3c93b2cb3aa1fe192643d17a293c6c41936"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"indexmap",
"lazy_static",
"strsim 0.9.3",
"os_str_bytes",
"strsim 0.10.0",
"termcolor",
"textwrap",
"unicode-width",
@ -473,11 +475,12 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "3.0.0-beta.1"
source = "git+https://github.com/rtfeldman/clap?branch=master#e1d83a78804a271b053d4d21f69b67f7eb01ad01"
version = "3.0.0-beta.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3"
dependencies = [
"heck",
"proc-macro-error 0.4.12",
"proc-macro-error",
"proc-macro2 1.0.29",
"quote 1.0.9",
"syn 1.0.76",
@ -2711,6 +2714,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "os_str_bytes"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
[[package]]
name = "output_vt100"
version = "0.1.2"
@ -3016,45 +3025,19 @@ dependencies = [
"toml",
]
[[package]]
name = "proc-macro-error"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
dependencies = [
"proc-macro-error-attr 0.4.12",
"proc-macro2 1.0.29",
"quote 1.0.9",
"syn 1.0.76",
"version_check",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr 1.0.4",
"proc-macro-error-attr",
"proc-macro2 1.0.29",
"quote 1.0.9",
"syn 1.0.76",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
dependencies = [
"proc-macro2 1.0.29",
"quote 1.0.9",
"syn 1.0.76",
"syn-mid",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
@ -4641,17 +4624,6 @@ dependencies = [
"unicode-xid 0.2.2",
]
[[package]]
name = "syn-mid"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baa8e7560a164edb1621a55d18a0c59abf49d360f47aa7b821061dd7eea7fac9"
dependencies = [
"proc-macro2 1.0.29",
"quote 1.0.9",
"syn 1.0.76",
]
[[package]]
name = "synstructure"
version = "0.12.5"
@ -5258,7 +5230,7 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee7b351bcc1e782997c72dc0b5b328f3ddcad4813b8ce3cac3f25ae5a4ab56b"
dependencies = [
"proc-macro-error 1.0.4",
"proc-macro-error",
"proc-macro2 1.0.29",
"quote 1.0.9",
"syn 1.0.76",

View file

@ -35,7 +35,7 @@ install-zig-llvm-valgrind-clippy-rustfmt:
RUN rustup component add rustfmt
# criterion
RUN cargo install cargo-criterion
# wasm
# editor
RUN apt -y install libxkbcommon-dev
# sccache
RUN apt -y install libssl-dev
@ -106,7 +106,7 @@ test-all:
build-nightly-release:
FROM +test-rust
COPY --dir .git ./
# version.txt is used by the CLI: roc version
# version.txt is used by the CLI: roc --version
RUN printf "nightly pre-release, built from commit " > version.txt
RUN git log --pretty=format:'%h' -n 1 >> version.txt
RUN cargo build --release

View file

@ -58,8 +58,7 @@ roc_fmt = { path = "../compiler/fmt" }
roc_reporting = { path = "../compiler/reporting" }
roc_editor = { path = "../editor", optional = true }
roc_linker = { path = "../linker" }
# TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it
clap = { git = "https://github.com/rtfeldman/clap", branch = "master" }
clap = "= 3.0.0-beta.1"
const_format = "0.2"
rustyline = { git = "https://github.com/rtfeldman/rustyline", tag = "prompt-fix" }
rustyline-derive = { git = "https://github.com/rtfeldman/rustyline", tag = "prompt-fix" }

View file

@ -45,25 +45,25 @@ pub fn build_app<'a>() -> App<'a> {
.about("Build a binary from the given .roc file, but don't run it")
.arg(
Arg::with_name(ROC_FILE)
.help("The .roc file to build")
.about("The .roc file to build")
.required(true),
)
.arg(
Arg::with_name(FLAG_OPTIMIZE)
.long(FLAG_OPTIMIZE)
.help("Optimize your compiled Roc program to run faster. (Optimization takes time to complete.)")
.about("Optimize your compiled Roc program to run faster. (Optimization takes time to complete.)")
.required(false),
)
.arg(
Arg::with_name(FLAG_DEV)
.long(FLAG_DEV)
.help("Make compilation as fast as possible. (Runtime performance may suffer)")
.about("Make compilation as fast as possible. (Runtime performance may suffer)")
.required(false),
)
.arg(
Arg::with_name(FLAG_BACKEND)
.long(FLAG_BACKEND)
.help("Choose a different backend")
.about("Choose a different backend")
// .requires(BACKEND)
.default_value(Backend::default().as_str())
.possible_values(Backend::OPTIONS)
@ -72,31 +72,31 @@ pub fn build_app<'a>() -> App<'a> {
.arg(
Arg::with_name(FLAG_LIB)
.long(FLAG_LIB)
.help("Build a C library instead of an executable.")
.about("Build a C library instead of an executable.")
.required(false),
)
.arg(
Arg::with_name(FLAG_DEBUG)
.long(FLAG_DEBUG)
.help("Store LLVM debug information in the generated program")
.about("Store LLVM debug information in the generated program")
.required(false),
)
.arg(
Arg::with_name(FLAG_TIME)
.long(FLAG_TIME)
.help("Prints detailed compilation time information.")
.about("Prints detailed compilation time information.")
.required(false),
)
.arg(
Arg::with_name(FLAG_LINK)
.long(FLAG_LINK)
.help("Uses the roc linker instead of the system linker.")
.about("Uses the roc linker instead of the system linker.")
.required(false),
)
.arg(
Arg::with_name(FLAG_PRECOMPILED)
.long(FLAG_PRECOMPILED)
.help("Assumes the host has been precompiled and skips recompiling the host.")
.about("Assumes the host has been precompiled and skips recompiling the host.")
.required(false),
)
)
@ -108,12 +108,12 @@ pub fn build_app<'a>() -> App<'a> {
.arg(
Arg::with_name(FLAG_TIME)
.long(FLAG_TIME)
.help("Prints detailed compilation time information.")
.about("Prints detailed compilation time information.")
.required(false),
)
.arg(
Arg::with_name(ROC_FILE)
.help("The .roc file of an app to run")
.about("The .roc file of an app to run")
.required(true),
)
)
@ -124,7 +124,7 @@ pub fn build_app<'a>() -> App<'a> {
.index(1)
.multiple(true)
.required(false)
.help("The directory or files to build documentation for")
.about("The directory or files to build documentation for")
)
)
@ -132,45 +132,45 @@ pub fn build_app<'a>() -> App<'a> {
.arg(
Arg::with_name(FLAG_OPTIMIZE)
.long(FLAG_OPTIMIZE)
.help("Optimize the compiled program to run faster. (Optimization takes time to complete.)")
.about("Optimize the compiled program to run faster. (Optimization takes time to complete.)")
.requires(ROC_FILE)
.required(false),
)
.arg(
Arg::with_name(FLAG_DEV)
.long(FLAG_DEV)
.help("Make compilation as fast as possible. (Runtime performance may suffer)")
.about("Make compilation as fast as possible. (Runtime performance may suffer)")
.required(false),
)
.arg(
Arg::with_name(FLAG_DEBUG)
.long(FLAG_DEBUG)
.help("Store LLVM debug information in the generated program")
.about("Store LLVM debug information in the generated program")
.requires(ROC_FILE)
.required(false),
)
.arg(
Arg::with_name(FLAG_TIME)
.long(FLAG_TIME)
.help("Prints detailed compilation time information.")
.about("Prints detailed compilation time information.")
.required(false),
)
.arg(
Arg::with_name(FLAG_LINK)
.long(FLAG_LINK)
.help("Uses the roc linker instead of the system linker.")
.about("Uses the roc linker instead of the system linker.")
.required(false),
)
.arg(
Arg::with_name(FLAG_PRECOMPILED)
.long(FLAG_PRECOMPILED)
.help("Assumes the host has been precompiled and skips recompiling the host.")
.about("Assumes the host has been precompiled and skips recompiling the host.")
.required(false),
)
.arg(
Arg::with_name(FLAG_BACKEND)
.long(FLAG_BACKEND)
.help("Choose a different backend")
.about("Choose a different backend")
// .requires(BACKEND)
.default_value(Backend::default().as_str())
.possible_values(Backend::OPTIONS)
@ -178,12 +178,12 @@ pub fn build_app<'a>() -> App<'a> {
)
.arg(
Arg::with_name(ROC_FILE)
.help("The .roc file of an app to build and run")
.about("The .roc file of an app to build and run")
.required(false),
)
.arg(
Arg::with_name(ARGS_FOR_APP)
.help("Arguments to pass into the app being run")
.about("Arguments to pass into the app being run")
.requires(ROC_FILE)
.multiple(true),
);
@ -195,7 +195,7 @@ pub fn build_app<'a>() -> App<'a> {
.index(1)
.multiple(true)
.required(false)
.help("(optional) The directory or files to open on launch."),
.about("(optional) The directory or files to open on launch."),
),
)
} else {

View file

@ -205,6 +205,9 @@ mod cli_run {
example.use_valgrind,
);
// This is mostly because the false interpreter is still very slow -
// 25s for the cli tests is just not acceptable during development!
#[cfg(not(debug_assertions))]
check_output_with_stdin(
&file_name,
example.stdin,

View file

@ -30,10 +30,7 @@ use roc_ast::{
env::Env,
},
};
use roc_module::{
module_err::ModuleResult,
symbol::{get_module_ident_ids, Interns},
};
use roc_module::{module_err::ModuleResult, symbol::Interns};
// make Markup Nodes: generate String representation, assign Highlighting Style
pub fn expr2_to_markup<'a>(
@ -46,6 +43,9 @@ pub fn expr2_to_markup<'a>(
) -> ASTResult<MarkNodeId> {
let ast_node_id = ASTNodeId::AExprId(expr2_node_id);
// for debugging
//println!("EXPR2 {:?}", expr2);
let mark_node_id = match expr2 {
Expr2::SmallInt { text, .. }
| Expr2::I128 { text, .. }
@ -112,8 +112,7 @@ pub fn expr2_to_markup<'a>(
mark_node_pool.add(call_node)
}
Expr2::Var(symbol) => {
let text = get_module_ident_ids(&interns.all_ident_ids, &env.home)?
.get_name_str_res(symbol.ident_id())?;
let text = symbol.fully_qualified(interns, env.home);
new_markup_node(
text.to_string(),

View file

@ -665,7 +665,7 @@ fn link_linux(
.args(&[
"--gc-sections",
"--eh-frame-hdr",
"-arch",
"--arch",
arch_str(target),
"-pie",
libcrt_path.join("crti.o").to_str().unwrap(),
@ -674,7 +674,7 @@ fn link_linux(
.args(&base_args)
.args(&["-dynamic-linker", ld_linux])
.args(input_paths)
// ld.lld requires this argument, and does not accept -arch
// ld.lld requires this argument, and does not accept --arch
// .args(&["-L/usr/lib/x86_64-linux-gnu"])
.args(&[
// Libraries - see https://github.com/rtfeldman/roc/pull/554#discussion_r496365925

View file

@ -86,8 +86,8 @@ pub fn build(b: *Builder) void {
fn removeInstallSteps(b: *Builder) void {
for (b.top_level_steps.items) |top_level_step, i| {
if (mem.eql(u8, top_level_step.step.name, "install") or mem.eql(u8, top_level_step.step.name, "uninstall")) {
const name = top_level_step.step.name;
if (mem.eql(u8, name, "install") or mem.eql(u8, name, "uninstall")) {
_ = b.top_level_steps.swapRemove(i);
}
}

View file

@ -160,7 +160,8 @@ fn exportUtilsFn(comptime func: anytype, comptime func_name: []const u8) void {
// Custom panic function, as builtin Zig version errors during LLVM verification
pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace) noreturn {
if (std.builtin.is_test) {
const builtin = @import("builtin");
if (builtin.is_test) {
std.debug.print("{s}: {?}", .{ message, stacktrace });
} else {
_ = message;

View file

@ -93,7 +93,7 @@ pub const RocStr = extern struct {
if (length < roc_str_size) {
return RocStr.empty();
} else {
var new_bytes: []T = utils.alloc(length, RocStr.alignment) catch unreachable;
var new_bytes = utils.alloc(length, RocStr.alignment) catch unreachable;
var new_bytes_ptr: [*]u8 = @ptrCast([*]u8, &new_bytes);

View file

@ -19,8 +19,9 @@ extern fn roc_dealloc(c_ptr: *c_void, alignment: u32) callconv(.C) void;
extern fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void;
comptime {
const builtin = @import("builtin");
// During tetsts, use the testing allocators to satisfy these functions.
if (std.builtin.is_test) {
if (builtin.is_test) {
@export(testing_roc_alloc, .{ .name = "roc_alloc", .linkage = .Strong });
@export(testing_roc_realloc, .{ .name = "roc_realloc", .linkage = .Strong });
@export(testing_roc_dealloc, .{ .name = "roc_dealloc", .linkage = .Strong });
@ -257,7 +258,7 @@ pub const Ordering = enum(u8) {
LT = 2,
};
pub const UpdateMode = extern enum(u8) {
pub const UpdateMode = enum(u8) {
Immutable = 0,
InPlace = 1,
};

View file

@ -3852,7 +3852,7 @@ fn build_procedures_help<'a, 'ctx, 'env>(
let it = procedures.iter().map(|x| x.1);
let solutions = match roc_mono::alias_analysis::spec_program(entry_point, it) {
let solutions = match roc_mono::alias_analysis::spec_program(opt_level, entry_point, it) {
Err(e) => panic!("Error in alias analysis: {}", e),
Ok(solutions) => solutions,
};

View file

@ -4531,7 +4531,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: PlatformPath) -> Strin
let doc = alloc.stack(vec![
alloc.reflow(r"The input file is a interface file, but only app modules can be ran."),
alloc.concat(vec![
alloc.reflow(r"I will still parse and typecheck the input file and its dependencies,"),
alloc.reflow(r"I will still parse and typecheck the input file and its dependencies, "),
alloc.reflow(r"but won't output any executable."),
])
]);
@ -4547,7 +4547,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: PlatformPath) -> Strin
let doc = alloc.stack(vec![
alloc.reflow(r"The input file is a package config file, but only app modules can be ran."),
alloc.concat(vec![
alloc.reflow(r"I will still parse and typecheck the input file and its dependencies,"),
alloc.reflow(r"I will still parse and typecheck the input file and its dependencies, "),
alloc.reflow(r"but won't output any executable."),
])
]);

View file

@ -4,7 +4,7 @@ use std::fmt;
/// This could be uppercase or lowercase, qualified or unqualified.
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Ident(pub IdentStr); // Is IdentStr allowed to be pub?
pub struct Ident(pub IdentStr);
impl Ident {
pub fn as_inline_str(&self) -> &IdentStr {

View file

@ -10,7 +10,8 @@ use roc_module::symbol::Symbol;
use std::convert::TryFrom;
use crate::ir::{
Call, CallType, Expr, HostExposedLayouts, ListLiteralElement, Literal, ModifyRc, Proc, Stmt,
Call, CallType, Expr, HostExposedLayouts, ListLiteralElement, Literal, ModifyRc, OptLevel,
Proc, Stmt,
};
use crate::layout::{Builtin, Layout, ListLayout, RawFunctionLayout, UnionLayout};
@ -109,6 +110,7 @@ fn bytes_as_ascii(bytes: &[u8]) -> String {
}
pub fn spec_program<'a, I>(
opt_level: OptLevel,
entry_point: crate::ir::EntryPoint<'a>,
procs: I,
) -> Result<morphic_lib::Solutions>
@ -239,7 +241,10 @@ where
eprintln!("{}", program.to_source_string());
}
morphic_lib::solve(program)
match opt_level {
OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program),
OptLevel::Optimize => morphic_lib::solve(program),
}
}
/// if you want an "escape hatch" which allows you construct "best-case scenario" values

View file

@ -1767,13 +1767,9 @@ fn specialize_all_help<'a>(
externals_others_need: ExternalSpecializations<'a>,
layout_cache: &mut LayoutCache<'a>,
) {
let mut symbol_solved_type = Vec::new_in(env.arena);
for (symbol, solved_types) in externals_others_need.specs.iter() {
// for some unclear reason, the MutSet does not deduplicate according to the hash
// instance. So we do it manually here
let mut as_vec: std::vec::Vec<_> = solved_types.iter().collect();
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
@ -1783,15 +1779,17 @@ fn specialize_all_help<'a>(
hasher.finish()
};
as_vec.sort_by_key(|x| hash_the_thing(x));
as_vec.dedup_by_key(|x| hash_the_thing(x));
let mut as_vec = Vec::from_iter_in(
solved_types.iter().map(|x| (hash_the_thing(x), x)),
env.arena,
);
for s in as_vec {
symbol_solved_type.push((*symbol, s.clone()));
}
}
as_vec.sort_by_key(|(k, _)| *k);
as_vec.dedup_by_key(|(k, _)| *k);
for (_, solved_type) in as_vec {
let name = *symbol;
for (name, solved_type) in symbol_solved_type.into_iter() {
let partial_proc = match procs.partial_procs.get(&name) {
Some(v) => v.clone(),
None => {
@ -1830,6 +1828,7 @@ fn specialize_all_help<'a>(
}
}
}
}
}
fn generate_runtime_error_function<'a>(
@ -2421,7 +2420,7 @@ fn specialize<'a>(
procs,
proc_name,
layout_cache,
solved_type,
&solved_type,
host_exposed_aliases,
partial_proc,
)
@ -2451,7 +2450,7 @@ fn specialize_solved_type<'a>(
procs: &mut Procs<'a>,
proc_name: Symbol,
layout_cache: &mut LayoutCache<'a>,
solved_type: SolvedType,
solved_type: &SolvedType,
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
partial_proc: PartialProc<'a>,
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
@ -2460,7 +2459,7 @@ fn specialize_solved_type<'a>(
procs,
proc_name,
layout_cache,
|env| introduce_solved_type_to_subs(env, &solved_type),
|env| introduce_solved_type_to_subs(env, solved_type),
host_exposed_aliases,
partial_proc,
)

View file

@ -151,16 +151,32 @@ main = "Hello, world!"
#[test]
fn top_level_def_value() {
expect_html_def(
r#"myFunction = "Hello, World!""#,
"<span class=\"syntax-value\">myFunction</span><span class=\"syntax-operator\"> = </span><span class=\"syntax-string\">\"Hello, World!\"</span>\n\n",
r#"myVal = "Hello, World!""#,
"<span class=\"syntax-value\">myVal</span><span class=\"syntax-operator\"> = </span><span class=\"syntax-string\">\"Hello, World!\"</span>\n\n",
);
}
#[test]
fn tld_newline_in_str() {
expect_html_def(
r#"myVal = "Hello, Newline!\n""#,
"<span class=\"syntax-value\">myVal</span><span class=\"syntax-operator\"> = </span><span class=\"syntax-string\">\"Hello, Newline!\n\"</span>\n\n",
);
}
#[test]
fn tld_list() {
expect_html_def(
r#"myFunction = [ 1, 2, 3 ]"#,
"<span class=\"syntax-value\">myFunction</span><span class=\"syntax-operator\"> = </span><span class=\"syntax-bracket\">[ </span><span class=\"syntax-number\">1</span><span class=\"syntax-comma\">, </span><span class=\"syntax-number\">2</span><span class=\"syntax-comma\">, </span><span class=\"syntax-number\">3</span><span class=\"syntax-bracket\"> ]</span>\n\n",
r#"myVal = [ 1, 2, 3 ]"#,
"<span class=\"syntax-value\">myVal</span><span class=\"syntax-operator\"> = </span><span class=\"syntax-bracket\">[ </span><span class=\"syntax-number\">1</span><span class=\"syntax-comma\">, </span><span class=\"syntax-number\">2</span><span class=\"syntax-comma\">, </span><span class=\"syntax-number\">3</span><span class=\"syntax-bracket\"> ]</span>\n\n",
);
}
#[test]
fn call_builtin() {
expect_html_def(
r#"myVal = Str.fromInt 1234"#,
"<span class=\"syntax-value\">myVal</span><span class=\"syntax-operator\"> = </span><span class=\"syntax-value\">Str.fromInt</span><span class=\"syntax-blank\"> </span><span class=\"syntax-number\">1234</span>\n\n",
);
}

View file

@ -130,7 +130,7 @@ fn markup_to_wgpu_helper<'a>(
} => {
let highlight_color = map_get(&code_style.ed_theme.syntax_high_map, syn_high_style)?;
let full_content = markup_node.get_full_content();
let full_content = markup_node.get_full_content().replace("\n", "\\n"); // any \n left here should be escaped so that it can be shown as \n
let glyph_text = glyph_brush::OwnedText::new(full_content)
.with_color(colors::to_slice(*highlight_color))

View file

@ -22,8 +22,7 @@ roc_mono = { path = "../compiler/mono" }
roc_build = { path = "../compiler/build", default-features = false }
roc_collections = { path = "../compiler/collections" }
bumpalo = { version = "3.6", features = ["collections"] }
# TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it
clap = { git = "https://github.com/rtfeldman/clap", branch = "master" }
clap = "= 3.0.0-beta.1"
iced-x86 = "1.14"
memmap2 = "0.3"
object = { version = "0.26", features = ["read", "write"] }

View file

@ -59,36 +59,36 @@ pub fn build_app<'a>() -> App<'a> {
.about("Preprocesses a dynamically linked platform to prepare for linking.")
.arg(
Arg::with_name(EXEC)
.help("The dynamically linked platform executable")
.about("The dynamically linked platform executable")
.required(true),
)
.arg(
Arg::with_name(METADATA)
.help("Where to save the metadata from preprocessing")
.about("Where to save the metadata from preprocessing")
.required(true),
)
.arg(
Arg::with_name(OUT)
.help("The modified version of the dynamically linked platform executable")
.about("The modified version of the dynamically linked platform executable")
.required(true),
)
.arg(
Arg::with_name(SHARED_LIB)
.help("The name of the shared library used in building the platform")
.about("The name of the shared library used in building the platform")
.default_value("libapp.so"),
)
.arg(
Arg::with_name(FLAG_VERBOSE)
.long(FLAG_VERBOSE)
.short('v')
.help("Enable verbose printing")
.about("Enable verbose printing")
.required(false),
)
.arg(
Arg::with_name(FLAG_TIME)
.long(FLAG_TIME)
.short('t')
.help("Print timing information")
.about("Print timing information")
.required(false),
),
)
@ -97,17 +97,17 @@ pub fn build_app<'a>() -> App<'a> {
.about("Links a preprocessed platform with a Roc application.")
.arg(
Arg::with_name(APP)
.help("The Roc application object file waiting to be linked")
.about("The Roc application object file waiting to be linked")
.required(true),
)
.arg(
Arg::with_name(METADATA)
.help("The metadata created by preprocessing the platform")
.about("The metadata created by preprocessing the platform")
.required(true),
)
.arg(
Arg::with_name(OUT)
.help(
.about(
"The modified version of the dynamically linked platform. \
It will be consumed to make linking faster.",
)
@ -117,14 +117,14 @@ pub fn build_app<'a>() -> App<'a> {
Arg::with_name(FLAG_VERBOSE)
.long(FLAG_VERBOSE)
.short('v')
.help("Enable verbose printing")
.about("Enable verbose printing")
.required(false),
)
.arg(
Arg::with_name(FLAG_TIME)
.long(FLAG_TIME)
.short('t')
.help("Print timing information")
.about("Print timing information")
.required(false),
),
)

View file

@ -28,6 +28,7 @@ let
xorg.libXrandr
xorg.libXi
xorg.libxcb
alsa-lib
];
llvmPkgs = pkgs.llvmPackages_12;

View file

@ -1768,3 +1768,56 @@ pub(crate) fn analyze(tc: TypeCache, program: &ir::Program) -> ProgramSolutions
entry_points: entry_point_solutions,
}
}
// Utilities for producing "trivial" solutions, in which each function has exactly one
// specialization and all update modes are `Immutable`:
fn hash_func_id_trivial(func_id: FuncId) -> api::FuncSpec {
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
hasher.update(&func_id.0.to_le_bytes());
api::FuncSpec(hasher.finalize().into())
}
fn func_solution_trivial(func_def: &ir::FuncDef) -> FuncSolution {
let update_modes = IdVec::filled_with(func_def.graph.update_mode_vars(), || {
api::UpdateMode::Immutable
});
let mut callee_specs = IdVec::filled_with(func_def.graph.callee_spec_vars(), || None);
for val_id in func_def.graph.values().count().iter() {
if let ir::ValueKind::Op(ir::OpKind::Call {
callee_spec_var,
callee,
}) = &func_def.graph.values().node(val_id).op.kind
{
replace_none(
&mut callee_specs[callee_spec_var],
hash_func_id_trivial(*callee),
)
.unwrap();
}
}
FuncSolution {
update_modes,
callee_specs: callee_specs.into_mapped(|_, spec| spec.unwrap()),
}
}
pub(crate) fn analyze_trivial(program: &ir::Program) -> ProgramSolutions {
let funcs = FuncSolutions {
solutions: program.funcs.map(|func_id, func_def| {
std::iter::once((
hash_func_id_trivial(func_id),
Some(func_solution_trivial(func_def)),
))
.collect()
}),
};
let entry_points = program
.entry_points
.map(|_, &func_id| hash_func_id_trivial(func_id));
ProgramSolutions {
funcs,
entry_points,
}
}

View file

@ -3,15 +3,16 @@ use smallvec::SmallVec;
use std::collections::{btree_map::Entry, BTreeMap};
use std::rc::Rc;
use crate::analyze;
use crate::preprocess;
use crate::render_api_ir;
use crate::type_cache::TypeCache;
use crate::util::blocks::Blocks;
use crate::util::id_bi_map::IdBiMap;
use crate::util::id_type::Count;
use crate::util::id_vec::IdVec;
use crate::util::op_graph::OpGraph;
use crate::util::replace_none::replace_none;
use crate::{analyze, ir};
#[derive(Clone, thiserror::Error, Debug)]
#[non_exhaustive]
@ -1533,6 +1534,8 @@ impl Solutions {
}
}
// TODO: Remove this; it's only used in obsolete logic for populating const definitions with trivial
// solutions
fn populate_specs(
callee_spec_var_ids: Count<CalleeSpecVarId>,
vals: &OpGraph<ValueId, Op>,
@ -1555,11 +1558,14 @@ fn populate_specs(
results.into_mapped(|_, spec| spec.unwrap())
}
pub fn solve(api_program: Program) -> Result<Solutions> {
fn solve_with(
api_program: Program,
analysis: impl for<'a> FnOnce(TypeCache, &'a ir::Program) -> analyze::ProgramSolutions,
) -> Result<Solutions> {
let (nc, tc, program) =
preprocess::preprocess(&api_program).map_err(ErrorKind::PreprocessError)?;
let mut solutions = analyze::analyze(tc, &program);
let mut solutions = analysis(tc, &program);
Ok(Solutions {
mods: api_program
@ -1600,6 +1606,8 @@ pub fn solve(api_program: Program) -> Result<Solutions> {
.const_defs
.into_iter()
.map(|(const_name, const_def)| {
// TODO: This is left over from the original stub implementation, and
// generates incorrect callee specialization hashes!
let callee_specs = populate_specs(
const_def.builder.expr_builder.callee_spec_vars.count(),
&const_def.builder.expr_builder.vals,
@ -1629,12 +1637,29 @@ pub fn solve(api_program: Program) -> Result<Solutions> {
})
}
/// Solve for optimized update modes and function specializations
pub fn solve(api_program: Program) -> Result<Solutions> {
solve_with(api_program, analyze::analyze)
}
/// Return a "trivial" solution for the program, setting every update mode to `Immutable`.
///
/// This function does not perform any expensive analysis, but it does typecheck the input program,
/// so it can be useful for verifying the correctness of a generated program.
pub fn solve_trivial(api_program: Program) -> Result<Solutions> {
solve_with(api_program, |_, program| analyze::analyze_trivial(program))
}
// TODO: Remove this; it's only used in obsolete logic for populating const definitions with trivial
// solutions
fn hash_bstr(hasher: &mut Sha256, bstr: &[u8]) {
let header = (bstr.len() as u64).to_le_bytes();
hasher.update(&header);
hasher.update(bstr);
}
// TODO: Remove this; it's only used in obsolete logic for populating const definitions with trivial
// solutions
fn hash_func_name(mod_: ModName, func: FuncName) -> FuncSpec {
let mut hasher = Sha256::new();
hash_bstr(&mut hasher, mod_.0);