mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Merge remote-tracking branch 'origin/trunk' into wasm-cli-option
This commit is contained in:
commit
13df4ee656
6 changed files with 38 additions and 61 deletions
37
Earthfile
37
Earthfile
|
@ -48,49 +48,18 @@ install-zig-llvm-valgrind-clippy-rustfmt:
|
||||||
ENV RUSTC_WRAPPER=/usr/local/cargo/bin/sccache
|
ENV RUSTC_WRAPPER=/usr/local/cargo/bin/sccache
|
||||||
ENV SCCACHE_DIR=/earthbuild/sccache_dir
|
ENV SCCACHE_DIR=/earthbuild/sccache_dir
|
||||||
ENV CARGO_INCREMENTAL=0 # no need to recompile package when using new function
|
ENV CARGO_INCREMENTAL=0 # no need to recompile package when using new function
|
||||||
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
|
||||||
cargo install cargo-chef
|
|
||||||
|
|
||||||
deps-image:
|
|
||||||
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
|
||||||
SAVE IMAGE roc-deps:latest
|
|
||||||
|
|
||||||
copy-dirs:
|
copy-dirs:
|
||||||
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
||||||
# If you edit this, make sure to update copy-dirs-and-cache below.
|
|
||||||
COPY --dir cli compiler docs editor roc_std vendor examples Cargo.toml Cargo.lock ./
|
COPY --dir cli compiler docs editor roc_std vendor examples Cargo.toml Cargo.lock ./
|
||||||
|
|
||||||
copy-dirs-and-cache:
|
|
||||||
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
|
||||||
COPY +save-cache/target ./target
|
|
||||||
COPY +save-cache/cargo_home $CARGO_HOME
|
|
||||||
# This needs to be kept in sync with copy-dirs above.
|
|
||||||
# The reason this is at the end is to maximize caching.
|
|
||||||
# Lines above this should be cached even if the code changes.
|
|
||||||
COPY --dir cli compiler docs editor roc_std vendor examples Cargo.toml Cargo.lock ./
|
|
||||||
|
|
||||||
prepare-cache:
|
|
||||||
FROM +copy-dirs
|
|
||||||
RUN cargo chef prepare
|
|
||||||
SAVE ARTIFACT recipe.json
|
|
||||||
|
|
||||||
save-cache:
|
|
||||||
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
|
||||||
COPY +prepare-cache/recipe.json ./
|
|
||||||
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
|
||||||
cargo chef cook && sccache --show-stats # for clippy
|
|
||||||
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
|
||||||
cargo chef cook --release --tests && sccache --show-stats
|
|
||||||
SAVE ARTIFACT target
|
|
||||||
SAVE ARTIFACT $CARGO_HOME cargo_home
|
|
||||||
|
|
||||||
test-zig:
|
test-zig:
|
||||||
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
FROM +install-zig-llvm-valgrind-clippy-rustfmt
|
||||||
COPY --dir compiler/builtins/bitcode ./
|
COPY --dir compiler/builtins/bitcode ./
|
||||||
RUN cd bitcode && ./run-tests.sh
|
RUN cd bitcode && ./run-tests.sh
|
||||||
|
|
||||||
check-clippy:
|
check-clippy:
|
||||||
FROM +copy-dirs-and-cache
|
FROM +copy-dirs
|
||||||
RUN cargo clippy -V
|
RUN cargo clippy -V
|
||||||
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
||||||
cargo clippy -- -D warnings
|
cargo clippy -- -D warnings
|
||||||
|
@ -106,7 +75,7 @@ check-typos:
|
||||||
RUN typos
|
RUN typos
|
||||||
|
|
||||||
test-rust:
|
test-rust:
|
||||||
FROM +copy-dirs-and-cache
|
FROM +copy-dirs
|
||||||
ENV RUST_BACKTRACE=1
|
ENV RUST_BACKTRACE=1
|
||||||
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
RUN --mount=type=cache,target=$SCCACHE_DIR \
|
||||||
cargo test --release && sccache --show-stats
|
cargo test --release && sccache --show-stats
|
||||||
|
@ -132,7 +101,7 @@ test-all:
|
||||||
|
|
||||||
# compile everything needed for benchmarks and output a self-contained folder
|
# compile everything needed for benchmarks and output a self-contained folder
|
||||||
prep-bench-folder:
|
prep-bench-folder:
|
||||||
FROM +copy-dirs-and-cache
|
FROM +copy-dirs
|
||||||
ARG BENCH_SUFFIX=branch
|
ARG BENCH_SUFFIX=branch
|
||||||
RUN cargo criterion -V
|
RUN cargo criterion -V
|
||||||
RUN --mount=type=cache,target=$SCCACHE_DIR cd cli && cargo criterion --no-run
|
RUN --mount=type=cache,target=$SCCACHE_DIR cd cli && cargo criterion --no-run
|
||||||
|
|
|
@ -9,12 +9,12 @@ const RocList = @import("list.zig").RocList;
|
||||||
|
|
||||||
const INITIAL_SEED = 0xc70f6907;
|
const INITIAL_SEED = 0xc70f6907;
|
||||||
|
|
||||||
const InPlace = packed enum(u8) {
|
const InPlace = enum(u8) {
|
||||||
InPlace,
|
InPlace,
|
||||||
Clone,
|
Clone,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Slot = packed enum(u8) {
|
const Slot = enum(u8) {
|
||||||
Empty,
|
Empty,
|
||||||
Filled,
|
Filled,
|
||||||
PreviouslyFilled,
|
PreviouslyFilled,
|
||||||
|
@ -63,7 +63,7 @@ fn capacityOfLevel(input: usize) usize {
|
||||||
// alignment of the key and value. The tag furthermore indicates
|
// alignment of the key and value. The tag furthermore indicates
|
||||||
// which has the biggest aligmnent. If both are the same, we put
|
// which has the biggest aligmnent. If both are the same, we put
|
||||||
// the key first
|
// the key first
|
||||||
const Alignment = packed enum(u8) {
|
const Alignment = enum(u8) {
|
||||||
Align16KeyFirst,
|
Align16KeyFirst,
|
||||||
Align16ValueFirst,
|
Align16ValueFirst,
|
||||||
Align8KeyFirst,
|
Align8KeyFirst,
|
||||||
|
@ -359,7 +359,7 @@ pub const RocDict = extern struct {
|
||||||
// hash the key, and modulo by the maximum size
|
// hash the key, and modulo by the maximum size
|
||||||
// (so we get an in-bounds index)
|
// (so we get an in-bounds index)
|
||||||
const hash = hash_fn(seed, key);
|
const hash = hash_fn(seed, key);
|
||||||
const index = capacityOfLevel(current_level - 1) + (hash % current_level_size);
|
const index = capacityOfLevel(current_level - 1) + @intCast(usize, (hash % current_level_size));
|
||||||
|
|
||||||
switch (self.getSlot(index, key_width, value_width)) {
|
switch (self.getSlot(index, key_width, value_width)) {
|
||||||
Slot.Empty, Slot.PreviouslyFilled => {
|
Slot.Empty, Slot.PreviouslyFilled => {
|
||||||
|
@ -426,7 +426,7 @@ pub fn dictInsert(input: RocDict, alignment: Alignment, key: Opaque, key_width:
|
||||||
}
|
}
|
||||||
|
|
||||||
const hash = hash_fn(seed, key);
|
const hash = hash_fn(seed, key);
|
||||||
const index: usize = capacityOfLevel(current_level - 1) + (hash % current_level_size);
|
const index = capacityOfLevel(current_level - 1) + @intCast(usize, (hash % current_level_size));
|
||||||
assert(index < result.capacity());
|
assert(index < result.capacity());
|
||||||
|
|
||||||
switch (result.getSlot(index, key_width, value_width)) {
|
switch (result.getSlot(index, key_width, value_width)) {
|
||||||
|
|
|
@ -180,8 +180,8 @@ pub const Wyhash = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn final(self: *Wyhash) u64 {
|
pub fn final(self: *Wyhash) u64 {
|
||||||
const seed = self.state.seed;
|
// const seed = self.state.seed;
|
||||||
const rem_len = @intCast(u5, self.buf_len);
|
// const rem_len = @intCast(u5, self.buf_len);
|
||||||
const rem_key = self.buf[0..self.buf_len];
|
const rem_key = self.buf[0..self.buf_len];
|
||||||
|
|
||||||
return self.state.final(rem_key);
|
return self.state.final(rem_key);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const utils = @import("utils.zig");
|
const utils = @import("utils.zig");
|
||||||
const roc_mem = @import("mem.zig");
|
|
||||||
const RocList = @import("list.zig").RocList;
|
const RocList = @import("list.zig").RocList;
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
@ -10,7 +9,7 @@ const expectEqual = testing.expectEqual;
|
||||||
const expectError = testing.expectError;
|
const expectError = testing.expectError;
|
||||||
const expect = testing.expect;
|
const expect = testing.expect;
|
||||||
|
|
||||||
const InPlace = packed enum(u8) {
|
const InPlace = enum(u8) {
|
||||||
InPlace,
|
InPlace,
|
||||||
Clone,
|
Clone,
|
||||||
};
|
};
|
||||||
|
@ -52,7 +51,7 @@ pub const RocStr = extern struct {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initBig(in_place: InPlace, number_of_chars: usize) RocStr {
|
pub fn initBig(_: InPlace, number_of_chars: usize) RocStr {
|
||||||
const first_element = utils.allocateWithRefcount(number_of_chars, @sizeOf(usize));
|
const first_element = utils.allocateWithRefcount(number_of_chars, @sizeOf(usize));
|
||||||
|
|
||||||
return RocStr{
|
return RocStr{
|
||||||
|
@ -222,7 +221,7 @@ pub const RocStr = extern struct {
|
||||||
// null-terminated strings. Otherwise, we need to allocate and copy a new
|
// null-terminated strings. Otherwise, we need to allocate and copy a new
|
||||||
// null-terminated string, which has a much higher performance cost!
|
// null-terminated string, which has a much higher performance cost!
|
||||||
fn isNullTerminated(self: RocStr) bool {
|
fn isNullTerminated(self: RocStr) bool {
|
||||||
const len = self.len();
|
const length = self.len();
|
||||||
const longest_small_str = @sizeOf(RocStr) - 1;
|
const longest_small_str = @sizeOf(RocStr) - 1;
|
||||||
|
|
||||||
// NOTE: We want to compare length here, *NOT* check for is_small_str!
|
// NOTE: We want to compare length here, *NOT* check for is_small_str!
|
||||||
|
@ -231,7 +230,7 @@ pub const RocStr = extern struct {
|
||||||
//
|
//
|
||||||
// (The other branch dereferences the bytes pointer, which is not safe
|
// (The other branch dereferences the bytes pointer, which is not safe
|
||||||
// to do for the empty string.)
|
// to do for the empty string.)
|
||||||
if (len <= longest_small_str) {
|
if (length <= longest_small_str) {
|
||||||
// If we're a small string, then usually the next byte after the
|
// If we're a small string, then usually the next byte after the
|
||||||
// end of the string will be zero. (Small strings set all their
|
// end of the string will be zero. (Small strings set all their
|
||||||
// unused bytes to 0, so that comparison for equality can be fast.)
|
// unused bytes to 0, so that comparison for equality can be fast.)
|
||||||
|
@ -242,7 +241,7 @@ pub const RocStr = extern struct {
|
||||||
// Also, if we are exactly a maximum-length small string,
|
// Also, if we are exactly a maximum-length small string,
|
||||||
// then the next byte is off the end of the struct;
|
// then the next byte is off the end of the struct;
|
||||||
// in that case, we are also not null-terminated!
|
// in that case, we are also not null-terminated!
|
||||||
return len != 0 and len != longest_small_str;
|
return length != 0 and length != longest_small_str;
|
||||||
} else {
|
} else {
|
||||||
// This is a big string, and it's not empty, so we can safely
|
// This is a big string, and it's not empty, so we can safely
|
||||||
// dereference the pointer.
|
// dereference the pointer.
|
||||||
|
@ -253,8 +252,8 @@ pub const RocStr = extern struct {
|
||||||
//
|
//
|
||||||
// If we have excess capacity, then we can safely read the next
|
// If we have excess capacity, then we can safely read the next
|
||||||
// byte after the end of the string. Maybe it happens to be zero!
|
// byte after the end of the string. Maybe it happens to be zero!
|
||||||
if (capacity_or_refcount > @intCast(isize, len)) {
|
if (capacity_or_refcount > @intCast(isize, length)) {
|
||||||
return self.str_bytes[len] == 0;
|
return self.str_bytes[length] == 0;
|
||||||
} else {
|
} else {
|
||||||
// This string was refcounted or immortal; we can't safely read
|
// This string was refcounted or immortal; we can't safely read
|
||||||
// the next byte, so assume the string is not null-terminated.
|
// the next byte, so assume the string is not null-terminated.
|
||||||
|
@ -267,10 +266,10 @@ pub const RocStr = extern struct {
|
||||||
// Returns 0 for refcounted stirngs and immortal strings.
|
// Returns 0 for refcounted stirngs and immortal strings.
|
||||||
// Returns the stored capacity value for all other strings.
|
// Returns the stored capacity value for all other strings.
|
||||||
pub fn capacity(self: RocStr) usize {
|
pub fn capacity(self: RocStr) usize {
|
||||||
const len = self.len();
|
const length = self.len();
|
||||||
const longest_small_str = @sizeOf(RocStr) - 1;
|
const longest_small_str = @sizeOf(RocStr) - 1;
|
||||||
|
|
||||||
if (len <= longest_small_str) {
|
if (length <= longest_small_str) {
|
||||||
// Note that although empty strings technically have the full
|
// Note that although empty strings technically have the full
|
||||||
// capacity of a small string available, they aren't marked as small
|
// capacity of a small string available, they aren't marked as small
|
||||||
// strings, so if you want to make use of that capacity, you need
|
// strings, so if you want to make use of that capacity, you need
|
||||||
|
@ -316,7 +315,14 @@ pub const RocStr = extern struct {
|
||||||
pub fn asU8ptr(self: RocStr) [*]u8 {
|
pub fn asU8ptr(self: RocStr) [*]u8 {
|
||||||
// Since this conditional would be prone to branch misprediction,
|
// Since this conditional would be prone to branch misprediction,
|
||||||
// make sure it will compile to a cmov.
|
// make sure it will compile to a cmov.
|
||||||
return if (self.isSmallStr() or self.isEmpty()) (&@bitCast([@sizeOf(RocStr)]u8, self)) else (@ptrCast([*]u8, self.str_bytes));
|
// return if (self.isSmallStr() or self.isEmpty()) (&@bitCast([@sizeOf(RocStr)]u8, self)) else (@ptrCast([*]u8, self.str_bytes));
|
||||||
|
if (self.isSmallStr() or self.isEmpty()) {
|
||||||
|
const as_int = @ptrToInt(&self);
|
||||||
|
const as_ptr = @intToPtr([*]u8, as_int);
|
||||||
|
return as_ptr;
|
||||||
|
} else {
|
||||||
|
return @ptrCast([*]u8, self.str_bytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a pointer to some bytes, write the first (len) bytes of this
|
// Given a pointer to some bytes, write the first (len) bytes of this
|
||||||
|
@ -408,7 +414,7 @@ pub fn strFromIntC(int: i64) callconv(.C) RocStr {
|
||||||
|
|
||||||
fn strFromIntHelp(comptime T: type, int: T) RocStr {
|
fn strFromIntHelp(comptime T: type, int: T) RocStr {
|
||||||
// determine maximum size for this T
|
// determine maximum size for this T
|
||||||
comptime const size = comptime blk: {
|
const size = comptime blk: {
|
||||||
// the string representation of the minimum i128 value uses at most 40 characters
|
// the string representation of the minimum i128 value uses at most 40 characters
|
||||||
var buf: [40]u8 = undefined;
|
var buf: [40]u8 = undefined;
|
||||||
var result = std.fmt.bufPrint(&buf, "{}", .{std.math.minInt(T)}) catch unreachable;
|
var result = std.fmt.bufPrint(&buf, "{}", .{std.math.minInt(T)}) catch unreachable;
|
||||||
|
@ -787,8 +793,6 @@ pub fn countGraphemeClusters(string: RocStr) callconv(.C) usize {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rocStrFromLiteral(bytes_arr: *const []u8) RocStr {}
|
|
||||||
|
|
||||||
test "countGraphemeClusters: empty string" {
|
test "countGraphemeClusters: empty string" {
|
||||||
const count = countGraphemeClusters(RocStr.empty());
|
const count = countGraphemeClusters(RocStr.empty());
|
||||||
try expectEqual(count, 0);
|
try expectEqual(count, 0);
|
||||||
|
@ -869,7 +873,6 @@ pub fn startsWith(string: RocStr, prefix: RocStr) callconv(.C) bool {
|
||||||
|
|
||||||
// Str.startsWithCodePt
|
// Str.startsWithCodePt
|
||||||
pub fn startsWithCodePt(string: RocStr, prefix: u32) callconv(.C) bool {
|
pub fn startsWithCodePt(string: RocStr, prefix: u32) callconv(.C) bool {
|
||||||
const bytes_len = string.len();
|
|
||||||
const bytes_ptr = string.asU8ptr();
|
const bytes_ptr = string.asU8ptr();
|
||||||
|
|
||||||
var buffer: [4]u8 = undefined;
|
var buffer: [4]u8 = undefined;
|
||||||
|
@ -1268,7 +1271,7 @@ pub fn numberOfNextCodepointBytes(ptr: [*]u8, len: usize, index: usize) Utf8Deco
|
||||||
|
|
||||||
// Return types for validateUtf8Bytes
|
// Return types for validateUtf8Bytes
|
||||||
// Values must be in alphabetical order. That is, lowest values are the first alphabetically.
|
// Values must be in alphabetical order. That is, lowest values are the first alphabetically.
|
||||||
pub const Utf8ByteProblem = packed enum(u8) {
|
pub const Utf8ByteProblem = enum(u8) {
|
||||||
CodepointTooLarge = 0,
|
CodepointTooLarge = 0,
|
||||||
EncodesSurrogateHalf = 1,
|
EncodesSurrogateHalf = 1,
|
||||||
ExpectedContinuation = 2,
|
ExpectedContinuation = 2,
|
||||||
|
|
|
@ -45,7 +45,10 @@ fn testing_roc_dealloc(c_ptr: *c_void, _: u32) callconv(.C) void {
|
||||||
std.testing.allocator.destroy(ptr);
|
std.testing.allocator.destroy(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_panic(c_ptr: *c_void, _: u32) callconv(.C) void {
|
fn testing_roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
|
||||||
|
_ = c_ptr;
|
||||||
|
_ = tag_id;
|
||||||
|
|
||||||
@panic("Roc paniced");
|
@panic("Roc paniced");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +72,9 @@ pub fn panic(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
||||||
// indirection because otherwise zig creats an alias to the panic function which our LLVM code
|
// indirection because otherwise zig creats an alias to the panic function which our LLVM code
|
||||||
// does not know how to deal with
|
// does not know how to deal with
|
||||||
pub fn test_panic(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
pub fn test_panic(c_ptr: *c_void, alignment: u32) callconv(.C) void {
|
||||||
const cstr = @ptrCast([*:0]u8, c_ptr);
|
_ = c_ptr;
|
||||||
|
_ = alignment;
|
||||||
|
// const cstr = @ptrCast([*:0]u8, c_ptr);
|
||||||
|
|
||||||
// const stderr = std.io.getStdErr().writer();
|
// const stderr = std.io.getStdErr().writer();
|
||||||
// stderr.print("Roc panicked: {s}!\n", .{cstr}) catch unreachable;
|
// stderr.print("Roc panicked: {s}!\n", .{cstr}) catch unreachable;
|
||||||
|
@ -226,7 +231,7 @@ pub const RocResult = extern struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Ordering = packed enum(u8) {
|
pub const Ordering = enum(u8) {
|
||||||
EQ = 0,
|
EQ = 0,
|
||||||
GT = 1,
|
GT = 1,
|
||||||
LT = 2,
|
LT = 2,
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
pub const NOTHING_OPENED: &str = "Opening files is not yet supported. Execute `cargo run edit` from the root folder of the repo to try the editor.";
|
pub const NOTHING_OPENED: &str = "Opening files is not yet supported, execute `cargo run edit` from the root folder of the repo to try the editor.";
|
||||||
pub const START_TIP: &str =
|
pub const START_TIP: &str =
|
||||||
"Start by typing '[', '{', '\"' or a number.\nInput chars that would create parse errors will be ignored.";
|
"Start by typing '[', '{', '\"' or a number.\nInput chars that would create parse errors will be ignored.";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue