@shd101wyy/yo 0.1.4 → 0.1.6
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.
- package/README.md +7 -6
- package/out/cjs/index.cjs +546 -535
- package/out/cjs/yo-cli.cjs +636 -623
- package/out/esm/index.mjs +478 -467
- package/out/types/src/codegen/codegen-c.d.ts +2 -0
- package/out/types/src/codegen/functions/context.d.ts +1 -0
- package/out/types/src/codegen/functions/generation.d.ts +10 -0
- package/out/types/src/codegen/utils/index.d.ts +1 -0
- package/out/types/src/env.d.ts +12 -1
- package/out/types/src/evaluator/builtins/build.d.ts +1 -0
- package/out/types/src/evaluator/context.d.ts +1 -0
- package/out/types/src/evaluator/types/enum.d.ts +1 -1
- package/out/types/src/evaluator/types/synthesizer.d.ts +6 -1
- package/out/types/src/expr.d.ts +2 -0
- package/out/types/src/target.d.ts +1 -0
- package/out/types/src/types/compatibility.d.ts +1 -1
- package/out/types/src/types/creators.d.ts +2 -1
- package/out/types/src/types/definitions.d.ts +11 -0
- package/out/types/src/types/guards.d.ts +2 -1
- package/out/types/src/types/tags.d.ts +2 -1
- package/out/types/src/value.d.ts +2 -1
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/build.yo +2 -1
- package/std/collections/array_list.yo +133 -1
- package/std/encoding/html.yo +283 -0
- package/std/encoding/html_char_utils.yo +36 -0
- package/std/encoding/html_entities.yo +2262 -0
- package/std/encoding/punycode.yo +366 -0
- package/std/fmt/to_string.yo +5 -4
- package/std/glob/index.yo +2 -2
- package/std/libc/wctype.yo +55 -0
- package/std/path.yo +6 -6
- package/std/prelude.yo +193 -7
- package/std/regex/parser.yo +69 -4
- package/std/regex/vm.yo +18 -31
- package/std/string/string.yo +1388 -1337
- package/std/string/unicode.yo +242 -0
package/std/prelude.yo
CHANGED
|
@@ -96,6 +96,8 @@ extern "Yo",
|
|
|
96
96
|
fn(forall(T: Type), slice: Slice(T)) -> usize,
|
|
97
97
|
__yo_slice_new :
|
|
98
98
|
fn(forall(T: Type), ptr: *(T), length: usize) -> Slice(T),
|
|
99
|
+
__yo_slice_ptr :
|
|
100
|
+
fn(forall(T: Type), slice: Slice(T)) -> *(T),
|
|
99
101
|
|
|
100
102
|
// C macro related
|
|
101
103
|
__yo_c_macro_defined : (fn(comptime(name) : comptime_string) -> comptime(bool)),
|
|
@@ -110,13 +112,7 @@ extern "Yo",
|
|
|
110
112
|
;
|
|
111
113
|
export __yo_as;
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
cond(
|
|
115
|
-
flag => (),
|
|
116
|
-
true => panic(msg)
|
|
117
|
-
)
|
|
118
|
-
;
|
|
119
|
-
export assert;
|
|
115
|
+
|
|
120
116
|
|
|
121
117
|
// unsafe module
|
|
122
118
|
unsafe :: impl {
|
|
@@ -3202,6 +3198,9 @@ impl(forall(T : Type), Slice(T),
|
|
|
3202
3198
|
),
|
|
3203
3199
|
len : (fn(self : Self) -> usize)(
|
|
3204
3200
|
__yo_slice_len(self)
|
|
3201
|
+
),
|
|
3202
|
+
ptr : (fn(self : Self) -> *(T))(
|
|
3203
|
+
__yo_slice_ptr(self)
|
|
3205
3204
|
)
|
|
3206
3205
|
);
|
|
3207
3206
|
|
|
@@ -3215,6 +3214,9 @@ impl(str,
|
|
|
3215
3214
|
),
|
|
3216
3215
|
len : (fn(self : Self) -> usize)(
|
|
3217
3216
|
__yo_slice_len(self.bytes)
|
|
3217
|
+
),
|
|
3218
|
+
ptr : (fn(self : Self) -> *(u8))(
|
|
3219
|
+
__yo_slice_ptr(self.bytes)
|
|
3218
3220
|
)
|
|
3219
3221
|
);
|
|
3220
3222
|
|
|
@@ -3271,6 +3273,14 @@ impl(str, Ord(str)(
|
|
|
3271
3273
|
|
|
3272
3274
|
export str;
|
|
3273
3275
|
|
|
3276
|
+
assert :: (fn(flag : bool, (msg : str) ?= "Assertion failed.") -> unit)
|
|
3277
|
+
cond(
|
|
3278
|
+
flag => (),
|
|
3279
|
+
true => panic(msg)
|
|
3280
|
+
)
|
|
3281
|
+
;
|
|
3282
|
+
export assert;
|
|
3283
|
+
|
|
3274
3284
|
|
|
3275
3285
|
/// ComptimeList
|
|
3276
3286
|
impl(forall(T : Type), ComptimeList(T), Comptime());
|
|
@@ -3419,6 +3429,85 @@ impl(forall(T : Type), Option(T),
|
|
|
3419
3429
|
)
|
|
3420
3430
|
);
|
|
3421
3431
|
|
|
3432
|
+
// Functional combinators for Option(T)
|
|
3433
|
+
impl(forall(T : Type), Option(T),
|
|
3434
|
+
map : (fn(forall(B : Type), self : Self, f : Impl(Fn(a : T) -> B)) -> Option(B))(
|
|
3435
|
+
match(self,
|
|
3436
|
+
.Some(value) => Option(B).Some(f(value)),
|
|
3437
|
+
.None => Option(B).None
|
|
3438
|
+
)
|
|
3439
|
+
),
|
|
3440
|
+
|
|
3441
|
+
and_then : (fn(forall(B : Type), self : Self, f : Impl(Fn(a : T) -> Option(B))) -> Option(B))(
|
|
3442
|
+
match(self,
|
|
3443
|
+
.Some(value) => f(value),
|
|
3444
|
+
.None => Option(B).None
|
|
3445
|
+
)
|
|
3446
|
+
),
|
|
3447
|
+
|
|
3448
|
+
filter : (fn(self : Self, predicate : Impl(Fn(a : T) -> bool)) -> Option(T))(
|
|
3449
|
+
match(self,
|
|
3450
|
+
.Some(value) => cond(
|
|
3451
|
+
predicate(value) => Option(T).Some(value),
|
|
3452
|
+
true => Option(T).None
|
|
3453
|
+
),
|
|
3454
|
+
.None => Option(T).None
|
|
3455
|
+
)
|
|
3456
|
+
),
|
|
3457
|
+
|
|
3458
|
+
or_else : (fn(self : Self, f : Impl(Fn() -> Option(T))) -> Option(T))(
|
|
3459
|
+
match(self,
|
|
3460
|
+
.Some(value) => Option(T).Some(value),
|
|
3461
|
+
.None => f()
|
|
3462
|
+
)
|
|
3463
|
+
),
|
|
3464
|
+
|
|
3465
|
+
map_or : (fn(forall(B : Type), self : Self, default_val : B, f : Impl(Fn(a : T) -> B)) -> B)(
|
|
3466
|
+
match(self,
|
|
3467
|
+
.Some(value) => f(value),
|
|
3468
|
+
.None => default_val
|
|
3469
|
+
)
|
|
3470
|
+
),
|
|
3471
|
+
|
|
3472
|
+
map_or_else : (fn(forall(B : Type), self : Self, default_fn : Impl(Fn() -> B), f : Impl(Fn(a : T) -> B)) -> B)(
|
|
3473
|
+
match(self,
|
|
3474
|
+
.Some(value) => f(value),
|
|
3475
|
+
.None => default_fn()
|
|
3476
|
+
)
|
|
3477
|
+
),
|
|
3478
|
+
|
|
3479
|
+
and : (fn(forall(B : Type), self : Self, optb : Option(B)) -> Option(B))(
|
|
3480
|
+
match(self,
|
|
3481
|
+
.Some(_) => optb,
|
|
3482
|
+
.None => Option(B).None
|
|
3483
|
+
)
|
|
3484
|
+
),
|
|
3485
|
+
|
|
3486
|
+
or : (fn(self : Self, optb : Option(T)) -> Option(T))(
|
|
3487
|
+
match(self,
|
|
3488
|
+
.Some(value) => Option(T).Some(value),
|
|
3489
|
+
.None => optb
|
|
3490
|
+
)
|
|
3491
|
+
),
|
|
3492
|
+
|
|
3493
|
+
unwrap_or_else : (fn(self : Self, f : Impl(Fn() -> T)) -> T)(
|
|
3494
|
+
match(self,
|
|
3495
|
+
.Some(value) => value,
|
|
3496
|
+
.None => f()
|
|
3497
|
+
)
|
|
3498
|
+
)
|
|
3499
|
+
);
|
|
3500
|
+
|
|
3501
|
+
// Flatten for nested Option
|
|
3502
|
+
impl(forall(T : Type), Option(Option(T)),
|
|
3503
|
+
flatten : (fn(self : Self) -> Option(T))(
|
|
3504
|
+
match(self,
|
|
3505
|
+
.Some(inner) => inner,
|
|
3506
|
+
.None => Option(T).None
|
|
3507
|
+
)
|
|
3508
|
+
)
|
|
3509
|
+
);
|
|
3510
|
+
|
|
3422
3511
|
// Option(T) implements Comptime when T implements Comptime
|
|
3423
3512
|
impl(forall(T : Type), where(T <: Comptime), Option(T), Comptime());
|
|
3424
3513
|
|
|
@@ -3503,6 +3592,103 @@ impl(forall(OkType : Type, ErrorType : Type), Result(OkType, ErrorType),
|
|
|
3503
3592
|
)
|
|
3504
3593
|
);
|
|
3505
3594
|
|
|
3595
|
+
// Functional combinators for Result(OkType, ErrorType)
|
|
3596
|
+
impl(forall(OkType : Type, ErrorType : Type), Result(OkType, ErrorType),
|
|
3597
|
+
map : (fn(forall(B : Type), self : Self, f : Impl(Fn(a : OkType) -> B)) -> Result(B, ErrorType))(
|
|
3598
|
+
match(self,
|
|
3599
|
+
.Ok(value) => Result(B, ErrorType).Ok(f(value)),
|
|
3600
|
+
.Err(error) => Result(B, ErrorType).Err(error)
|
|
3601
|
+
)
|
|
3602
|
+
),
|
|
3603
|
+
|
|
3604
|
+
map_err : (fn(forall(F : Type), self : Self, f : Impl(Fn(a : ErrorType) -> F)) -> Result(OkType, F))(
|
|
3605
|
+
match(self,
|
|
3606
|
+
.Ok(value) => Result(OkType, F).Ok(value),
|
|
3607
|
+
.Err(error) => Result(OkType, F).Err(f(error))
|
|
3608
|
+
)
|
|
3609
|
+
),
|
|
3610
|
+
|
|
3611
|
+
and_then : (fn(forall(B : Type), self : Self, f : Impl(Fn(a : OkType) -> Result(B, ErrorType))) -> Result(B, ErrorType))(
|
|
3612
|
+
match(self,
|
|
3613
|
+
.Ok(value) => f(value),
|
|
3614
|
+
.Err(error) => Result(B, ErrorType).Err(error)
|
|
3615
|
+
)
|
|
3616
|
+
),
|
|
3617
|
+
|
|
3618
|
+
or_else : (fn(forall(F : Type), self : Self, f : Impl(Fn(a : ErrorType) -> Result(OkType, F))) -> Result(OkType, F))(
|
|
3619
|
+
match(self,
|
|
3620
|
+
.Ok(value) => Result(OkType, F).Ok(value),
|
|
3621
|
+
.Err(error) => f(error)
|
|
3622
|
+
)
|
|
3623
|
+
),
|
|
3624
|
+
|
|
3625
|
+
and : (fn(forall(B : Type), self : Self, res : Result(B, ErrorType)) -> Result(B, ErrorType))(
|
|
3626
|
+
match(self,
|
|
3627
|
+
.Ok(_) => res,
|
|
3628
|
+
.Err(error) => Result(B, ErrorType).Err(error)
|
|
3629
|
+
)
|
|
3630
|
+
),
|
|
3631
|
+
|
|
3632
|
+
or : (fn(forall(F : Type), self : Self, res : Result(OkType, F)) -> Result(OkType, F))(
|
|
3633
|
+
match(self,
|
|
3634
|
+
.Ok(value) => Result(OkType, F).Ok(value),
|
|
3635
|
+
.Err(_) => res
|
|
3636
|
+
)
|
|
3637
|
+
),
|
|
3638
|
+
|
|
3639
|
+
ok : (fn(self : Self) -> Option(OkType))(
|
|
3640
|
+
match(self,
|
|
3641
|
+
.Ok(value) => Option(OkType).Some(value),
|
|
3642
|
+
.Err(_) => Option(OkType).None
|
|
3643
|
+
)
|
|
3644
|
+
),
|
|
3645
|
+
|
|
3646
|
+
err : (fn(self : Self) -> Option(ErrorType))(
|
|
3647
|
+
match(self,
|
|
3648
|
+
.Ok(_) => Option(ErrorType).None,
|
|
3649
|
+
.Err(error) => Option(ErrorType).Some(error)
|
|
3650
|
+
)
|
|
3651
|
+
),
|
|
3652
|
+
|
|
3653
|
+
map_or : (fn(forall(B : Type), self : Self, default_val : B, f : Impl(Fn(a : OkType) -> B)) -> B)(
|
|
3654
|
+
match(self,
|
|
3655
|
+
.Ok(value) => f(value),
|
|
3656
|
+
.Err(_) => default_val
|
|
3657
|
+
)
|
|
3658
|
+
),
|
|
3659
|
+
|
|
3660
|
+
map_or_else : (fn(forall(B : Type), self : Self, default_fn : Impl(Fn(a : ErrorType) -> B), f : Impl(Fn(a : OkType) -> B)) -> B)(
|
|
3661
|
+
match(self,
|
|
3662
|
+
.Ok(value) => f(value),
|
|
3663
|
+
.Err(error) => default_fn(error)
|
|
3664
|
+
)
|
|
3665
|
+
),
|
|
3666
|
+
|
|
3667
|
+
unwrap_or_else : (fn(self : Self, f : Impl(Fn(a : ErrorType) -> OkType)) -> OkType)(
|
|
3668
|
+
match(self,
|
|
3669
|
+
.Ok(value) => value,
|
|
3670
|
+
.Err(error) => f(error)
|
|
3671
|
+
)
|
|
3672
|
+
)
|
|
3673
|
+
);
|
|
3674
|
+
|
|
3675
|
+
// Option -> Result conversion (defined after Result)
|
|
3676
|
+
impl(forall(T : Type), Option(T),
|
|
3677
|
+
ok_or : (fn(forall(E : Type), self : Self, err : E) -> Result(T, E))(
|
|
3678
|
+
match(self,
|
|
3679
|
+
.Some(value) => Result(T, E).Ok(value),
|
|
3680
|
+
.None => Result(T, E).Err(err)
|
|
3681
|
+
)
|
|
3682
|
+
),
|
|
3683
|
+
|
|
3684
|
+
ok_or_else : (fn(forall(E : Type), self : Self, err_fn : Impl(Fn() -> E)) -> Result(T, E))(
|
|
3685
|
+
match(self,
|
|
3686
|
+
.Some(value) => Result(T, E).Ok(value),
|
|
3687
|
+
.None => Result(T, E).Err(err_fn())
|
|
3688
|
+
)
|
|
3689
|
+
)
|
|
3690
|
+
);
|
|
3691
|
+
|
|
3506
3692
|
// Result(OkType, ErrorType) implements Comptime when both types implement Comptime
|
|
3507
3693
|
impl(forall(OkType : Type, ErrorType : Type), where(OkType <: Comptime, ErrorType <: Comptime), Result(OkType, ErrorType), Comptime());
|
|
3508
3694
|
|
package/std/regex/parser.yo
CHANGED
|
@@ -189,6 +189,27 @@ impl(RegexParser,
|
|
|
189
189
|
r
|
|
190
190
|
}),
|
|
191
191
|
|
|
192
|
+
// Parse \xHH hex escape — reads exactly 2 hex digits and returns the codepoint.
|
|
193
|
+
_parse_hex_byte : (fn(self : Self) -> Option(u32))({
|
|
194
|
+
if(((self._pos + usize(2)) > self._bytes.len()), { return .None; });
|
|
195
|
+
(h1 : u8) = self._bytes.get(self._pos).unwrap();
|
|
196
|
+
(h2 : u8) = self._bytes.get((self._pos + usize(1))).unwrap();
|
|
197
|
+
(v1 : i32) = cond(
|
|
198
|
+
((h1 >= u8(48)) && (h1 <= u8(57))) => (i32(h1) - i32(48)),
|
|
199
|
+
((h1 >= u8(65)) && (h1 <= u8(70))) => ((i32(h1) - i32(65)) + i32(10)),
|
|
200
|
+
((h1 >= u8(97)) && (h1 <= u8(102))) => ((i32(h1) - i32(97)) + i32(10)),
|
|
201
|
+
true => { return .None; }
|
|
202
|
+
);
|
|
203
|
+
(v2 : i32) = cond(
|
|
204
|
+
((h2 >= u8(48)) && (h2 <= u8(57))) => (i32(h2) - i32(48)),
|
|
205
|
+
((h2 >= u8(65)) && (h2 <= u8(70))) => ((i32(h2) - i32(65)) + i32(10)),
|
|
206
|
+
((h2 >= u8(97)) && (h2 <= u8(102))) => ((i32(h2) - i32(97)) + i32(10)),
|
|
207
|
+
true => { return .None; }
|
|
208
|
+
);
|
|
209
|
+
self._pos = (self._pos + usize(2));
|
|
210
|
+
.Some(u32(((v1 << i32(4)) | v2)))
|
|
211
|
+
}),
|
|
212
|
+
|
|
192
213
|
_parse_class_escape : (fn(self : Self) -> Result(ArrayList(CharRange), String))({
|
|
193
214
|
b := self._advance();
|
|
194
215
|
match(b,
|
|
@@ -219,6 +240,14 @@ impl(RegexParser,
|
|
|
219
240
|
r.push(CharRange(low: u32(33), high: u32(0x10FFFF)));
|
|
220
241
|
.Ok(r)
|
|
221
242
|
},
|
|
243
|
+
(ch == u8(120)) => {
|
|
244
|
+
r := ArrayList(CharRange).new();
|
|
245
|
+
match(self._parse_hex_byte(),
|
|
246
|
+
.Some(v) => r.push(CharRange(low: v, high: v)),
|
|
247
|
+
.None => r.push(CharRange(low: u32(ch), high: u32(ch)))
|
|
248
|
+
);
|
|
249
|
+
.Ok(r)
|
|
250
|
+
},
|
|
222
251
|
true => {
|
|
223
252
|
r := ArrayList(CharRange).new();
|
|
224
253
|
codepoint := self._escape_char_codepoint(ch);
|
|
@@ -246,6 +275,31 @@ impl(RegexParser,
|
|
|
246
275
|
(end_first == u8(93)) => {
|
|
247
276
|
ranges.push(CharRange(low: low, high: low));
|
|
248
277
|
},
|
|
278
|
+
(end_first == u8(92)) => {
|
|
279
|
+
// High end is an escape sequence (e.g. \x20, \0, \n)
|
|
280
|
+
self._pos = (self._pos + usize(1));
|
|
281
|
+
self._pos = (self._pos + usize(1));
|
|
282
|
+
esc := self._parse_class_escape();
|
|
283
|
+
match(esc,
|
|
284
|
+
.Ok(esc_ranges) => {
|
|
285
|
+
if(((esc_ranges.len() == usize(1)) && (esc_ranges.get(usize(0)).unwrap().low == esc_ranges.get(usize(0)).unwrap().high)), {
|
|
286
|
+
(high : u32) = esc_ranges.get(usize(0)).unwrap().low;
|
|
287
|
+
ranges.push(CharRange(low: low, high: high));
|
|
288
|
+
}, {
|
|
289
|
+
// Multi-range escape like \d can't be range endpoint; treat dash as literal
|
|
290
|
+
ranges.push(CharRange(low: low, high: low));
|
|
291
|
+
ranges.push(CharRange(low: u32(45), high: u32(45)));
|
|
292
|
+
j := usize(0);
|
|
293
|
+
while (j < esc_ranges.len()), (j = (j + usize(1))), {
|
|
294
|
+
ranges.push(esc_ranges.get(j).unwrap());
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
},
|
|
298
|
+
.Err(_e) => {
|
|
299
|
+
ranges.push(CharRange(low: low, high: low));
|
|
300
|
+
}
|
|
301
|
+
);
|
|
302
|
+
},
|
|
249
303
|
true => {
|
|
250
304
|
// Consume dash
|
|
251
305
|
self._pos = (self._pos + usize(1));
|
|
@@ -284,10 +338,16 @@ impl(RegexParser,
|
|
|
284
338
|
esc := self._parse_class_escape();
|
|
285
339
|
match(esc,
|
|
286
340
|
.Ok(esc_ranges) => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
341
|
+
// If escape produced a single codepoint, check for range (e.g. \0-\x20)
|
|
342
|
+
if(((esc_ranges.len() == usize(1)) && (esc_ranges.get(usize(0)).unwrap().low == esc_ranges.get(usize(0)).unwrap().high)), {
|
|
343
|
+
(low : u32) = esc_ranges.get(usize(0)).unwrap().low;
|
|
344
|
+
self._try_parse_char_range(ranges, low);
|
|
345
|
+
}, {
|
|
346
|
+
j := usize(0);
|
|
347
|
+
while (j < esc_ranges.len()), (j = (j + usize(1))), {
|
|
348
|
+
ranges.push(esc_ranges.get(j).unwrap());
|
|
349
|
+
};
|
|
350
|
+
});
|
|
291
351
|
},
|
|
292
352
|
.Err(e) => { return .Err(e); }
|
|
293
353
|
);
|
|
@@ -452,6 +512,11 @@ impl(RegexParser,
|
|
|
452
512
|
(ch == u8(112)) => self._parse_unicode_property(false),
|
|
453
513
|
// Negated unicode property \P{Name}
|
|
454
514
|
(ch == u8(80)) => self._parse_unicode_property(true),
|
|
515
|
+
// Hex escape \xHH
|
|
516
|
+
(ch == u8(120)) => match(self._parse_hex_byte(),
|
|
517
|
+
.Some(v) => .Ok(RegexNode.literal(v)),
|
|
518
|
+
.None => .Ok(RegexNode.literal(u32(ch)))
|
|
519
|
+
),
|
|
455
520
|
true => .Ok(RegexNode.literal(self._escape_char_codepoint(ch)))
|
|
456
521
|
),
|
|
457
522
|
.None => .Err(`Unexpected end of pattern after backslash`)
|
package/std/regex/vm.yo
CHANGED
|
@@ -22,21 +22,18 @@ NfaThread :: object(
|
|
|
22
22
|
impl(NfaThread,
|
|
23
23
|
new : (fn(pc : usize, n_slots : usize) -> Self)({
|
|
24
24
|
s := ArrayList(usize).with_capacity(n_slots);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// usize.MAX signals "unset"
|
|
28
|
-
s.push(usize.MAX);
|
|
29
|
-
};
|
|
25
|
+
// usize.MAX = 0xFF..FF, so memset with 0xFF fills each byte
|
|
26
|
+
s.resize_with_byte(n_slots, int(255));
|
|
30
27
|
Self(pc: pc, slots: s)
|
|
31
28
|
}),
|
|
32
29
|
|
|
33
30
|
// Clone a thread with a new PC
|
|
34
31
|
fork : (fn(self : Self, new_pc : usize) -> Self)({
|
|
35
32
|
new_slots := ArrayList(usize).with_capacity(self.slots.len());
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
match(self.slots.ptr(),
|
|
34
|
+
.Some(src) => new_slots.extend_from_ptr(src, self.slots.len()),
|
|
35
|
+
.None => ()
|
|
36
|
+
);
|
|
40
37
|
Self(pc: new_pc, slots: new_slots)
|
|
41
38
|
})
|
|
42
39
|
);
|
|
@@ -233,14 +230,15 @@ impl(NfaVm,
|
|
|
233
230
|
true => ()
|
|
234
231
|
);
|
|
235
232
|
|
|
236
|
-
|
|
233
|
+
// Already checked bounds above: thread.pc < instructions.len()
|
|
234
|
+
is_seen := seen.*.get_unchecked(thread.pc);
|
|
237
235
|
cond(
|
|
238
236
|
is_seen => { return (); },
|
|
239
237
|
true => ()
|
|
240
238
|
);
|
|
241
|
-
seen.*.
|
|
239
|
+
seen.*.set_unchecked(thread.pc, true);
|
|
242
240
|
|
|
243
|
-
instr := self._program.instructions.
|
|
241
|
+
instr := self._program.instructions.get_unchecked(thread.pc);
|
|
244
242
|
|
|
245
243
|
match(instr.kind,
|
|
246
244
|
.Split => {
|
|
@@ -326,10 +324,7 @@ impl(NfaVm,
|
|
|
326
324
|
sub_next := ArrayList(NfaThread).new();
|
|
327
325
|
|
|
328
326
|
sub_seen := ArrayList(bool).with_capacity(self._program.instructions.len());
|
|
329
|
-
|
|
330
|
-
while (si < self._program.instructions.len()), (si = (si + usize(1))), {
|
|
331
|
-
sub_seen.push(false);
|
|
332
|
-
};
|
|
327
|
+
sub_seen.resize_with_byte(self._program.instructions.len(), int(0));
|
|
333
328
|
|
|
334
329
|
initial := NfaThread.new(sub_start_pc, self._n_slots);
|
|
335
330
|
self._add_thread(&(sub_current), initial, start_byte, &(sub_seen));
|
|
@@ -376,10 +371,7 @@ impl(NfaVm,
|
|
|
376
371
|
sub_blen := decoded.byte_len;
|
|
377
372
|
|
|
378
373
|
// Clear seen
|
|
379
|
-
|
|
380
|
-
while (sj < sub_seen.len()), (sj = (sj + usize(1))), {
|
|
381
|
-
sub_seen.set(sj, false);
|
|
382
|
-
};
|
|
374
|
+
sub_seen.fill_with_byte(int(0));
|
|
383
375
|
|
|
384
376
|
// Process consuming instructions
|
|
385
377
|
st2 := usize(0);
|
|
@@ -446,11 +438,9 @@ impl(NfaVm,
|
|
|
446
438
|
|
|
447
439
|
seen := ArrayList(bool).with_capacity(self._program.instructions.len());
|
|
448
440
|
next_seen := ArrayList(bool).with_capacity(self._program.instructions.len());
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
next_seen.push(false);
|
|
453
|
-
};
|
|
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
444
|
|
|
455
445
|
initial := NfaThread.new(usize(0), self._n_slots);
|
|
456
446
|
self._add_thread(&(current), initial, start_byte, &(seen));
|
|
@@ -474,12 +464,9 @@ impl(NfaVm,
|
|
|
474
464
|
true => ()
|
|
475
465
|
);
|
|
476
466
|
|
|
477
|
-
// Clear seen flags for this generation
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
seen.set(j, false);
|
|
481
|
-
next_seen.set(j, false);
|
|
482
|
-
};
|
|
467
|
+
// Clear seen flags for this generation using memset
|
|
468
|
+
seen.fill_with_byte(int(0));
|
|
469
|
+
next_seen.fill_with_byte(int(0));
|
|
483
470
|
|
|
484
471
|
// Process deferred threads targeting this byte_pos
|
|
485
472
|
new_deferred := ArrayList(DeferredThread).new();
|