mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge branch 'main' into div-0-should-crash
This commit is contained in:
commit
20bcd70ad2
195 changed files with 7098 additions and 1165 deletions
|
@ -11,10 +11,14 @@ fn roc_alloc(_: usize, _: u32) callconv(.C) ?*anyopaque {
|
|||
fn roc_panic(_: *anyopaque, _: u32) callconv(.C) void {
|
||||
@panic("Not needed for dec benchmark");
|
||||
}
|
||||
fn roc_dbg(_: *anyopaque, _: *anyopaque) callconv(.C) void {
|
||||
@panic("Not needed for dec benchmark");
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(roc_alloc, .{ .name = "roc_alloc", .linkage = .Strong });
|
||||
@export(roc_panic, .{ .name = "roc_panic", .linkage = .Strong });
|
||||
@export(roc_dbg, .{ .name = "roc_dbg", .linkage = .Strong });
|
||||
}
|
||||
|
||||
var timer: Timer = undefined;
|
||||
|
@ -100,16 +104,16 @@ pub fn main() !void {
|
|||
const f64Atan = try avg_runs(f64, n, atanF64, f1);
|
||||
|
||||
try stdout.print("\n\nDec/F64:\n", .{});
|
||||
try stdout.print("addition: {d:0.2}\n", .{@intToFloat(f64, decAdd) / @intToFloat(f64, f64Add)});
|
||||
try stdout.print("subtraction: {d:0.2}\n", .{@intToFloat(f64, decSub) / @intToFloat(f64, f64Sub)});
|
||||
try stdout.print("multiplication: {d:0.2}\n", .{@intToFloat(f64, decMul) / @intToFloat(f64, f64Mul)});
|
||||
try stdout.print("division: {d:0.2}\n", .{@intToFloat(f64, decDiv) / @intToFloat(f64, f64Div)});
|
||||
try stdout.print("sin: {d:0.2}\n", .{@intToFloat(f64, decSin) / @intToFloat(f64, f64Sin)});
|
||||
try stdout.print("cos: {d:0.2}\n", .{@intToFloat(f64, decCos) / @intToFloat(f64, f64Cos)});
|
||||
try stdout.print("tan: {d:0.2}\n", .{@intToFloat(f64, decTan) / @intToFloat(f64, f64Tan)});
|
||||
try stdout.print("asin: {d:0.2}\n", .{@intToFloat(f64, decAsin) / @intToFloat(f64, f64Asin)});
|
||||
try stdout.print("acos: {d:0.2}\n", .{@intToFloat(f64, decAcos) / @intToFloat(f64, f64Acos)});
|
||||
try stdout.print("atan: {d:0.2}\n", .{@intToFloat(f64, decAtan) / @intToFloat(f64, f64Atan)});
|
||||
try stdout.print("addition: {d:0.2}\n", .{@as(f64, @floatFromInt(decAdd)) / @as(f64, @floatFromInt(f64Add))});
|
||||
try stdout.print("subtraction: {d:0.2}\n", .{@as(f64, @floatFromInt(decSub)) / @as(f64, @floatFromInt(f64Sub))});
|
||||
try stdout.print("multiplication: {d:0.2}\n", .{@as(f64, @floatFromInt(decMul)) / @as(f64, @floatFromInt(f64Mul))});
|
||||
try stdout.print("division: {d:0.2}\n", .{@as(f64, @floatFromInt(decDiv)) / @as(f64, @floatFromInt(f64Div))});
|
||||
try stdout.print("sin: {d:0.2}\n", .{@as(f64, @floatFromInt(decSin)) / @as(f64, @floatFromInt(f64Sin))});
|
||||
try stdout.print("cos: {d:0.2}\n", .{@as(f64, @floatFromInt(decCos)) / @as(f64, @floatFromInt(f64Cos))});
|
||||
try stdout.print("tan: {d:0.2}\n", .{@as(f64, @floatFromInt(decTan)) / @as(f64, @floatFromInt(f64Tan))});
|
||||
try stdout.print("asin: {d:0.2}\n", .{@as(f64, @floatFromInt(decAsin)) / @as(f64, @floatFromInt(f64Asin))});
|
||||
try stdout.print("acos: {d:0.2}\n", .{@as(f64, @floatFromInt(decAcos)) / @as(f64, @floatFromInt(f64Acos))});
|
||||
try stdout.print("atan: {d:0.2}\n", .{@as(f64, @floatFromInt(decAtan)) / @as(f64, @floatFromInt(f64Atan))});
|
||||
}
|
||||
|
||||
fn avg_runs(comptime T: type, comptime n: usize, comptime op: fn (T, T) T, v: T) !u64 {
|
||||
|
|
|
@ -460,6 +460,10 @@ pub const RocDec = extern struct {
|
|||
return RocDec{ .num = out };
|
||||
}
|
||||
|
||||
pub fn log(self: RocDec) RocDec {
|
||||
return fromF64(@log(self.toF64())).?;
|
||||
}
|
||||
|
||||
// I belive the output of the trig functions is always in range of Dec.
|
||||
// If not, we probably should just make it saturate the Dec.
|
||||
// I don't think this should crash or return errors.
|
||||
|
@ -1187,6 +1191,10 @@ test "div: 500 / 1000" {
|
|||
try expectEqual(RocDec.fromStr(roc_str), number1.div(number2));
|
||||
}
|
||||
|
||||
test "log: 1" {
|
||||
try expectEqual(RocDec.fromU64(0), RocDec.log(RocDec.fromU64(1)));
|
||||
}
|
||||
|
||||
// exports
|
||||
|
||||
pub fn fromStr(arg: RocStr) callconv(.C) num_.NumParseResult(i128) {
|
||||
|
@ -1283,6 +1291,10 @@ pub fn divC(arg1: RocDec, arg2: RocDec) callconv(.C) i128 {
|
|||
return @call(.always_inline, RocDec.div, .{ arg1, arg2 }).num;
|
||||
}
|
||||
|
||||
pub fn logC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.always_inline, RocDec.log, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn sinC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.always_inline, RocDec.sin, .{arg}).num;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,3 @@ pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
|
|||
pub fn notifyParentExpect(shared_buffer: [*]u8) callconv(.C) void {
|
||||
notifyParent(shared_buffer, 1);
|
||||
}
|
||||
|
||||
pub fn notifyParentDbg(shared_buffer: [*]u8) callconv(.C) void {
|
||||
notifyParent(shared_buffer, 2);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ comptime {
|
|||
exportDecFn(dec.fromF64C, "from_float.f64");
|
||||
exportDecFn(dec.fromStr, "from_str");
|
||||
exportDecFn(dec.fromU64C, "from_u64");
|
||||
exportDecFn(dec.logC, "log");
|
||||
exportDecFn(dec.mulC, "mul_with_overflow");
|
||||
exportDecFn(dec.mulOrPanicC, "mul_or_panic");
|
||||
exportDecFn(dec.mulSaturatedC, "mul_saturated");
|
||||
|
@ -230,6 +231,7 @@ comptime {
|
|||
|
||||
// Utils
|
||||
comptime {
|
||||
exportUtilsFn(utils.test_dbg, "test_dbg");
|
||||
exportUtilsFn(utils.test_panic, "test_panic");
|
||||
exportUtilsFn(utils.increfRcPtrC, "incref_rc_ptr");
|
||||
exportUtilsFn(utils.decrefRcPtrC, "decref_rc_ptr");
|
||||
|
@ -248,7 +250,6 @@ comptime {
|
|||
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
|
||||
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
|
||||
exportUtilsFn(expect.notifyParentExpect, "notify_parent_expect");
|
||||
exportUtilsFn(expect.notifyParentDbg, "notify_parent_dbg");
|
||||
|
||||
// sets the buffer used for expect failures
|
||||
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });
|
||||
|
|
|
@ -20,6 +20,13 @@ extern fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, align
|
|||
// This should never be passed a null pointer.
|
||||
extern fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void;
|
||||
|
||||
extern fn roc_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void;
|
||||
|
||||
// Since roc_dbg is never used by the builtins, we need at export a function that uses it to stop DCE.
|
||||
pub fn test_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void {
|
||||
roc_dbg(file_path, message);
|
||||
}
|
||||
|
||||
extern fn kill(pid: c_int, sig: c_int) c_int;
|
||||
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
|
||||
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
|
||||
|
@ -40,6 +47,11 @@ fn testing_roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int
|
|||
return mmap(addr, length, prot, flags, fd, offset);
|
||||
}
|
||||
|
||||
fn testing_roc_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void {
|
||||
_ = message;
|
||||
_ = file_path;
|
||||
}
|
||||
|
||||
comptime {
|
||||
// During tests, use the testing allocators to satisfy these functions.
|
||||
if (builtin.is_test) {
|
||||
|
@ -47,6 +59,7 @@ comptime {
|
|||
@export(testing_roc_realloc, .{ .name = "roc_realloc", .linkage = .Strong });
|
||||
@export(testing_roc_dealloc, .{ .name = "roc_dealloc", .linkage = .Strong });
|
||||
@export(testing_roc_panic, .{ .name = "roc_panic", .linkage = .Strong });
|
||||
@export(testing_roc_dbg, .{ .name = "roc_dbg", .linkage = .Strong });
|
||||
|
||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
@export(testing_roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
|
||||
|
|
|
@ -32,6 +32,7 @@ interface Dict
|
|||
Str,
|
||||
Num.{ Nat, U64, U8, I8 },
|
||||
Hash.{ Hasher, Hash },
|
||||
Inspect.{ Inspect, Inspector, InspectFormatter },
|
||||
]
|
||||
|
||||
## A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you
|
||||
|
@ -108,6 +109,9 @@ Dict k v := {
|
|||
Hash {
|
||||
hash: hashDict,
|
||||
},
|
||||
Inspect {
|
||||
toInspector: toInspectorDict,
|
||||
},
|
||||
]
|
||||
|
||||
isEq : Dict k v, Dict k v -> Bool where k implements Hash & Eq, v implements Eq
|
||||
|
@ -126,6 +130,11 @@ isEq = \xs, ys ->
|
|||
hashDict : hasher, Dict k v -> hasher where k implements Hash & Eq, v implements Hash, hasher implements Hasher
|
||||
hashDict = \hasher, dict -> Hash.hashUnordered hasher (toList dict) List.walk
|
||||
|
||||
toInspectorDict : Dict k v -> Inspector f where k implements Inspect & Hash & Eq, v implements Inspect, f implements InspectFormatter
|
||||
toInspectorDict = \dict ->
|
||||
fmt <- Inspect.custom
|
||||
Inspect.apply (Inspect.dict dict walk Inspect.toInspector Inspect.toInspector) fmt
|
||||
|
||||
## Return an empty dictionary.
|
||||
## ```
|
||||
## emptyDict = Dict.empty {}
|
||||
|
|
|
@ -15,6 +15,7 @@ interface Inspect
|
|||
record,
|
||||
bool,
|
||||
str,
|
||||
function,
|
||||
opaque,
|
||||
u8,
|
||||
i8,
|
||||
|
@ -26,16 +27,19 @@ interface Inspect
|
|||
i64,
|
||||
u128,
|
||||
i128,
|
||||
nat,
|
||||
f32,
|
||||
f64,
|
||||
dec,
|
||||
custom,
|
||||
apply,
|
||||
toInspector,
|
||||
DbgFormatter,
|
||||
toDbgStr,
|
||||
]
|
||||
imports [
|
||||
Bool.{ Bool },
|
||||
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec },
|
||||
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec, Nat },
|
||||
List,
|
||||
Str,
|
||||
]
|
||||
|
@ -56,12 +60,13 @@ InspectFormatter implements
|
|||
set : set, ElemWalker state set elem, (elem -> Inspector f) -> Inspector f where f implements InspectFormatter
|
||||
dict : dict, KeyValWalker state dict key value, (key -> Inspector f), (value -> Inspector f) -> Inspector f where f implements InspectFormatter
|
||||
|
||||
# Note opaque is used for both opaque types and functions.
|
||||
# The auto deriver for functions probably could put the function type.
|
||||
# For regular opaque types, I think we can use the type name, though that may lead to some reflection related issues that still need to be discussed.
|
||||
# As a simple baseline, it can just use the exact words `opaque` and `function` for now.
|
||||
# In text, this would render as `<opaque>`, `<function>`, etc
|
||||
opaque : Str -> Inspector f where f implements InspectFormatter
|
||||
# In text, this would render as `<opaque>`
|
||||
# TODO: Pass the type name to opaque so that it can be displayed.
|
||||
opaque : * -> Inspector f where f implements InspectFormatter
|
||||
|
||||
# In text, this would render as `<function>`
|
||||
# TODO: Maybe pass the the function name or signiture to function so that it can be displayed.
|
||||
function : * -> Inspector f where f implements InspectFormatter
|
||||
|
||||
u8 : U8 -> Inspector f where f implements InspectFormatter
|
||||
i8 : I8 -> Inspector f where f implements InspectFormatter
|
||||
|
@ -73,6 +78,7 @@ InspectFormatter implements
|
|||
i64 : I64 -> Inspector f where f implements InspectFormatter
|
||||
u128 : U128 -> Inspector f where f implements InspectFormatter
|
||||
i128 : I128 -> Inspector f where f implements InspectFormatter
|
||||
nat : Nat -> Inspector f where f implements InspectFormatter
|
||||
f32 : F32 -> Inspector f where f implements InspectFormatter
|
||||
f64 : F64 -> Inspector f where f implements InspectFormatter
|
||||
dec : Dec -> Inspector f where f implements InspectFormatter
|
||||
|
@ -80,7 +86,7 @@ InspectFormatter implements
|
|||
Inspector f := f -> f where f implements InspectFormatter
|
||||
|
||||
custom : (f -> f) -> Inspector f where f implements InspectFormatter
|
||||
custom = @Inspector
|
||||
custom = \fn -> @Inspector fn
|
||||
|
||||
apply : Inspector f, f -> f where f implements InspectFormatter
|
||||
apply = \@Inspector fn, fmt -> fn fmt
|
||||
|
@ -92,3 +98,252 @@ inspect : val -> f where val implements Inspect, f implements InspectFormatter
|
|||
inspect = \val ->
|
||||
(@Inspector valFn) = toInspector val
|
||||
valFn (init {})
|
||||
|
||||
# The current default formatter for inspect.
|
||||
# This just returns a simple string for debugging.
|
||||
# More powerful formatters will likely be wanted in the future.
|
||||
DbgFormatter := { data : Str }
|
||||
implements [
|
||||
InspectFormatter {
|
||||
init: dbgInit,
|
||||
list: dbgList,
|
||||
set: dbgSet,
|
||||
dict: dbgDict,
|
||||
tag: dbgTag,
|
||||
tuple: dbgTuple,
|
||||
record: dbgRecord,
|
||||
bool: dbgBool,
|
||||
str: dbgStr,
|
||||
opaque: dbgOpaque,
|
||||
function: dbgFunction,
|
||||
u8: dbgU8,
|
||||
i8: dbgI8,
|
||||
u16: dbgU16,
|
||||
i16: dbgI16,
|
||||
u32: dbgU32,
|
||||
i32: dbgI32,
|
||||
u64: dbgU64,
|
||||
i64: dbgI64,
|
||||
u128: dbgU128,
|
||||
i128: dbgI128,
|
||||
nat: dbgNat,
|
||||
f32: dbgF32,
|
||||
f64: dbgF64,
|
||||
dec: dbgDec,
|
||||
},
|
||||
]
|
||||
|
||||
dbgInit : {} -> DbgFormatter
|
||||
dbgInit = \{} -> @DbgFormatter { data: "" }
|
||||
|
||||
dbgList : list, ElemWalker (DbgFormatter, Bool) list elem, (elem -> Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgList = \content, walkFn, toDbgInspector ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "["
|
||||
|> \f1 ->
|
||||
(f2, prependSep), elem <- walkFn content (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
elem
|
||||
|> toDbgInspector
|
||||
|> apply f3
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "]"
|
||||
|
||||
dbgSet : set, ElemWalker (DbgFormatter, Bool) set elem, (elem -> Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgSet = \content, walkFn, toDbgInspector ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "{"
|
||||
|> \f1 ->
|
||||
(f2, prependSep), elem <- walkFn content (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
elem
|
||||
|> toDbgInspector
|
||||
|> apply f3
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "}"
|
||||
|
||||
dbgDict : dict, KeyValWalker (DbgFormatter, Bool) dict key value, (key -> Inspector DbgFormatter), (value -> Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgDict = \d, walkFn, keyToInspector, valueToInspector ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "{"
|
||||
|> \f1 ->
|
||||
(f2, prependSep), key, value <- walkFn d (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
apply (keyToInspector key) f3
|
||||
|> dbgWrite ": "
|
||||
|> \x -> apply (valueToInspector value) x
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "}"
|
||||
|
||||
dbgTag : Str, List (Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgTag = \name, fields ->
|
||||
if List.isEmpty fields then
|
||||
f0 <- custom
|
||||
dbgWrite f0 name
|
||||
else
|
||||
f0 <- custom
|
||||
dbgWrite f0 "("
|
||||
|> dbgWrite name
|
||||
|> \f1 ->
|
||||
f2, inspector <- List.walk fields f1
|
||||
dbgWrite f2 " "
|
||||
|> \x -> apply inspector x
|
||||
|> dbgWrite ")"
|
||||
|
||||
dbgTuple : List (Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgTuple = \fields ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "("
|
||||
|> \f1 ->
|
||||
(f2, prependSep), inspector <- List.walk fields (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
apply inspector f3
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite ")"
|
||||
|
||||
dbgRecord : List { key : Str, value : Inspector DbgFormatter } -> Inspector DbgFormatter
|
||||
dbgRecord = \fields ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "{"
|
||||
|> \f1 ->
|
||||
(f2, prependSep), { key, value } <- List.walk fields (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
dbgWrite f3 key
|
||||
|> dbgWrite ": "
|
||||
|> \x -> apply value x
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "}"
|
||||
|
||||
dbgBool : Bool -> Inspector DbgFormatter
|
||||
dbgBool = \b ->
|
||||
if b then
|
||||
f0 <- custom
|
||||
dbgWrite f0 "Bool.true"
|
||||
else
|
||||
f0 <- custom
|
||||
dbgWrite f0 "Bool.false"
|
||||
|
||||
dbgStr : Str -> Inspector DbgFormatter
|
||||
dbgStr = \s ->
|
||||
f0 <- custom
|
||||
f0
|
||||
|> dbgWrite "\""
|
||||
|> dbgWrite s # TODO: Should we be escaping strings for dbg/logging?
|
||||
|> dbgWrite "\""
|
||||
|
||||
dbgOpaque : * -> Inspector DbgFormatter
|
||||
dbgOpaque = \_ ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "<opaque>"
|
||||
|
||||
dbgFunction : * -> Inspector DbgFormatter
|
||||
dbgFunction = \_ ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "<function>"
|
||||
|
||||
dbgU8 : U8 -> Inspector DbgFormatter
|
||||
dbgU8 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI8 : I8 -> Inspector DbgFormatter
|
||||
dbgI8 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU16 : U16 -> Inspector DbgFormatter
|
||||
dbgU16 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI16 : I16 -> Inspector DbgFormatter
|
||||
dbgI16 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU32 : U32 -> Inspector DbgFormatter
|
||||
dbgU32 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI32 : I32 -> Inspector DbgFormatter
|
||||
dbgI32 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU64 : U64 -> Inspector DbgFormatter
|
||||
dbgU64 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI64 : I64 -> Inspector DbgFormatter
|
||||
dbgI64 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU128 : U128 -> Inspector DbgFormatter
|
||||
dbgU128 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI128 : I128 -> Inspector DbgFormatter
|
||||
dbgI128 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgNat : Nat -> Inspector DbgFormatter
|
||||
dbgNat = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgF32 : F32 -> Inspector DbgFormatter
|
||||
dbgF32 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgF64 : F64 -> Inspector DbgFormatter
|
||||
dbgF64 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgDec : Dec -> Inspector DbgFormatter
|
||||
dbgDec = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgWrite : DbgFormatter, Str -> DbgFormatter
|
||||
dbgWrite = \@DbgFormatter { data }, added ->
|
||||
@DbgFormatter { data: Str.concat data added }
|
||||
|
||||
toDbgStr : DbgFormatter -> Str
|
||||
toDbgStr = \@DbgFormatter { data } -> data
|
||||
|
|
|
@ -25,6 +25,7 @@ interface Set
|
|||
Dict.{ Dict },
|
||||
Num.{ Nat },
|
||||
Hash.{ Hash, Hasher },
|
||||
Inspect.{ Inspect, Inspector, InspectFormatter },
|
||||
]
|
||||
|
||||
## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
|
||||
|
@ -37,6 +38,9 @@ Set k := Dict.Dict k {} where k implements Hash & Eq
|
|||
Hash {
|
||||
hash: hashSet,
|
||||
},
|
||||
Inspect {
|
||||
toInspector: toInspectorSet,
|
||||
},
|
||||
]
|
||||
|
||||
isEq : Set k, Set k -> Bool where k implements Hash & Eq
|
||||
|
@ -53,6 +57,11 @@ isEq = \xs, ys ->
|
|||
hashSet : hasher, Set k -> hasher where k implements Hash & Eq, hasher implements Hasher
|
||||
hashSet = \hasher, @Set inner -> Hash.hash hasher inner
|
||||
|
||||
toInspectorSet : Set k -> Inspector f where k implements Inspect & Hash & Eq, f implements InspectFormatter
|
||||
toInspectorSet = \set ->
|
||||
fmt <- Inspect.custom
|
||||
Inspect.apply (Inspect.set set walk Inspect.toInspector) fmt
|
||||
|
||||
## Creates a new empty `Set`.
|
||||
## ```
|
||||
## emptySet = Set.empty {}
|
||||
|
|
|
@ -880,8 +880,11 @@ walkUtf8WithIndexHelp = \string, state, step, index, length ->
|
|||
## state for each byte.
|
||||
##
|
||||
## ```
|
||||
## result = walkUtf8 "hello, world!" "" (\state, byte -> state ++ String.fromCodePoint byte)
|
||||
## expect result == Ok "hello, world!"
|
||||
## sumOfUtf8Bytes =
|
||||
## Str.walkUtf8 "Hello, World!" 0 \total, byte ->
|
||||
## total + byte
|
||||
##
|
||||
## expect sumOfUtf8Bytes == 105
|
||||
## ```
|
||||
walkUtf8 : Str, state, (state, U8 -> state) -> state
|
||||
walkUtf8 = \str, initial, step ->
|
||||
|
|
|
@ -408,6 +408,7 @@ pub const DEC_FROM_FLOAT: IntrinsicName = float_intrinsic!("roc_builtins.dec.fro
|
|||
pub const DEC_FROM_INT: IntrinsicName = int_intrinsic!("roc_builtins.dec.from_int");
|
||||
pub const DEC_FROM_STR: &str = "roc_builtins.dec.from_str";
|
||||
pub const DEC_FROM_U64: &str = "roc_builtins.dec.from_u64";
|
||||
pub const DEC_LOG: &str = "roc_builtins.dec.log";
|
||||
pub const DEC_MUL_OR_PANIC: &str = "roc_builtins.dec.mul_or_panic";
|
||||
pub const DEC_MUL_SATURATED: &str = "roc_builtins.dec.mul_saturated";
|
||||
pub const DEC_MUL_WITH_OVERFLOW: &str = "roc_builtins.dec.mul_with_overflow";
|
||||
|
@ -439,7 +440,6 @@ pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
|
|||
"roc_builtins.utils.expect_failed_start_shared_file";
|
||||
pub const UTILS_EXPECT_READ_ENV_SHARED_BUFFER: &str = "roc_builtins.utils.read_env_shared_buffer";
|
||||
pub const NOTIFY_PARENT_EXPECT: &str = "roc_builtins.utils.notify_parent_expect";
|
||||
pub const NOTIFY_PARENT_DBG: &str = "roc_builtins.utils.notify_parent_dbg";
|
||||
|
||||
pub const UTILS_LONGJMP: &str = "longjmp";
|
||||
pub const UTILS_SETJMP: &str = "setjmp";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue