@shd101wyy/yo 0.1.6 → 0.1.8

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 (35) hide show
  1. package/LICENSE.md +2 -2
  2. package/README.md +7 -6
  3. package/out/cjs/index.cjs +688 -638
  4. package/out/cjs/yo-cli.cjs +698 -648
  5. package/out/esm/index.mjs +628 -578
  6. package/out/types/src/build-runner.d.ts +1 -1
  7. package/out/types/src/codegen/async/runtime-io-common.d.ts +2 -1
  8. package/out/types/src/codegen/async/runtime.d.ts +5 -1
  9. package/out/types/src/codegen/functions/collection.d.ts +1 -1
  10. package/out/types/src/codegen/utils/index.d.ts +3 -0
  11. package/out/types/src/evaluator/builtins/comptime-index-fns.d.ts +17 -0
  12. package/out/types/src/evaluator/calls/index-trait.d.ts +17 -0
  13. package/out/types/src/evaluator/context.d.ts +18 -14
  14. package/out/types/src/evaluator/index.d.ts +3 -1
  15. package/out/types/src/evaluator/trait-checking.d.ts +1 -0
  16. package/out/types/src/evaluator/values/anonymous-module.d.ts +3 -2
  17. package/out/types/src/expr.d.ts +20 -1
  18. package/out/types/src/module-manager.d.ts +1 -0
  19. package/out/types/src/value.d.ts +2 -0
  20. package/out/types/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +1 -1
  22. package/std/collections/array_list.yo +17 -61
  23. package/std/collections/btree_map.yo +13 -3
  24. package/std/collections/deque.yo +10 -0
  25. package/std/collections/hash_map.yo +15 -0
  26. package/std/collections/priority_queue.yo +5 -5
  27. package/std/encoding/punycode.yo +2 -2
  28. package/std/encoding/toml.yo +1 -1
  29. package/std/prelude.yo +818 -205
  30. package/std/process.yo +1 -1
  31. package/std/regex/compiler.yo +11 -11
  32. package/std/regex/index.yo +2 -4
  33. package/std/regex/vm.yo +41 -21
  34. package/std/string/string.yo +39 -5
  35. package/out/types/src/evaluator/calls/array.d.ts +0 -14
package/std/process.yo CHANGED
@@ -66,7 +66,7 @@ extern "Yo",
66
66
  // The first element is the program name
67
67
  // Example: ["./program", "arg1", "arg2"]
68
68
  raw_args :: (fn() -> [*(u8)]) {
69
- return __yo_args(:);
69
+ return __yo_args;
70
70
  };
71
71
  export raw_args;
72
72
 
@@ -183,14 +183,14 @@ impl(NfaCompiler,
183
183
  right := node.children.get(usize(1)).unwrap();
184
184
  split_pc := self._emit(Instr.split_instr(usize(0), usize(0)));
185
185
  left_start := self._current_pc();
186
- self._program.instructions.set(split_pc, Instr.split_instr(left_start, usize(0)));
186
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(left_start, usize(0));
187
187
  recur(self, left);
188
188
  jump_pc := self._emit(Instr.jump_instr(usize(0)));
189
189
  right_start := self._current_pc();
190
- self._program.instructions.set(split_pc, Instr.split_instr(left_start, right_start));
190
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(left_start, right_start);
191
191
  recur(self, right);
192
192
  end_pc := self._current_pc();
193
- self._program.instructions.set(jump_pc, Instr.jump_instr(end_pc));
193
+ &(self._program.instructions(jump_pc)).* = Instr.jump_instr(end_pc);
194
194
  },
