mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge branch 'trunk' into str_trim
This commit is contained in:
commit
02117ba512
25 changed files with 233 additions and 158 deletions
2
.github/workflows/nightly.yml
vendored
2
.github/workflows/nightly.yml
vendored
|
@ -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
|
||||
|
|
2
AUTHORS
2
AUTHORS
|
@ -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
60
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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."),
|
||||
])
|
||||
]);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -28,6 +28,7 @@ let
|
|||
xorg.libXrandr
|
||||
xorg.libXi
|
||||
xorg.libxcb
|
||||
alsa-lib
|
||||
];
|
||||
|
||||
llvmPkgs = pkgs.llvmPackages_12;
|
||||
|
|
53
vendor/morphic_lib/src/analyze.rs
vendored
53
vendor/morphic_lib/src/analyze.rs
vendored
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
31
vendor/morphic_lib/src/api.rs
vendored
31
vendor/morphic_lib/src/api.rs
vendored
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue