@shd101wyy/yo 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.github/skills/yo-async-effects/async-effects-recipes.md +2 -2
  2. package/.github/skills/yo-core-patterns/SKILL.md +1 -1
  3. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +76 -22
  4. package/.github/skills/yo-syntax/SKILL.md +1 -1
  5. package/.github/skills/yo-syntax/syntax-cheatsheet.md +59 -67
  6. package/out/cjs/index.cjs +662 -574
  7. package/out/cjs/yo-cli.cjs +803 -715
  8. package/out/cjs/yo-lsp.cjs +771 -683
  9. package/out/esm/index.mjs +555 -467
  10. package/out/types/src/codegen/exprs/comptime-value.d.ts +2 -1
  11. package/out/types/src/codegen/functions/context.d.ts +1 -0
  12. package/out/types/src/codegen/types/generation.d.ts +1 -1
  13. package/out/types/src/codegen/utils/index.d.ts +2 -4
  14. package/out/types/src/evaluator/exprs/_expr.d.ts +1 -0
  15. package/out/types/src/evaluator/types/flowability.d.ts +22 -0
  16. package/out/types/src/expr.d.ts +4 -13
  17. package/out/types/src/types/creators.d.ts +2 -3
  18. package/out/types/src/types/definitions.d.ts +2 -3
  19. package/out/types/src/types/guards.d.ts +2 -2
  20. package/out/types/src/types/tags.d.ts +2 -2
  21. package/out/types/src/value-tag.d.ts +0 -1
  22. package/out/types/src/value.d.ts +2 -11
  23. package/out/types/tsconfig.tsbuildinfo +1 -1
  24. package/package.json +1 -1
  25. package/std/alg/hash.yo +5 -3
  26. package/std/build.yo +46 -46
  27. package/std/collections/array_list.yo +73 -66
  28. package/std/collections/hash_map.yo +53 -95
  29. package/std/collections/list_view.yo +77 -0
  30. package/std/crypto/random.yo +5 -5
  31. package/std/encoding/base64.yo +12 -13
  32. package/std/encoding/hex.yo +6 -6
  33. package/std/encoding/json.yo +6 -5
  34. package/std/encoding/utf16.yo +9 -9
  35. package/std/env.yo +8 -8
  36. package/std/fmt/to_string.yo +12 -12
  37. package/std/http/client.yo +1 -1
  38. package/std/imm/list.yo +4 -3
  39. package/std/imm/map.yo +3 -2
  40. package/std/imm/set.yo +4 -3
  41. package/std/imm/sorted_map.yo +3 -2
  42. package/std/imm/sorted_set.yo +4 -3
  43. package/std/imm/string.yo +12 -5
  44. package/std/imm/vec.yo +8 -3
  45. package/std/prelude.yo +178 -401
  46. package/std/string/string.yo +198 -71
  47. package/std/url/index.yo +26 -26
  48. package/out/types/src/evaluator/types/slice.d.ts +0 -8
@@ -0,0 +1,77 @@
1
+ //! ListView — a SAFE window over an `ArrayList(T)`.
2
+ //!
3
+ //! The safe replacement for borrowed slices (plans/SLICE_REWORK.md §3):
4
+ //! a ListView holds the Rc'd backing list and indexes through the LIVE
5
+ //! handle. By construction it cannot dangle:
6
+ //! - the view's Rc keeps the backing object alive (reassigning the
7
+ //! original variable doesn't matter),
8
+ //! - every access re-reads the CURRENT buffer through the handle, so
9
+ //! realloc-on-growth cannot leave a stale pointer,
10
+ //! - shrinkage is caught by bounds checks (a clean `.None`, never UB),
11
+ //! - alias mutation is VISIBLE (alias semantics, not a snapshot).
12
+ //!
13
+ //! Cost model: copying a view = one Rc incref; access = one extra
14
+ //! indirection + bounds check. No copy-on-write.
15
+ { ArrayList } :: import("./array_list.yo");
16
+ ListView :: (fn(comptime(T) : Type) -> comptime(Type))(
17
+ struct(
18
+ _backing : ArrayList(T),
19
+ _offset : usize,
20
+ _len : usize
21
+ )
22
+ );
23
+ impl(
24
+ forall(T : Type),
25
+ ListView(T),
26
+ /// Create a view of `[offset, offset+len)` over `backing`. The window is
27
+ /// clamped to the backing's CURRENT length.
28
+ new : (fn(backing : ArrayList(T), offset : usize, len : usize) -> Self)({
29
+ blen := backing.len();
30
+ o := cond((offset > blen) => blen, true => offset);
31
+ available := (blen - o);
32
+ l := cond((len > available) => available, true => len);
33
+ Self(_backing : backing, _offset : o, _len : l)
34
+ }),
35
+ /// View of the whole list.
36
+ of : (fn(backing : ArrayList(T)) -> Self)({
37
+ n := backing.len();
38
+ Self(_backing : backing, _offset : usize(0), _len : n)
39
+ }),
40
+ /// The view's length (fixed at construction; may exceed what the
41
+ /// backing currently holds if it shrank — reads past it yield .None).
42
+ len : (fn(self : Self) -> usize)(self._len),
43
+ is_empty : (fn(self : Self) -> bool)(self._len == usize(0)),
44
+ /// Read element `i` THROUGH the live backing. Bounds-checked against
45
+ /// both the view window and the backing's current length.
46
+ get : (fn(self : Self, i : usize) -> Option(T))(
47
+ cond(
48
+ (i >= self._len) => Option(T).None,
49
+ true => self._backing.get(self._offset + i)
50
+ )
51
+ ),
52
+ /// A sub-view of this view (still aliasing the same backing).
53
+ /// (Params avoid the names of sibling methods bound earlier in this
54
+ /// impl — e.g. `len` — which cannot be shadowed.)
55
+ view : (fn(self : Self, sub_offset : usize, sub_len : usize) -> Self)({
56
+ o := cond((sub_offset > self._len) => self._len, true => sub_offset);
57
+ available := (self._len - o);
58
+ l := cond((sub_len > available) => available, true => sub_len);
59
+ Self(_backing : self._backing, _offset : (self._offset + o), _len : l)
60
+ }),
61
+ /// Owned copy of the window's CURRENT contents.
62
+ to_list : (fn(self : Self) -> ArrayList(T))({
63
+ out := ArrayList(T).new();
64
+ i := usize(0);
65
+ while(i < self._len, i = (i + usize(1)), {
66
+ match(
67
+ self._backing.get(self._offset + i),
68
+ .Some(v) => {
69
+ ___ := out.push(v);
70
+ },
71
+ .None => ()
72
+ );
73
+ });
74
+ out
75
+ })
76
+ );
77
+ export(ListView);
@@ -55,9 +55,9 @@ extern(
55
55
  // ============================================================================
56
56
  // Fill a buffer with cryptographically secure random bytes.
57
57
  // ============================================================================
58
- random_bytes :: (fn(buf : Slice(u8), exn : Exception) -> unit)({
59
- buf_ptr := buf.ptr();
60
- size := buf.len();
58
+ random_bytes :: (fn(buf : RawSlice(u8), exn : Exception) -> unit)({
59
+ buf_ptr := buf.ptr;
60
+ size := buf.len;
61
61
  cond(
62
62
  (platform == Platform.Macos) => {
63
63
  __yo_arc4random_buf(buf_ptr, size);
@@ -109,7 +109,7 @@ export(random_bytes);
109
109
  // ============================================================================
110
110
  random_u32 :: (fn(exn : Exception) -> u32)({
111
111
  buf := Array(u8, usize(4)).fill(u8(0));
112
- random_bytes(Slice(u8).from_raw_parts(&(buf(usize(0))), usize(4)), exn);
112
+ random_bytes(RawSlice(u8)(ptr : &(buf(usize(0))), len : usize(4)), exn);
113
113
  u32(buf(usize(0))) |
114
114
  (u32(buf(usize(1))) << u32(8)) |
115
115
  (u32(buf(usize(2))) << u32(16)) |
@@ -142,7 +142,7 @@ export(random_u32, random_u64, random_f64, random_range);
142
142
  uuid_v4 :: (fn(exn : Exception) -> String)({
143
143
  bytes := ArrayList(u8).with_capacity(usize(16));
144
144
  buf := Array(u8, usize(16)).fill(u8(0));
145
- random_bytes(Slice(u8).from_raw_parts(&(buf(usize(0))), usize(16)), exn);
145
+ random_bytes(RawSlice(u8)(ptr : &(buf(usize(0))), len : usize(16)), exn);
146
146
  // Set version bits (v4)
147
147
  buf(usize(6)) = ((buf(usize(6)) & u8(0x0F)) | u8(0x40));
148
148
  // Set variant bits
@@ -6,7 +6,7 @@
6
6
  //! { base64_encode, base64_decode } :: import "std/encoding/base64";
7
7
  //!
8
8
  //! s := base64_encode(data);
9
- //! b := base64_decode(s.to_str()).unwrap();
9
+ //! b := base64_decode(s.to_string()).unwrap();
10
10
  //! ```
11
11
  open(import("../string"));
12
12
  { ArrayList } :: import("../collections/array_list");
@@ -76,26 +76,26 @@ _decode_char :: (fn(c : u8, alpha : str, exn : Exception) -> u8)({
76
76
  });
77
77
  exn.throw(dyn(EncodingError.InvalidChar(c)))
78
78
  });
79
- _decode_with :: (fn(s : str, alpha : str, exn : Exception) -> ArrayList(u8))({
79
+ _decode_with :: (fn(s : String, alpha : str, exn : Exception) -> ArrayList(u8))({
80
80
  // Strip trailing padding
81
- len := s.len();
82
- while((len > usize(0)) && (s.bytes(len - usize(1)) == _PAD), len = (len - usize(1)), ());
81
+ len := s.bytes_len();
82
+ while((len > usize(0)) && (s.byte_at(len - usize(1)) == _PAD), len = (len - usize(1)), ());
83
83
  out := ArrayList(u8).with_capacity((len * usize(3)) / usize(4));
84
84
  i := usize(0);
85
85
  while(i < len, i = (i + usize(4)), {
86
- c0 := _decode_char(s.bytes(i), alpha, exn);
86
+ c0 := _decode_char(s.byte_at(i), alpha, exn);
87
87
  c1 := cond(
88
- ((i + usize(1)) < len) => _decode_char(s.bytes(i + usize(1)), alpha, exn),
88
+ ((i + usize(1)) < len) => _decode_char(s.byte_at(i + usize(1)), alpha, exn),
89
89
  true => u8(0)
90
90
  );
91
91
  out.push((c0 << u8(2)) | (c1 >> u8(4)));
92
92
  cond(
93
93
  ((i + usize(2)) < len) => {
94
- c2 := _decode_char(s.bytes(i + usize(2)), alpha, exn);
94
+ c2 := _decode_char(s.byte_at(i + usize(2)), alpha, exn);
95
95
  out.push(((c1 & u8(15)) << u8(4)) | (c2 >> u8(2)));
96
96
  cond(
97
97
  ((i + usize(3)) < len) => {
98
- c3 := _decode_char(s.bytes(i + usize(3)), alpha, exn);
98
+ c3 := _decode_char(s.byte_at(i + usize(3)), alpha, exn);
99
99
  out.push(((c2 & u8(3)) << u8(6)) | c3);
100
100
  },
101
101
  true => ()
@@ -107,11 +107,11 @@ _decode_with :: (fn(s : str, alpha : str, exn : Exception) -> ArrayList(u8))({
107
107
  out
108
108
  });
109
109
  /// Decode a standard base64 string to bytes. Throws via `Exception` on invalid input.
110
- base64_decode :: (fn(s : str, exn : Exception) -> ArrayList(u8))(
110
+ base64_decode :: (fn(s : String, exn : Exception) -> ArrayList(u8))(
111
111
  _decode_with(s, _STD_ALPHA, exn)
112
112
  );
113
113
  /// Decode a URL-safe base64 string to bytes. Throws via `Exception` on invalid input.
114
- base64_decode_url :: (fn(s : str, exn : Exception) -> ArrayList(u8))(
114
+ base64_decode_url :: (fn(s : String, exn : Exception) -> ArrayList(u8))(
115
115
  _decode_with(s, _URL_ALPHA, exn)
116
116
  );
117
117
  export(base64_decode, base64_decode_url);
@@ -138,11 +138,10 @@ _base64_index :: (fn(c : u8) -> i32)({
138
138
  });
139
139
  /// Decode a base64 `String`, ignoring whitespace. Returns `Result(String, String)`.
140
140
  base64_decode_string :: (fn(input : String) -> Result(String, String))({
141
- raw := input.as_str();
142
141
  cleaned := ArrayList(u8).new();
143
142
  i := usize(0);
144
- while(i < raw.len(), i = (i + usize(1)), {
145
- ch := raw.bytes(i);
143
+ while(i < input.bytes_len(), i = (i + usize(1)), {
144
+ ch := input.byte_at(i);
146
145
  cond(
147
146
  (((ch == u8(32)) || (ch == u8(9))) || ((ch == u8(10)) || (ch == u8(13)))) => (),
148
147
  true => {
@@ -76,18 +76,18 @@ _hex_nibble :: (fn(c : u8, exn : Exception) -> u8)(
76
76
  )
77
77
  );
78
78
  /// Decode a hexadecimal string to bytes. Throws via `Exception` on invalid input.
79
- hex_decode :: (fn(s : str, exn : Exception) -> ArrayList(u8))({
79
+ hex_decode :: (fn(s : String, exn : Exception) -> ArrayList(u8))({
80
80
  cond(
81
- ((s.len() % usize(2)) != usize(0)) => {
81
+ ((s.bytes_len() % usize(2)) != usize(0)) => {
82
82
  exn.throw(dyn(EncodingError.OddLength));
83
83
  },
84
84
  true => ()
85
85
  );
86
- out := ArrayList(u8).with_capacity(s.len() / usize(2));
86
+ out := ArrayList(u8).with_capacity(s.bytes_len() / usize(2));
87
87
  i := usize(0);
88
- while(i < s.len(), i = (i + usize(2)), {
89
- hi := _hex_nibble(s.bytes(i), exn);
90
- lo := _hex_nibble(s.bytes(i + usize(1)), exn);
88
+ while(i < s.bytes_len(), i = (i + usize(2)), {
89
+ hi := _hex_nibble(s.byte_at(i), exn);
90
+ lo := _hex_nibble(s.byte_at(i + usize(1)), exn);
91
91
  out.push((hi << u8(4)) | lo);
92
92
  });
93
93
  out
@@ -173,9 +173,9 @@ impl(
173
173
  if(keys(i) == key, {
174
174
  // SAFETY: `i` is bounded by `keys.len()` and the
175
175
  // Object variant invariant says `values.len() ==
176
- // keys.len()`, so `values.project(i)` yields a valid
177
- // ref into the Rc-managed values list.
178
- return(unsafe(&(values.project(i))));
176
+ // keys.len()`, so `&(values(i))` (Index trait) yields a
177
+ // valid pointer into the Rc-managed values list.
178
+ return(unsafe(&(values(i))));
179
179
  });
180
180
  });
181
181
  panic("JsonValue: key not found in Object")
@@ -198,8 +198,9 @@ impl(
198
198
  assert(idx < items.len(), "JsonValue: Array index out of bounds");
199
199
  // SAFETY: assert above bounds `idx`; `items` is the
200
200
  // Rc-managed Array list whose storage outlives this call
201
- // (ref(self) keeps `self` and therefore `items` alive).
202
- return(unsafe(&(items.project(idx))));
201
+ // (ref(self) keeps `self` and therefore `items` alive);
202
+ // `&(items(idx))` (Index trait) yields the element pointer.
203
+ return(unsafe(&(items(idx))));
203
204
  },
204
205
  _ => panic("JsonValue: index by usize requires .Array variant")
205
206
  )
@@ -20,34 +20,34 @@ open(import("../string"));
20
20
  /// Convert a UTF-8 string to an `ArrayList(u16)` of UTF-16 code units.
21
21
  ///
22
22
  /// Handles BMP characters directly and encodes supplementary characters as surrogate pairs.
23
- utf8_to_utf16 :: (fn(s : str) -> ArrayList(u16))({
23
+ utf8_to_utf16 :: (fn(s : String) -> ArrayList(u16))({
24
24
  out := ArrayList(u16).new();
25
25
  i := usize(0);
26
- while(i < s.len(), {
27
- b0 := u32(s.bytes(i));
26
+ while(i < s.bytes_len(), {
27
+ b0 := u32(s.byte_at(i));
28
28
  cond(
29
29
  (b0 < u32(0x80)) => {
30
30
  out.push(u16(b0));
31
31
  i = (i + usize(1));
32
32
  },
33
33
  ((b0 & u32(0xE0)) == u32(0xC0)) => {
34
- b1 := u32(s.bytes(i + usize(1)));
34
+ b1 := u32(s.byte_at(i + usize(1)));
35
35
  cp := (((b0 & u32(0x1F)) << u32(6)) | (b1 & u32(0x3F)));
36
36
  out.push(u16(cp));
37
37
  i = (i + usize(2));
38
38
  },
39
39
  ((b0 & u32(0xF0)) == u32(0xE0)) => {
40
- b1 := u32(s.bytes(i + usize(1)));
41
- b2 := u32(s.bytes(i + usize(2)));
40
+ b1 := u32(s.byte_at(i + usize(1)));
41
+ b2 := u32(s.byte_at(i + usize(2)));
42
42
  cp := ((((b0 & u32(0x0F)) << u32(12)) | ((b1 & u32(0x3F)) << u32(6))) | (b2 & u32(0x3F)));
43
43
  out.push(u16(cp));
44
44
  i = (i + usize(3));
45
45
  },
46
46
  true => {
47
47
  // 4-byte sequence → surrogate pair
48
- b1 := u32(s.bytes(i + usize(1)));
49
- b2 := u32(s.bytes(i + usize(2)));
50
- b3 := u32(s.bytes(i + usize(3)));
48
+ b1 := u32(s.byte_at(i + usize(1)));
49
+ b2 := u32(s.byte_at(i + usize(2)));
50
+ b3 := u32(s.byte_at(i + usize(3)));
51
51
  cp := (((((b0 & u32(0x07)) << u32(18)) | ((b1 & u32(0x3F)) << u32(12))) | ((b2 & u32(0x3F)) << u32(6))) | (b3 & u32(0x3F)));
52
52
  cp2 := (cp - u32(0x10000));
53
53
  hi := u16((cp2 >> u32(10)) + u32(0xD800));
package/std/env.yo CHANGED
@@ -14,14 +14,14 @@ open(import("./path"));
14
14
  extern(
15
15
  "Yo",
16
16
  __yo_argc : i32,
17
- __yo_argv : *(*(u8)),
18
- __yo_args : [*(u8)]
17
+ __yo_argv : *(*(u8))
19
18
  );
20
19
  // === Raw command-line arguments ===
21
- /// Get raw command-line arguments as a slice of C strings.
22
- /// The first element is the program name.
23
- raw_args :: (fn() -> [*(u8)])({
24
- return(__yo_args);
20
+ /// Get raw command-line arguments as a RawSlice of C strings (privileged:
21
+ /// callers must be pragma'd to name RawSlice). The first element is the
22
+ /// program name.
23
+ raw_args :: (fn() -> RawSlice(*(u8)))({
24
+ return(RawSlice(*(u8))(ptr : __yo_argv, len : usize(__yo_argc)));
25
25
  });
26
26
  export(raw_args);
27
27
  /// Get the number of command-line arguments (including program name).
@@ -38,12 +38,12 @@ export(argv);
38
38
  /// Get command-line arguments as an `ArrayList(String)`.
39
39
  /// The first element is the program name.
40
40
  args :: (fn() -> ArrayList(String))({
41
- raw := raw_args();
42
41
  i := usize(0);
43
42
  len := usize(argc());
44
43
  result := ArrayList(String).with_capacity(len);
45
44
  while(i < len, {
46
- arg_ptr := raw(i);
45
+ // SAFETY: i < argc; argv is the C runtime's argument vector.
46
+ arg_ptr := unsafe((__yo_argv &+ i).*);
47
47
  arg_str := String.from_cstr(arg_ptr).unwrap();
48
48
  result.push(arg_str);
49
49
  i = (i + 1);
@@ -252,22 +252,22 @@ impl(
252
252
  // TODO: Array to_string implementation?
253
253
  // --- derive_rule for ToString ---
254
254
  // Local helpers (not exported from prelude, so defined locally)
255
- __ts_s2 :: (fn(comptime(a) : comptime_string, comptime(b) : comptime_string) -> comptime(comptime_string))(a + b);
256
- __ts_s3 :: (fn(comptime(a) : comptime_string, comptime(b) : comptime_string, comptime(c) : comptime_string) -> comptime(comptime_string))(
255
+ __ts_s2 :: (fn(comptime(a) : comptime_str, comptime(b) : comptime_str) -> comptime(comptime_str))(a + b);
256
+ __ts_s3 :: (fn(comptime(a) : comptime_str, comptime(b) : comptime_str, comptime(c) : comptime_str) -> comptime(comptime_str))(
257
257
  (a + b) + c
258
258
  );
259
- __ts_s4 :: (fn(comptime(a) : comptime_string, comptime(b) : comptime_string, comptime(c) : comptime_string, comptime(d) : comptime_string) -> comptime(comptime_string))(
259
+ __ts_s4 :: (fn(comptime(a) : comptime_str, comptime(b) : comptime_str, comptime(c) : comptime_str, comptime(d) : comptime_str) -> comptime(comptime_str))(
260
260
  ((a + b) + c) + d
261
261
  );
262
- __ts_s5 :: (fn(comptime(a) : comptime_string, comptime(b) : comptime_string, comptime(c) : comptime_string, comptime(d) : comptime_string, comptime(e) : comptime_string) -> comptime(comptime_string))(
262
+ __ts_s5 :: (fn(comptime(a) : comptime_str, comptime(b) : comptime_str, comptime(c) : comptime_str, comptime(d) : comptime_str, comptime(e) : comptime_str) -> comptime(comptime_str))(
263
263
  (((a + b) + c) + d) + e
264
264
  );
265
265
  __ts_fold_range :: (
266
266
  fn(
267
267
  comptime(n) : usize,
268
- comptime(init) : comptime_string,
269
- comptime(f) : (fn(comptime(acc) : comptime_string, comptime(i) : usize) -> comptime(comptime_string))
270
- ) -> comptime(comptime_string)
268
+ comptime(init) : comptime_str,
269
+ comptime(f) : (fn(comptime(acc) : comptime_str, comptime(i) : usize) -> comptime(comptime_str))
270
+ ) -> comptime(comptime_str)
271
271
  )(
272
272
  cond(
273
273
  (n == usize(0)) => init,
@@ -276,7 +276,7 @@ __ts_fold_range :: (
276
276
  )
277
277
  );
278
278
  // Helper: join string parts with + operator, left-to-right parenthesized
279
- __derive_join_plus :: (fn(comptime(parts) : comptime_string, comptime(new_part) : comptime_string) -> comptime(comptime_string))(
279
+ __derive_join_plus :: (fn(comptime(parts) : comptime_str, comptime(new_part) : comptime_str) -> comptime(comptime_str))(
280
280
  cond(
281
281
  (parts == "") => new_part,
282
282
  true => __ts_s5("(", parts, " + ", new_part, ")")
@@ -304,7 +304,7 @@ __derive_tostring :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comp
304
304
  body :: __ts_fold_range(
305
305
  fc,
306
306
  __ts_s3("String.from(\"", type_name, "(\")"),
307
- (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
307
+ (fn(comptime(a) : comptime_str, comptime(fi) : usize) -> comptime(comptime_str))({
308
308
  fname :: fields.get(fi).name;
309
309
  with_sep :: cond(
310
310
  (fi == 0) => a,
@@ -330,7 +330,7 @@ __derive_tostring :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comp
330
330
  ts_branches :: __ts_fold_range(
331
331
  vc,
332
332
  "",
333
- (fn(comptime(acc) : comptime_string, comptime(vi) : usize) -> comptime(comptime_string))({
333
+ (fn(comptime(acc) : comptime_str, comptime(vi) : usize) -> comptime(comptime_str))({
334
334
  v :: variants.get(vi);
335
335
  branch :: cond(
336
336
  (v.fields.len() == 0) =>
@@ -339,7 +339,7 @@ __derive_tostring :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comp
339
339
  bindings :: __ts_fold_range(
340
340
  v.fields.len(),
341
341
  "",
342
- (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
342
+ (fn(comptime(a) : comptime_str, comptime(fi) : usize) -> comptime(comptime_str))({
343
343
  fname :: v.fields.get(fi).name;
344
344
  cond(
345
345
  (a == "") => __ts_s2("__v_", fname),
@@ -350,7 +350,7 @@ __derive_tostring :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comp
350
350
  body :: __ts_fold_range(
351
351
  v.fields.len(),
352
352
  __ts_s5("String.from(\"", type_name, ".", v.name, "(\")"),
353
- (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
353
+ (fn(comptime(a) : comptime_str, comptime(fi) : usize) -> comptime(comptime_str))({
354
354
  fname :: v.fields.get(fi).name;
355
355
  with_sep :: cond(
356
356
  (fi == 0) => a,
@@ -248,7 +248,7 @@ fetch_with :: (
248
248
  )(
249
249
  io.async((e) => {
250
250
  // Parse URL
251
- url := Url.parse(url_str.as_str(), e.exn);
251
+ url := Url.parse(url_str, e.exn);
252
252
  // Validate scheme
253
253
  scheme := url.scheme();
254
254
  is_http := (scheme == `http`);
package/std/imm/list.yo CHANGED
@@ -17,6 +17,7 @@
17
17
  //! ```
18
18
  pragma(Pragma.AllowUnsafe);
19
19
  { GlobalAllocator } :: import("../allocator.yo");
20
+ { ArrayList } :: import("../collections/array_list.yo");
20
21
  { malloc, free } :: GlobalAllocator;
21
22
  { memcpy } :: import("../libc/string.yo");
22
23
  /// Internal cons cell — atomic object for thread-safe structural sharing.
@@ -197,12 +198,12 @@ impl(
197
198
  false
198
199
  }),
199
200
  /// Build a list from a slice. O(n).
200
- from_slice : (fn(s : Slice(T)) -> Self)({
201
+ from_list : (fn(l : ArrayList(T)) -> Self)({
201
202
  (result : Self) = Self.new();
202
- (i : usize) = s.len();
203
+ (i : usize) = l.len();
203
204
  while(i > usize(0), {
204
205
  i = (i - usize(1));
205
- result = result.prepend(s(i));
206
+ result = result.prepend(match(l.get(i),.Some(__e) => __e,.None => panic("from_list: index out of bounds")));
206
207
  });
207
208
  result
208
209
  })
package/std/imm/map.yo CHANGED
@@ -19,6 +19,7 @@
19
19
  //! ```
20
20
  pragma(Pragma.AllowUnsafe);
21
21
  { GlobalAllocator } :: import("../allocator.yo");
22
+ { ArrayList } :: import("../collections/array_list.yo");
22
23
  { malloc, free } :: GlobalAllocator;
23
24
  /// Number of bits per HAMT level.
24
25
  BITS :: usize(5);
@@ -948,12 +949,12 @@ impl(
948
949
  result
949
950
  }),
950
951
  /// Create a map from a slice of key-value pairs.
951
- from_entries : (fn(pairs : Slice(Pair(K, V))) -> Self)({
952
+ from_entries : (fn(pairs : ArrayList(Pair(K, V))) -> Self)({
952
953
  (result : Self) = Self.new();
953
954
  i := usize(0);
954
955
  plen := pairs.len();
955
956
  while(i < plen, i = (i + usize(1)), {
956
- p := (pairs.ptr() &+ i).*;
957
+ p := match(pairs.get(i),.Some(__e) => __e,.None => panic("from_entries: index out of bounds"));
957
958
  result = result.insert(p.key, p.value);
958
959
  });
959
960
  result
package/std/imm/set.yo CHANGED
@@ -19,6 +19,7 @@
19
19
  //! ```
20
20
  pragma(Pragma.AllowUnsafe);
21
21
  { Map } :: import("./map.yo");
22
+ { ArrayList } :: import("../collections/array_list.yo");
22
23
  { List } :: import("./list.yo");
23
24
  /// Persistent immutable hash set backed by a HAMT.
24
25
  ///
@@ -152,12 +153,12 @@ impl(
152
153
  self._inner.keys()
153
154
  ),
154
155
  /// Create a set from a slice of elements.
155
- from_slice : (fn(s : Slice(T)) -> Self)({
156
+ from_list : (fn(l : ArrayList(T)) -> Self)({
156
157
  (result : Self) = Self.new();
157
158
  i := usize(0);
158
- slen := s.len();
159
+ slen := l.len();
159
160
  while(i < slen, i = (i + usize(1)), {
160
- result = result.insert((s.ptr() &+ i).*);
161
+ result = result.insert(match(l.get(i),.Some(__e) => __e,.None => panic("from_list: index out of bounds")));
161
162
  });
162
163
  result
163
164
  })
@@ -19,6 +19,7 @@
19
19
  //! ```
20
20
  pragma(Pragma.AllowUnsafe);
21
21
  { List } :: import("./list.yo");
22
+ { ArrayList } :: import("../collections/array_list.yo");
22
23
  { Pair } :: import("./map.yo");
23
24
  /// Color of a red-black tree node.
24
25
  Color :: enum(Red, Black);
@@ -614,12 +615,12 @@ impl(
614
615
  _collect_values(K, V, self._root, List(V).new())
615
616
  ),
616
617
  /// Create a sorted map from a slice of key-value pairs.
617
- from_entries : (fn(pairs : Slice(Pair(K, V))) -> Self)({
618
+ from_entries : (fn(pairs : ArrayList(Pair(K, V))) -> Self)({
618
619
  (result : Self) = Self.new();
619
620
  i := usize(0);
620
621
  plen := pairs.len();
621
622
  while(i < plen, i = (i + usize(1)), {
622
- p := (pairs.ptr() &+ i).*;
623
+ p := match(pairs.get(i),.Some(__e) => __e,.None => panic("from_entries: index out of bounds"));
623
624
  result = result.insert(p.key, p.value);
624
625
  });
625
626
  result
@@ -19,6 +19,7 @@
19
19
  //! ```
20
20
  pragma(Pragma.AllowUnsafe);
21
21
  { SortedMap } :: import("./sorted_map.yo");
22
+ { ArrayList } :: import("../collections/array_list.yo");
22
23
  { List } :: import("./list.yo");
23
24
  /// Persistent immutable sorted set backed by a left-leaning red-black tree.
24
25
  SortedSet :: (fn(comptime(T) : Type, where(T <: (Eq(T), Ord(T), Send))) -> comptime(Type))(
@@ -174,12 +175,12 @@ impl(
174
175
  result
175
176
  }),
176
177
  /// Create a sorted set from a slice of elements.
177
- from_slice : (fn(s : Slice(T)) -> Self)({
178
+ from_list : (fn(l : ArrayList(T)) -> Self)({
178
179
  (result : Self) = Self.new();
179
180
  i := usize(0);
180
- slen := s.len();
181
+ slen := l.len();
181
182
  while(i < slen, i = (i + usize(1)), {
182
- result = result.insert((s.ptr() &+ i).*);
183
+ result = result.insert(match(l.get(i),.Some(__e) => __e,.None => panic("from_list: index out of bounds")));
183
184
  });
184
185
  result
185
186
  })
package/std/imm/string.yo CHANGED
@@ -4,6 +4,7 @@
4
4
  //! All "modification" operations return a new string; the original is unchanged.
5
5
  pragma(Pragma.AllowUnsafe);
6
6
  { GlobalAllocator } :: import("../allocator.yo");
7
+ { ArrayList } :: import("../collections/array_list.yo");
7
8
  { malloc, free } :: GlobalAllocator;
8
9
  { memcpy, memcmp } :: import("../libc/string.yo");
9
10
  { rune } :: import("../string/rune.yo");
@@ -68,8 +69,8 @@ impl(
68
69
  return(Self(_ptr :.None, _len : usize(0), _capacity : usize(0)));
69
70
  });
70
71
  ptr := _alloc_bytes(slen);
71
- (as_str : str) = s.as_str();
72
- unsafe(memcpy(*(void)(ptr), *(void)(as_str.ptr()), slen));
72
+ rb := s.raw_bytes();
73
+ unsafe(memcpy(*(void)(ptr), *(void)(rb.ptr), slen));
73
74
  return(Self(_ptr :.Some(ptr), _len : slen, _capacity : slen));
74
75
  }),
75
76
  /// Byte length of the string.
@@ -722,9 +723,15 @@ impl(
722
723
  impl(
723
724
  String,
724
725
  ToString(
725
- to_string : (fn(ref(self) : Self) -> std_string.String)(
726
- std_string.String.from(self.as_str())
727
- )
726
+ to_string : (fn(ref(self) : Self) -> std_string.String)({
727
+ bytes := ArrayList(u8).new();
728
+ match(
729
+ self._ptr,
730
+ .None => (),
731
+ .Some(p) => bytes.extend_from_ptr(p, self._len)
732
+ );
733
+ std_string.String.from_bytes(bytes)
734
+ })
728
735
  )
729
736
  );
730
737
  export(String);
package/std/imm/vec.yo CHANGED
@@ -18,6 +18,7 @@
18
18
  //! ```
19
19
  pragma(Pragma.AllowUnsafe);
20
20
  { GlobalAllocator } :: import("../allocator.yo");
21
+ { ArrayList } :: import("../collections/array_list.yo");
21
22
  { malloc, free } :: GlobalAllocator;
22
23
  /// Persistent immutable vector.
23
24
  ///
@@ -412,15 +413,19 @@ impl(
412
413
  Vec(V)(_ptr : new_ptr, _len : min_len, _cap : min_len)
413
414
  }),
414
415
  /// Create a vector from a slice, copying all elements.
415
- from_slice : (fn(s : Slice(T)) -> Self)({
416
- slen := s.len();
416
+ from_list : (fn(l : ArrayList(T)) -> Self)({
417
+ slen := l.len();
417
418
  cap := cond(
418
419
  (slen > usize(0)) => slen,
419
420
  true => usize(4)
420
421
  );
421
422
  new_ptr := Self._raw_alloc(cap);
422
423
  if(slen > usize(0), {
423
- Self._copy_elems(new_ptr, s.ptr(), usize(0), usize(0), slen);
424
+ match(
425
+ l.ptr(),
426
+ .Some(src) => Self._copy_elems(new_ptr, src, usize(0), usize(0), slen),
427
+ .None => ()
428
+ );
424
429
  });
425
430
  Self(_ptr : new_ptr, _len : slen, _cap : cap)
426
431
  })