195
195
  .Quantifier => {
196
196
  child := node.children.get(usize(0)).unwrap();
@@ -217,10 +217,10 @@ impl(NfaCompiler,
217
217
  l3 := self._current_pc();
218
218
  cond(
219
219
  greedy => {
220
- self._program.instructions.set(split_pc, Instr.split_instr(l2, l3));
220
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(l2, l3);
221
221
  },
222
222
  true => {
223
- self._program.instructions.set(split_pc, Instr.split_instr(l3, l2));
223
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(l3, l2);
224
224
  }
225
225
  );
226
226
  },
@@ -230,10 +230,10 @@ impl(NfaCompiler,
230
230
  l2 := self._current_pc();
231
231
  cond(
232
232
  greedy => {
233
- self._program.instructions.set(split_pc, Instr.split_instr(last_body_start, l2));
233
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(last_body_start, l2);
234
234
  },
235
235
  true => {
236
- self._program.instructions.set(split_pc, Instr.split_instr(l2, last_body_start));
236
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(l2, last_body_start);
237
237
  }
238
238
  );
239
239
  },
@@ -248,10 +248,10 @@ impl(NfaCompiler,
248
248
  after := self._current_pc();
249
249
  cond(
250
250
  greedy => {
251
- self._program.instructions.set(split_pc, Instr.split_instr(body_start, after));
251
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(body_start, after);
252
252
  },
253
253
  true => {
254
- self._program.instructions.set(split_pc, Instr.split_instr(after, body_start));
254
+ &(self._program.instructions(split_pc)).* = Instr.split_instr(after, body_start);
255
255
  }
256
256
  );
257
257
  };
@@ -282,7 +282,7 @@ impl(NfaCompiler,
282
282
  recur(self, child);
283
283
  self._emit(Instr.match_instr());
284
284
  sub_end := self._current_pc();
285
- self._program.instructions.set(la_pc, Instr.lookahead_instr(sub_start, sub_end, positive));
285
+ &(self._program.instructions(la_pc)).* = Instr.lookahead_instr(sub_start, sub_end, positive);
286
286
  },
287
287
  .Lookbehind => {
288
288
  child := node.children.get(usize(0)).unwrap();
@@ -292,7 +292,7 @@ impl(NfaCompiler,
292
292
  recur(self, child);
293
293
  self._emit(Instr.match_instr());
294
294
  sub_end := self._current_pc();
295
- self._program.instructions.set(lb_pc, Instr.lookbehind_instr(sub_start, sub_end, positive));
295
+ &(self._program.instructions(lb_pc)).* = Instr.lookbehind_instr(sub_start, sub_end, positive);
296
296
  }
297
297
  );
298
298
  })
@@ -186,11 +186,11 @@ impl(Regex,
186
186
  exec : (fn(self : Self, input : String) -> Option(RegexMatch))({
187
187
  bytes := input.as_bytes();
188
188
  input_len := bytes.len();
189
+ vm := NfaVm.new(self._program, self._flags, input);
189
190
 
190
191
  // Sticky flag: only try matching at position 0
191
192
  cond(
192
193
  self._flags.sticky => {
193
- vm := NfaVm.new(self._program, self._flags, input);
194
194
  result := vm.exec_at(usize(0));
195
195
  cond(
196
196
  result.matched => .Some(self._build_match(result.slots, input)),
@@ -205,7 +205,6 @@ impl(Regex,
205
205
  );
206
206
 
207
207
  while (byte_pos <= input_len), {
208
- vm := NfaVm.new(self._program, self._flags, input);
209
208
  result := vm.exec_at(byte_pos);
210
209
 
211
210
  cond(
@@ -244,13 +243,13 @@ impl(Regex,
244
243
  matches := ArrayList(RegexMatch).new();
245
244
  bytes := input.as_bytes();
246
245
  input_len := bytes.len();
246
+ vm := NfaVm.new(self._program, self._flags, input);
247
247
 
248
248
  cond(
249
249
  self._flags.sticky => {
250
250
  // Sticky: only try at position 0, then at end of each match
251
251
  (byte_pos : usize) = usize(0);
252
252
  while (byte_pos <= input_len), {
253
- vm := NfaVm.new(self._program, self._flags, input);
254
253
  result := vm.exec_at(byte_pos);
255
254
 
256
255
  cond(
@@ -293,7 +292,6 @@ impl(Regex,
293
292
  );
294
293
 
295
294
  while (byte_pos <= input_len), {
296
- vm := NfaVm.new(self._program, self._flags, input);
297
295
  result := vm.exec_at(byte_pos);
298
296
 
299
297
  cond(
package/std/regex/vm.yo CHANGED
@@ -44,15 +44,6 @@ VmMatch :: struct(
44
44
  slots : ArrayList(usize)
45
45
  );
46
46
 
47
- // The NFA virtual machine
48
- NfaVm :: object(
49
- _program : NfaProgram,
50
- _flags : RegexFlags,
51
- _input : String,
52
- _bytes : ArrayList(u8),
53
- _n_slots : usize
54
- );
55
-
56
47
  // Helper struct for decoded characters
57
48
  DecodedChar :: struct(
58
49
  codepoint : u32,
@@ -65,16 +56,34 @@ DeferredThread :: struct(
65
56
  thread : NfaThread
66
57
  );
67
58
 
59
+ // The NFA virtual machine
60
+ NfaVm :: object(
61
+ _program : NfaProgram,
62
+ _flags : RegexFlags,
63
+ _input : String,
64
+ _bytes : ArrayList(u8),
65
+ _n_slots : usize,
66
+ _seen : ArrayList(bool),
67
+ _next_seen : ArrayList(bool)
68
+ );
69
+
68
70
  // Block 1: Constructor and leaf helpers (no method dependencies)
69
71
  impl(NfaVm,
70
72
  new : (fn(program : NfaProgram, flags : RegexFlags, input : String) -> Self)({
71
73
  n_slots := ((program.n_groups + usize(1)) * usize(2));
74
+ n_instr := program.instructions.len();
75
+ seen := ArrayList(bool).with_capacity(n_instr);
76
+ seen.resize_with_byte(n_instr, int(0));
77
+ next_seen := ArrayList(bool).with_capacity(n_instr);
78
+ next_seen.resize_with_byte(n_instr, int(0));
72
79
  Self(
73
80
  _program: program,
74
81
  _flags: flags,
75
82
  _input: input,
76
83
  _bytes: input.as_bytes(),
77
- _n_slots: n_slots
84
+ _n_slots: n_slots,
85
+ _seen: seen,
86
+ _next_seen: next_seen
78
87
  )
79
88
  }),
80
89
 
@@ -231,14 +240,14 @@ impl(NfaVm,
231
240
  );
232
241
 
233
242
  // Already checked bounds above: thread.pc < instructions.len()
234
- is_seen := seen.*.get_unchecked(thread.pc);
243
+ is_seen := (seen.*)(thread.pc);
235
244
  cond(
236
245
  is_seen => { return (); },
237
246
  true => ()
238
247
  );
239
- seen.*.set_unchecked(thread.pc, true);
248
+ &((seen.*)(thread.pc)).* = true;
240
249
 
241
- instr := self._program.instructions.get_unchecked(thread.pc);
250
+ instr := self._program.instructions(thread.pc);
242
251
 
243
252
  match(instr.kind,
244
253
  .Split => {
@@ -254,7 +263,7 @@ impl(NfaVm,
254
263
  .Save => {
255
264
  cond(
256
265
  (instr.slot < thread.slots.len()) => {
257
- thread.slots.set(instr.slot, byte_pos);
266
+ &(thread.slots(instr.slot)).* = byte_pos;
258
267
  },
259
268
  true => ()
260
269
  );
@@ -420,8 +429,11 @@ impl(NfaVm,
420
429
  );
421
430
  };
422
431
 
432
+ // Swap sub_current/sub_next and clear for reuse
433
+ tmp_sub := sub_current;
423
434
  sub_current = sub_next;
424
- sub_next = ArrayList(NfaThread).new();
435
+ sub_next = tmp_sub;
436
+ sub_next.clear();
425
437
  sub_pos = (sub_pos + sub_blen);
426
438
  };
427
439
 
@@ -432,15 +444,16 @@ impl(NfaVm,
432
444
  // Block 5: exec_at (depends on Block 1+2+3+4)
433
445
  impl(NfaVm,
434
446
  exec_at : (fn(self : Self, start_byte : usize) -> VmMatch)({
447
+ // Reuse pre-allocated seen buffers from the VM
435
448
  current := ArrayList(NfaThread).new();
436
449
  next := ArrayList(NfaThread).new();
450
+ seen := self._seen;
451
+ next_seen := self._next_seen;
437
452
  deferred := ArrayList(DeferredThread).new();
438
453
 
439
- seen := ArrayList(bool).with_capacity(self._program.instructions.len());
440
- next_seen := ArrayList(bool).with_capacity(self._program.instructions.len());
441
- // Fill with false (0x00) using memset
442
- seen.resize_with_byte(self._program.instructions.len(), int(0));
443
- next_seen.resize_with_byte(self._program.instructions.len(), int(0));
454
+ // Clear for this execution
455
+ seen.fill_with_byte(int(0));
456
+ next_seen.fill_with_byte(int(0));
444
457
 
445
458
  initial := NfaThread.new(usize(0), self._n_slots);
446
459
  self._add_thread(&(current), initial, start_byte, &(seen));
@@ -701,8 +714,11 @@ impl(NfaVm,
701
714
  );
702
715
  };
703
716
 
717
+ // Swap current/next and clear for reuse
718
+ tmp_c := current;
704
719
  current = next;
705
- next = ArrayList(NfaThread).new();
720
+ next = tmp_c;
721
+ next.clear();
706
722
 
707
723
  cond(
708
724
  at_end => { break; },
@@ -712,6 +728,10 @@ impl(NfaVm,
712
728
  );
713
729
  };
714
730
 
731
+ // Store seen buffers back for reuse in next exec_at call
732
+ self._seen = seen;
733
+ self._next_seen = next_seen;
734
+
715
735
  best_match
716
736
  })
717
737
  );
@@ -384,6 +384,29 @@ impl(String,
384
384
  );
385
385
  }),
386
386
 
387
+ // Clear the string content but keep the allocated buffer for reuse
388
+ clear : (fn(self: *(Self)) -> unit)(
389
+ match(self.*._bytes,
390
+ .Some(al) => al.clear(),
391
+ .None => ()
392
+ )
393
+ ),
394
+
395
+ // Create a deep copy of this string with its own buffer
396
+ clone : (fn(self: Self) -> Self)(
397
+ match(self._bytes,
398
+ .None => Self(_bytes: .None),
399
+ .Some(al) => {
400
+ (new_al : ArrayList(u8)) = ArrayList(u8).with_capacity(al.len());
401
+ match(al.ptr(),
402
+ .Some(p) => new_al.extend_from_ptr(p, al.len()),
403
+ .None => ()
404
+ );
405
+ Self(_bytes: .Some(new_al))
406
+ }
407
+ )
408
+ ),
409
+
387
410
  // Get the number of bytes in the string (not Unicode characters)
388
411
  bytes_len : (fn(self: Self) -> usize)(
389
412
  match(self._bytes, .Some(b) => b.len(), .None => usize(0))
@@ -415,7 +438,7 @@ impl(String,
415
438
  end_byte = byte_index;
416
439
  break;
417
440
  });
418
- (b : u8) = al.get_unchecked(byte_index);
441
+ (b : u8) = al(byte_index);
419
442
  (byte_len : usize) = cond(
420
443
  (b < u8(0x80)) => usize(1),
421
444
  (b < u8(0xE0)) => usize(2),
@@ -1249,14 +1272,14 @@ impl(String,
1249
1272
 
1250
1273
  (start_idx : usize) = usize(0);
1251
1274
  while (start_idx < total_bytes), {
1252
- (b : u8) = al.get_unchecked(start_idx);
1275
+ (b : u8) = al(start_idx);
1253
1276
  if(!(Self._is_whitespace_byte(b)), { break; });
1254
1277
  start_idx = (start_idx + usize(1));
1255
1278
  };
1256
1279
 
1257
1280
  (end_idx : usize) = total_bytes;
1258
1281
  while (end_idx > start_idx), {
1259
- (b : u8) = al.get_unchecked((end_idx - usize(1)));
1282
+ (b : u8) = al((end_idx - usize(1)));
1260
1283
  if(!(Self._is_whitespace_byte(b)), { break; });
1261
1284
  end_idx = (end_idx - usize(1));
1262
1285
  };
@@ -1370,8 +1393,9 @@ impl(String,
1370
1393
  )
1371
1394
  );
1372
1395
 
1373
- impl(String, Add(String, String)(
1374
- (+) : (fn(self: Self, other: Self) -> Self)({
1396
+ impl(String, Add(String)(
1397
+ Output : String,
1398
+ (+) : (fn(self: Self, other: Self) -> Self.Output)({
1375
1399
  return self.concat(other);
1376
1400
  })
1377
1401
  ));
@@ -1886,6 +1910,16 @@ impl(String,
1886
1910
  )
1887
1911
  );
1888
1912
 
1913
+ impl(String, Index(usize)(
1914
+ Output : u8,
1915
+ index : (fn(self: *(Self), idx: usize) -> *(Self.Output))(
1916
+ match(self.*._bytes,
1917
+ .Some(bytes) => &(bytes(idx)),
1918
+ .None => panic("String: index on empty string")
1919
+ )
1920
+ )
1921
+ ));
1922
+
1889
1923
  export
1890
1924
  String,
1891
1925
  StringError,
@@ -1,14 +0,0 @@
1
- import type { Environment } from "../../env";
2
- import { type Expr, type FnCallExpr } from "../../expr";
3
- import type { ArrayType, SliceType } from "../../types/definitions";
4
- import { type ArrayValue, type SliceValue } from "../../value";
5
- import type { ArrayCallResult, EvaluatorContext } from "../context";
6
- export declare function tryToCallArrayWithArguments({ expr, arrayType, arrayValue, sliceValue, argExprs, callerEnv, context, }: {
7
- expr: FnCallExpr;
8
- arrayType: ArrayType | SliceType;
9
- arrayValue: ArrayValue | undefined;
10
- sliceValue: SliceValue | undefined;
11
- argExprs: Expr[];
12
- callerEnv: Environment;
13
- context: EvaluatorContext;
14
- }): ArrayCallResult;