@shd101wyy/yo 0.1.11 → 0.1.13
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 +10 -1
- package/out/cjs/index.cjs +579 -573
- package/out/cjs/yo-cli.cjs +1413 -592
- package/out/esm/index.mjs +437 -431
- package/out/types/src/build-runner.d.ts +1 -1
- package/out/types/src/doc/builder.d.ts +21 -0
- package/out/types/src/doc/builder.test.d.ts +1 -0
- package/out/types/src/doc/extractor.d.ts +27 -0
- package/out/types/src/doc/extractor.test.d.ts +1 -0
- package/out/types/src/doc/model.d.ts +87 -0
- package/out/types/src/doc/render-html.d.ts +23 -0
- package/out/types/src/doc/render-html.test.d.ts +1 -0
- package/out/types/src/doc/render-json.d.ts +7 -0
- package/out/types/src/doc/render-json.test.d.ts +1 -0
- package/out/types/src/doc/render-markdown.d.ts +13 -0
- package/out/types/src/doc/render-markdown.test.d.ts +1 -0
- package/out/types/src/doc/sections.d.ts +7 -0
- package/out/types/src/doc/sections.test.d.ts +1 -0
- package/out/types/src/doc-command.d.ts +10 -0
- package/out/types/src/env.d.ts +1 -0
- package/out/types/src/evaluator/builtins/build.d.ts +17 -0
- package/out/types/src/evaluator/context.d.ts +1 -0
- package/out/types/src/evaluator/exprs/import.d.ts +2 -0
- package/out/types/src/expr.d.ts +2 -1
- package/out/types/src/tests/import-path.test.d.ts +1 -0
- package/out/types/src/token.d.ts +4 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/scripts/build-site.ts +461 -0
- package/std/alg/hash.yo +12 -24
- package/std/allocator.yo +21 -29
- package/std/async.yo +4 -2
- package/std/build.yo +188 -42
- package/std/cli/arg_parser.yo +37 -1
- package/std/collections/array_list.yo +8 -20
- package/std/collections/btree_map.yo +15 -20
- package/std/collections/deque.yo +13 -15
- package/std/collections/hash_map.yo +15 -54
- package/std/collections/hash_set.yo +14 -50
- package/std/collections/linked_list.yo +6 -23
- package/std/collections/priority_queue.yo +15 -17
- package/std/crypto/md5.yo +10 -9
- package/std/crypto/random.yo +14 -12
- package/std/crypto/sha256.yo +9 -8
- package/std/encoding/base64.yo +13 -15
- package/std/encoding/hex.yo +14 -10
- package/std/encoding/html.yo +14 -11
- package/std/encoding/html_char_utils.yo +14 -11
- package/std/encoding/html_entities.yo +7 -8
- package/std/encoding/json.yo +36 -19
- package/std/encoding/punycode.yo +21 -18
- package/std/encoding/toml.yo +23 -9
- package/std/encoding/utf16.yo +16 -9
- package/std/error.yo +10 -23
- package/std/fmt/display.yo +15 -17
- package/std/fmt/index.yo +6 -27
- package/std/fmt/to_string.yo +4 -10
- package/std/fmt/writer.yo +33 -34
- package/std/fs/dir.yo +37 -30
- package/std/fs/file.yo +77 -75
- package/std/fs/metadata.yo +25 -25
- package/std/fs/temp.yo +21 -27
- package/std/fs/types.yo +20 -23
- package/std/fs/walker.yo +26 -31
- package/std/gc.yo +5 -0
- package/std/glob/index.yo +3 -0
- package/std/http/client.yo +25 -11
- package/std/http/http.yo +20 -0
- package/std/http/index.yo +1 -0
- package/std/io/reader.yo +4 -8
- package/std/io/writer.yo +4 -7
- package/std/libc/assert.yo +2 -2
- package/std/libc/ctype.yo +1 -2
- package/std/libc/dirent.yo +1 -2
- package/std/libc/errno.yo +1 -2
- package/std/libc/fcntl.yo +2 -2
- package/std/libc/float.yo +1 -2
- package/std/libc/limits.yo +1 -2
- package/std/libc/math.yo +2 -0
- package/std/libc/signal.yo +1 -2
- package/std/libc/stdatomic.yo +1 -2
- package/std/libc/stdint.yo +4 -3
- package/std/libc/stdio.yo +2 -0
- package/std/libc/stdlib.yo +2 -0
- package/std/libc/string.yo +2 -0
- package/std/libc/sys/stat.yo +1 -2
- package/std/libc/time.yo +2 -2
- package/std/libc/unistd.yo +2 -0
- package/std/libc/wctype.yo +1 -2
- package/std/libc/windows.yo +2 -2
- package/std/log/index.yo +11 -26
- package/std/net/addr.yo +18 -11
- package/std/net/dns.yo +3 -2
- package/std/net/errors.yo +16 -2
- package/std/net/tcp.yo +25 -22
- package/std/net/udp.yo +14 -12
- package/std/os/env.yo +23 -18
- package/std/os/signal.yo +31 -19
- package/std/path.yo +23 -74
- package/std/prelude.yo +284 -113
- package/std/process.yo +23 -37
- package/std/regex/compiler.yo +3 -5
- package/std/regex/flags.yo +11 -11
- package/std/regex/index.yo +2 -13
- package/std/regex/match.yo +3 -5
- package/std/regex/node.yo +6 -6
- package/std/regex/parser.yo +2 -4
- package/std/regex/unicode.yo +5 -5
- package/std/regex/vm.yo +5 -5
- package/std/string/index.yo +2 -1
- package/std/string/rune.yo +25 -1
- package/std/string/string.yo +31 -19
- package/std/string/unicode.yo +14 -15
- package/std/sync/channel.yo +18 -28
- package/std/sync/cond.yo +4 -0
- package/std/sync/mutex.yo +4 -1
- package/std/sync/once.yo +17 -19
- package/std/sync/rwlock.yo +19 -22
- package/std/sync/waitgroup.yo +21 -23
- package/std/sys/advise.yo +4 -4
- package/std/sys/bufio/buf_reader.yo +19 -16
- package/std/sys/bufio/buf_writer.yo +14 -11
- package/std/sys/clock.yo +4 -4
- package/std/sys/constants.yo +5 -5
- package/std/sys/copy.yo +9 -8
- package/std/sys/dir.yo +9 -8
- package/std/sys/dns.yo +8 -8
- package/std/sys/errors.yo +35 -6
- package/std/sys/events.yo +3 -3
- package/std/sys/externs.yo +3 -3
- package/std/sys/fallocate.yo +4 -4
- package/std/sys/fcntl.yo +8 -6
- package/std/sys/file.yo +7 -8
- package/std/sys/future.yo +1 -3
- package/std/sys/iov.yo +4 -4
- package/std/sys/lock.yo +7 -7
- package/std/sys/mmap.yo +7 -8
- package/std/sys/path.yo +4 -7
- package/std/sys/perm.yo +8 -8
- package/std/sys/pipe.yo +9 -8
- package/std/sys/process.yo +8 -8
- package/std/sys/seek.yo +4 -4
- package/std/sys/signal.yo +4 -4
- package/std/sys/signals.yo +4 -4
- package/std/sys/socket.yo +4 -4
- package/std/sys/socketpair.yo +4 -4
- package/std/sys/sockinfo.yo +4 -4
- package/std/sys/statfs.yo +8 -8
- package/std/sys/statx.yo +4 -4
- package/std/sys/sysinfo.yo +4 -4
- package/std/sys/tcp.yo +8 -8
- package/std/sys/temp.yo +9 -8
- package/std/sys/time.yo +8 -8
- package/std/sys/timer.yo +7 -8
- package/std/sys/tty.yo +13 -10
- package/std/sys/udp.yo +8 -8
- package/std/sys/umask.yo +4 -4
- package/std/sys/unix.yo +5 -5
- package/std/testing/bench.yo +21 -10
- package/std/thread.yo +18 -9
- package/std/time/datetime.yo +12 -14
- package/std/time/duration.yo +12 -14
- package/std/time/instant.yo +13 -16
- package/std/time/sleep.yo +9 -8
- package/std/url/index.yo +3 -19
- package/std/worker.yo +10 -18
package/std/process.yo
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// Provides access to process information and command-line arguments
|
|
1
|
+
//! Process information, command-line arguments, environment variables, and platform detection.
|
|
3
2
|
|
|
4
3
|
open import "./collections/array_list";
|
|
5
4
|
open import "./string";
|
|
@@ -7,19 +6,12 @@ open import "./path";
|
|
|
7
6
|
{ GlobalAllocator } :: import "./allocator";
|
|
8
7
|
{ malloc, free } :: GlobalAllocator;
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* Uses standard naming:
|
|
13
|
-
* - "linux"
|
|
14
|
-
* - "macos"
|
|
15
|
-
* - "windows"
|
|
16
|
-
* - "freebsd"
|
|
17
|
-
* - "emscripten"
|
|
18
|
-
* - "wasi"
|
|
19
|
-
*/
|
|
9
|
+
/// Current target platform as a compile-time string.
|
|
10
|
+
/// One of: "linux", "macos", "windows", "freebsd", "emscripten", "wasi".
|
|
20
11
|
platform :: __yo_process_platform();
|
|
21
12
|
export platform;
|
|
22
13
|
|
|
14
|
+
/// Platform constants for compile-time platform comparisons.
|
|
23
15
|
Platform :: {
|
|
24
16
|
Linux : "linux",
|
|
25
17
|
Macos : "macos",
|
|
@@ -30,18 +22,12 @@ Platform :: {
|
|
|
30
22
|
};
|
|
31
23
|
export Platform;
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* Uses standard naming:
|
|
36
|
-
* - "x86_64"
|
|
37
|
-
* - "aarch64"
|
|
38
|
-
* - "x86"
|
|
39
|
-
* - "arm"
|
|
40
|
-
* - "wasm32"
|
|
41
|
-
*/
|
|
25
|
+
/// Current target architecture as a compile-time string.
|
|
26
|
+
/// One of: "x86_64", "aarch64", "x86", "arm", "wasm32".
|
|
42
27
|
arch :: __yo_process_arch();
|
|
43
28
|
export arch;
|
|
44
29
|
|
|
30
|
+
/// Architecture constants for compile-time architecture comparisons.
|
|
45
31
|
Arch :: {
|
|
46
32
|
X86_64 : "x86_64",
|
|
47
33
|
Aarch64 : "aarch64",
|
|
@@ -62,21 +48,20 @@ extern "Yo",
|
|
|
62
48
|
|
|
63
49
|
// === Raw command-line arguments ===
|
|
64
50
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Example: ["./program", "arg1", "arg2"]
|
|
51
|
+
/// Get raw command-line arguments as a slice of C strings.
|
|
52
|
+
/// The first element is the program name.
|
|
68
53
|
raw_args :: (fn() -> [*(u8)]) {
|
|
69
54
|
return __yo_args;
|
|
70
55
|
};
|
|
71
56
|
export raw_args;
|
|
72
57
|
|
|
73
|
-
|
|
58
|
+
/// Get the number of command-line arguments (including program name).
|
|
74
59
|
argc :: (fn() -> i32) {
|
|
75
60
|
return __yo_argc;
|
|
76
61
|
};
|
|
77
62
|
export argc;
|
|
78
63
|
|
|
79
|
-
|
|
64
|
+
/// Get the raw `argv` pointer (`*(*(u8))`).
|
|
80
65
|
argv :: (fn() -> *(*(u8))) {
|
|
81
66
|
return __yo_argv;
|
|
82
67
|
};
|
|
@@ -84,9 +69,8 @@ export argv;
|
|
|
84
69
|
|
|
85
70
|
// === Convenient command-line arguments ===
|
|
86
71
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// Example: [String("./program"), String("arg1"), String("arg2")]
|
|
72
|
+
/// Get command-line arguments as an `ArrayList(String)`.
|
|
73
|
+
/// The first element is the program name.
|
|
90
74
|
args :: (fn() -> ArrayList(String)) {
|
|
91
75
|
raw := raw_args();
|
|
92
76
|
i := usize(0);
|
|
@@ -104,9 +88,12 @@ args :: (fn() -> ArrayList(String)) {
|
|
|
104
88
|
};
|
|
105
89
|
export args;
|
|
106
90
|
|
|
91
|
+
/// Environment variable access and manipulation.
|
|
107
92
|
env :: impl {
|
|
108
93
|
{ getenv, setenv } :: import "./libc/stdlib";
|
|
109
94
|
|
|
95
|
+
/// Get the value of an environment variable by name.
|
|
96
|
+
/// Returns `.None` if the variable is not set.
|
|
110
97
|
get :: (fn(name : String) -> Option(String)) {
|
|
111
98
|
name_cstr := name.to_cstr().ptr().unwrap();
|
|
112
99
|
val_ptr := getenv(*(char)(name_cstr));
|
|
@@ -117,6 +104,8 @@ env :: impl {
|
|
|
117
104
|
};
|
|
118
105
|
export get;
|
|
119
106
|
|
|
107
|
+
/// Set an environment variable. If `overwrite` is false and the variable
|
|
108
|
+
/// already exists, it is not modified. Returns true on success.
|
|
120
109
|
set :: (fn(name : String, value : String, (overwrite : bool) ?= true) -> bool) {
|
|
121
110
|
name_cstr := name.to_cstr().ptr().unwrap();
|
|
122
111
|
value_cstr := value.to_cstr().ptr().unwrap();
|
|
@@ -156,10 +145,8 @@ env :: impl {
|
|
|
156
145
|
};
|
|
157
146
|
export env;
|
|
158
147
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
* Returns a Result with the current directory as a Path, or an error message.
|
|
162
|
-
*/
|
|
148
|
+
/// Get the current working directory as a `Path`.
|
|
149
|
+
/// Returns `Err` with a message on failure.
|
|
163
150
|
cwd :: (fn() -> Result(Path, String))(
|
|
164
151
|
cond(
|
|
165
152
|
(platform == Platform.Windows) => {
|
|
@@ -265,10 +252,8 @@ cwd :: (fn() -> Result(Path, String))(
|
|
|
265
252
|
);
|
|
266
253
|
export cwd;
|
|
267
254
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
* Returns Ok(()) on success, or an error message on failure.
|
|
271
|
-
*/
|
|
255
|
+
/// Change the current working directory to `path`.
|
|
256
|
+
/// Returns `Ok(())` on success, or `Err` with a message on failure.
|
|
272
257
|
chdir :: (fn(path: Path) -> Result(unit, String))(
|
|
273
258
|
cond(
|
|
274
259
|
(platform == Platform.Windows) => {
|
|
@@ -301,6 +286,7 @@ chdir :: (fn(path: Path) -> Result(unit, String))(
|
|
|
301
286
|
);
|
|
302
287
|
export chdir;
|
|
303
288
|
|
|
289
|
+
/// Exit the process with the given status code.
|
|
304
290
|
exit :: (fn(code : usize) -> unit) {
|
|
305
291
|
{ exit : _exit } :: import "./libc/stdlib";
|
|
306
292
|
_exit(int(code));
|
package/std/regex/compiler.yo
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// Compiles a RegexNode AST into a flat list of NFA instructions
|
|
4
|
-
// using Thompson's construction algorithm.
|
|
1
|
+
//! NFA compiler — compiles a `RegexNode` AST into a flat list of NFA instructions
|
|
2
|
+
//! using Thompson's construction algorithm.
|
|
5
3
|
|
|
6
4
|
open import "std/collections/array_list";
|
|
7
5
|
open import "std/string";
|
|
8
6
|
{ RegexNode, NodeKind, CharRange, AnchorKind, GroupNameEntry } :: import "./node.yo";
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
/// NFA instruction types.
|
|
11
9
|
InstrKind :: enum(
|
|
12
10
|
Char,
|
|
13
11
|
CharClass,
|
package/std/regex/flags.yo
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
//! Regex flags parsing and representation.
|
|
2
|
+
//!
|
|
3
|
+
//! Regex flags follow JavaScript syntax: `"gi"`, `"ms"`, `"iu"`, etc.
|
|
4
|
+
//!
|
|
5
|
+
//! Supported flags:
|
|
6
|
+
//! - `g` — global: match all occurrences
|
|
7
|
+
//! - `i` — ignoreCase: case-insensitive matching
|
|
8
|
+
//! - `m` — multiline: `^` and `$` match line boundaries
|
|
9
|
+
//! - `s` — dotAll: `.` matches newline characters
|
|
10
|
+
//! - `u` — unicode: full Unicode matching
|
|
11
|
+
//! - `y` — sticky: match from lastIndex only
|
|
12
12
|
|
|
13
13
|
open import "std/string";
|
|
14
14
|
open import "std/collections/array_list";
|
package/std/regex/index.yo
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
// High-level regex API similar to JavaScript's RegExp.
|
|
4
|
-
//
|
|
5
|
-
// Example:
|
|
6
|
-
// { Regex } :: import "std/regex";
|
|
7
|
-
// re := Regex.new(`\\d+`).unwrap();
|
|
8
|
-
// m := re.exec(`abc123def`);
|
|
9
|
-
// match(m,
|
|
10
|
-
// .Some(result) => println(result.value()),
|
|
11
|
-
// .None => println(`no match`)
|
|
12
|
-
// );
|
|
1
|
+
//! Regular expression engine with an NFA-based virtual machine.
|
|
13
2
|
|
|
14
3
|
open import "std/collections/array_list";
|
|
15
4
|
open import "std/string";
|
|
@@ -19,7 +8,7 @@ open import "std/string";
|
|
|
19
8
|
{ RegexFlags } :: import "./flags.yo";
|
|
20
9
|
{ RegexMatch } :: import "./match.yo";
|
|
21
10
|
|
|
22
|
-
|
|
11
|
+
/// Compiled regular expression backed by an NFA program.
|
|
23
12
|
Regex :: object(
|
|
24
13
|
_program : NfaProgram,
|
|
25
14
|
_flags : RegexFlags,
|
package/std/regex/match.yo
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// Represents the result of a regex match, including the matched text,
|
|
4
|
-
// position, and captured groups.
|
|
1
|
+
//! Match result type — represents the result of a regex match,
|
|
2
|
+
//! including the matched text, position, and captured groups.
|
|
5
3
|
|
|
6
4
|
open import "std/collections/array_list";
|
|
7
5
|
open import "std/string";
|
|
8
6
|
{ GroupNameEntry } :: import "./node.yo";
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
/// A single regex match result.
|
|
11
9
|
RegexMatch :: object(
|
|
12
10
|
_value : String,
|
|
13
11
|
_index : usize,
|
package/std/regex/node.yo
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
//! Regex AST node types.
|
|
2
|
+
//!
|
|
3
|
+
//! The parser produces a tree of `RegexNode` objects representing the
|
|
4
|
+
//! structure of a regex pattern. Nodes are reference-counted objects
|
|
5
|
+
//! since they form a recursive tree.
|
|
6
6
|
|
|
7
7
|
open import "std/collections/array_list";
|
|
8
8
|
open import "std/string";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
/// A range of characters for character classes, e.g. `a`–`z`.
|
|
11
11
|
CharRange :: struct(
|
|
12
12
|
low : u32,
|
|
13
13
|
high : u32
|
package/std/regex/parser.yo
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// Parses a regex pattern string into an AST of RegexNode objects.
|
|
4
|
-
// Uses an iterative stack-based approach to avoid mutual recursion.
|
|
1
|
+
//! Regex pattern parser — parses a regex pattern string into an AST
|
|
2
|
+
//! of `RegexNode` objects. Uses an iterative stack-based approach.
|
|
5
3
|
|
|
6
4
|
open import "std/collections/array_list";
|
|
7
5
|
open import "std/string";
|
package/std/regex/unicode.yo
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
//! Unicode property ranges for `\p{...}` support.
|
|
2
|
+
//!
|
|
3
|
+
//! Provides character ranges for common Unicode general categories.
|
|
4
|
+
//! Uses compact range representation covering the most commonly used
|
|
5
|
+
//! Unicode blocks. Not exhaustive but covers practical use cases.
|
|
6
6
|
|
|
7
7
|
open import "std/collections/array_list";
|
|
8
8
|
open import "std/string";
|
package/std/regex/vm.yo
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
//! NFA virtual machine (Thompson simulation).
|
|
2
|
+
//!
|
|
3
|
+
//! Executes a compiled NFA program against an input string.
|
|
4
|
+
//! Uses Thompson's NFA simulation with parallel state tracking
|
|
5
|
+
//! for O(n×m) worst-case time complexity.
|
|
6
6
|
|
|
7
7
|
open import "std/collections/array_list";
|
|
8
8
|
open import "std/string";
|
package/std/string/index.yo
CHANGED
package/std/string/rune.yo
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
//! Unicode code point type (`rune`) for representing individual characters.
|
|
2
|
+
|
|
3
|
+
/// Unicode code point (U+0000 to U+10FFFF, excluding surrogates).
|
|
4
|
+
/// Similar to Go's `rune` or Rust's `char`.
|
|
1
5
|
rune :: newtype(
|
|
6
|
+
/// The raw Unicode code point value.
|
|
2
7
|
char : u32
|
|
3
8
|
);
|
|
4
9
|
impl(rune,
|
|
10
|
+
/// Create a rune from a `u32` value, returning `None` if the value is not a valid Unicode code point.
|
|
5
11
|
from_u32 : (fn(value: u32) -> Option(Self))(
|
|
6
12
|
cond(
|
|
7
13
|
((value <= u32(0x10FFFF)) && (((value < 0xD800) || (value > 0xDFFF)))) => .Some(Self(value)),
|
|
@@ -9,34 +15,42 @@ impl(rune,
|
|
|
9
15
|
)
|
|
10
16
|
),
|
|
11
17
|
|
|
18
|
+
/// Return the raw `u32` code point value.
|
|
12
19
|
to_u32 : (fn(self: Self) -> u32)(
|
|
13
20
|
self.char
|
|
14
21
|
),
|
|
15
22
|
|
|
23
|
+
/// Check if this is an ASCII character (U+0000 to U+007F).
|
|
16
24
|
is_ascii : (fn(self: Self) -> bool)(
|
|
17
25
|
(self.char <= 0x7F)
|
|
18
26
|
),
|
|
19
27
|
|
|
28
|
+
/// Check if this is a whitespace character (space, tab, newline, or carriage return).
|
|
20
29
|
is_whitespace : (fn(self: Self) -> bool)(
|
|
21
30
|
(((self.char == 0x20) || (self.char == 0x09)) || ((self.char == 0x0A) || (self.char == 0x0D)))
|
|
22
31
|
),
|
|
23
32
|
|
|
33
|
+
/// Check if this is an ASCII digit ('0' to '9').
|
|
24
34
|
is_digit : (fn(self: Self) -> bool)(
|
|
25
35
|
((self.char >= 0x30) && (self.char <= 0x39))
|
|
26
36
|
),
|
|
27
37
|
|
|
38
|
+
/// Check if this is an ASCII letter ('A'-'Z' or 'a'-'z').
|
|
28
39
|
is_alphabetic : (fn(self: Self) -> bool)(
|
|
29
40
|
(((self.char >= 0x41) && (self.char <= 0x5A)) || ((self.char >= 0x61) && (self.char <= 0x7A)))
|
|
30
41
|
),
|
|
31
42
|
|
|
43
|
+
/// Check if this is an ASCII uppercase letter ('A'-'Z').
|
|
32
44
|
is_uppercase : (fn(self: Self) -> bool)(
|
|
33
45
|
((self.char >= 0x41) && (self.char <= 0x5A))
|
|
34
46
|
),
|
|
35
47
|
|
|
48
|
+
/// Check if this is an ASCII lowercase letter ('a'-'z').
|
|
36
49
|
is_lowercase : (fn(self: Self) -> bool)(
|
|
37
50
|
((self.char >= 0x61) && (self.char <= 0x7A))
|
|
38
51
|
),
|
|
39
52
|
|
|
53
|
+
/// Convert to lowercase. Only affects ASCII uppercase letters.
|
|
40
54
|
to_lowercase : (fn(self: Self) -> Self)(
|
|
41
55
|
cond(
|
|
42
56
|
is_uppercase(self) => Self((self.char + 32)),
|
|
@@ -44,6 +58,7 @@ impl(rune,
|
|
|
44
58
|
)
|
|
45
59
|
),
|
|
46
60
|
|
|
61
|
+
/// Convert to uppercase. Only affects ASCII lowercase letters.
|
|
47
62
|
to_uppercase : (fn(self: Self) -> Self)(
|
|
48
63
|
cond(
|
|
49
64
|
is_lowercase(self) => Self((self.char - 32)),
|
|
@@ -51,16 +66,25 @@ impl(rune,
|
|
|
51
66
|
)
|
|
52
67
|
),
|
|
53
68
|
|
|
54
|
-
|
|
69
|
+
/// Null character (U+0000).
|
|
55
70
|
NUL : Self(0x00),
|
|
71
|
+
/// Horizontal tab (U+0009).
|
|
56
72
|
TAB : Self(0x09),
|
|
73
|
+
/// Line feed / newline (U+000A).
|
|
57
74
|
NEWLINE : Self(0x0A),
|
|
75
|
+
/// Space (U+0020).
|
|
58
76
|
SPACE : Self(0x20),
|
|
77
|
+
/// Digit zero '0' (U+0030).
|
|
59
78
|
ZERO : Self(0x30),
|
|
79
|
+
/// Digit nine '9' (U+0039).
|
|
60
80
|
NINE : Self(0x39),
|
|
81
|
+
/// Uppercase 'A' (U+0041).
|
|
61
82
|
UPPERCASE_A : Self(0x41),
|
|
83
|
+
/// Uppercase 'Z' (U+005A).
|
|
62
84
|
UPPERCASE_Z : Self(0x5A),
|
|
85
|
+
/// Lowercase 'a' (U+0061).
|
|
63
86
|
LOWERCASE_A : Self(0x61),
|
|
87
|
+
/// Lowercase 'z' (U+007A).
|
|
64
88
|
LOWERCASE_Z : Self(0x7A)
|
|
65
89
|
);
|
|
66
90
|
|
package/std/string/string.yo
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
+
//! Immutable UTF-8 string type with comprehensive operations.
|
|
2
|
+
|
|
1
3
|
{ ArrayList } :: import "../collections/array_list.yo";
|
|
2
4
|
{ rune } :: import "./rune.yo";
|
|
3
5
|
{ memcpy, memcmp, strlen } :: import "../libc/string.yo";
|
|
4
6
|
|
|
7
|
+
/// String operation error variants.
|
|
5
8
|
StringError :: enum(
|
|
9
|
+
/// The input bytes are not valid UTF-8.
|
|
6
10
|
InvalidUtf8,
|
|
11
|
+
/// The index is out of bounds for the string's byte length.
|
|
7
12
|
IndexOutOfBounds(index: usize, length: usize)
|
|
8
13
|
);
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* Similar to JavaScript String, Python str, and Rust String.
|
|
14
|
-
* Strings are immutable - all operations return new strings.
|
|
15
|
-
*
|
|
16
|
-
* Internal storage uses Option(ArrayList(u8)) for UTF-8 bytes.
|
|
17
|
-
* An empty string is represented as .None (zero allocation).
|
|
18
|
-
*/
|
|
15
|
+
/// Immutable UTF-8 encoded string.
|
|
16
|
+
/// All operations return new strings; mutable operations require a pointer to self.
|
|
17
|
+
/// Empty strings use zero allocation (represented as `Option.None` internally).
|
|
19
18
|
String :: newtype(
|
|
20
19
|
_bytes: Option(ArrayList(u8))
|
|
21
20
|
);
|
|
@@ -82,6 +81,8 @@ impl(String,
|
|
|
82
81
|
return .Ok(Self(_bytes: .Some(bytes)));
|
|
83
82
|
}),
|
|
84
83
|
|
|
84
|
+
/// Convert the string to a null-terminated C string.
|
|
85
|
+
/// Returns an `ArrayList(u8)` with the string bytes followed by a `\0`.
|
|
85
86
|
to_cstr : (fn(self: Self) -> ArrayList(u8))({
|
|
86
87
|
(bytes_len : usize) = match(self._bytes,
|
|
87
88
|
.Some(b) => b.len(),
|
|
@@ -318,7 +319,7 @@ impl(String,
|
|
|
318
319
|
return Self(_bytes: .Some(new_bytes));
|
|
319
320
|
}),
|
|
320
321
|
|
|
321
|
-
|
|
322
|
+
/// Append another `String` to this string in-place (mutates `self`).
|
|
322
323
|
push_string : (fn(self: *(Self), other: Self) -> unit)({
|
|
323
324
|
(olen : usize) = match(other._bytes, .Some(b) => b.len(), .None => usize(0));
|
|
324
325
|
if((olen > usize(0)), {
|
|
@@ -343,6 +344,7 @@ impl(String,
|
|
|
343
344
|
});
|
|
344
345
|
}),
|
|
345
346
|
|
|
347
|
+
/// Append a `str` slice to this string in-place (mutates `self`).
|
|
346
348
|
push_str : (fn(self: *(Self), s: str) -> unit)({
|
|
347
349
|
(slen : usize) = s.len();
|
|
348
350
|
if((slen > usize(0)), {
|
|
@@ -359,6 +361,8 @@ impl(String,
|
|
|
359
361
|
});
|
|
360
362
|
}),
|
|
361
363
|
|
|
364
|
+
/// Append a single byte to this string in-place (mutates `self`).
|
|
365
|
+
/// The caller must ensure the byte maintains valid UTF-8.
|
|
362
366
|
push_byte : (fn(self: *(Self), b: u8) -> unit)({
|
|
363
367
|
match(self.*._bytes,
|
|
364
368
|
.None => {
|
|
@@ -372,6 +376,8 @@ impl(String,
|
|
|
372
376
|
);
|
|
373
377
|
}),
|
|
374
378
|
|
|
379
|
+
/// Reserve capacity for at least `additional` more bytes.
|
|
380
|
+
/// If the string is empty, creates a new buffer with the given capacity.
|
|
375
381
|
reserve : (fn(self: *(Self), additional: usize) -> unit)({
|
|
376
382
|
match(self.*._bytes,
|
|
377
383
|
.None => {
|
|
@@ -384,7 +390,7 @@ impl(String,
|
|
|
384
390
|
);
|
|
385
391
|
}),
|
|
386
392
|
|
|
387
|
-
|
|
393
|
+
/// Clear the string content but keep the allocated buffer for reuse.
|
|
388
394
|
clear : (fn(self: *(Self)) -> unit)(
|
|
389
395
|
match(self.*._bytes,
|
|
390
396
|
.Some(al) => al.clear(),
|
|
@@ -392,7 +398,7 @@ impl(String,
|
|
|
392
398
|
)
|
|
393
399
|
),
|
|
394
400
|
|
|
395
|
-
|
|
401
|
+
/// Create a deep copy of this string with its own buffer.
|
|
396
402
|
clone : (fn(self: Self) -> Self)(
|
|
397
403
|
match(self._bytes,
|
|
398
404
|
.None => Self(_bytes: .None),
|
|
@@ -407,7 +413,8 @@ impl(String,
|
|
|
407
413
|
)
|
|
408
414
|
),
|
|
409
415
|
|
|
410
|
-
|
|
416
|
+
/// Get the number of bytes in the string (not Unicode characters).
|
|
417
|
+
/// Use `len()` for Unicode character count.
|
|
411
418
|
bytes_len : (fn(self: Self) -> usize)(
|
|
412
419
|
match(self._bytes, .Some(b) => b.len(), .None => usize(0))
|
|
413
420
|
),
|
|
@@ -1393,6 +1400,7 @@ impl(String,
|
|
|
1393
1400
|
)
|
|
1394
1401
|
);
|
|
1395
1402
|
|
|
1403
|
+
/// Add trait implementation — concatenate two strings with `+`.
|
|
1396
1404
|
impl(String, Add(String)(
|
|
1397
1405
|
Output : String,
|
|
1398
1406
|
(+) : (fn(self: Self, other: Self) -> Self.Output)({
|
|
@@ -1400,6 +1408,7 @@ impl(String, Add(String)(
|
|
|
1400
1408
|
})
|
|
1401
1409
|
));
|
|
1402
1410
|
|
|
1411
|
+
/// Eq trait implementation — byte-level comparison of two strings.
|
|
1403
1412
|
impl(String, Eq(String)(
|
|
1404
1413
|
(==) : (fn(self: Self, other: Self) -> bool)({
|
|
1405
1414
|
(self_len : usize) = match(self._bytes, .Some(b) => b.len(), .None => usize(0));
|
|
@@ -1433,6 +1442,7 @@ impl(String, Eq(String)(
|
|
|
1433
1442
|
})
|
|
1434
1443
|
));
|
|
1435
1444
|
|
|
1445
|
+
/// Hash trait implementation — FNV-1a hash over the string's bytes.
|
|
1436
1446
|
impl(String, Hash(
|
|
1437
1447
|
(hash): (fn(self: *(Self)) -> u64)({
|
|
1438
1448
|
h := u64(14695981039346656037);
|
|
@@ -1458,11 +1468,11 @@ impl(String, Hash(
|
|
|
1458
1468
|
})
|
|
1459
1469
|
));
|
|
1460
1470
|
|
|
1461
|
-
|
|
1471
|
+
/// === Iterator support ===
|
|
1462
1472
|
|
|
1463
1473
|
/**
|
|
1464
|
-
* Rune iterator for String
|
|
1465
|
-
* Used by chars() and into_iter()
|
|
1474
|
+
* Rune iterator for `String` — yields decoded Unicode runes.
|
|
1475
|
+
* Used by `chars()` and `into_iter()`.
|
|
1466
1476
|
*/
|
|
1467
1477
|
StringChars :: struct(
|
|
1468
1478
|
_string : String,
|
|
@@ -1500,8 +1510,8 @@ impl(StringChars, Iterator(
|
|
|
1500
1510
|
));
|
|
1501
1511
|
|
|
1502
1512
|
/**
|
|
1503
|
-
* Byte iterator for String
|
|
1504
|
-
* Used by bytes()
|
|
1513
|
+
* Byte iterator for `String` — yields raw UTF-8 bytes.
|
|
1514
|
+
* Used by `bytes()`.
|
|
1505
1515
|
*/
|
|
1506
1516
|
StringBytes :: struct(
|
|
1507
1517
|
_string : String,
|
|
@@ -1548,7 +1558,7 @@ impl(String,
|
|
|
1548
1558
|
)
|
|
1549
1559
|
);
|
|
1550
1560
|
|
|
1551
|
-
|
|
1561
|
+
/// === Numeric parsing methods ===
|
|
1552
1562
|
|
|
1553
1563
|
impl(String,
|
|
1554
1564
|
/**
|
|
@@ -1910,6 +1920,8 @@ impl(String,
|
|
|
1910
1920
|
)
|
|
1911
1921
|
);
|
|
1912
1922
|
|
|
1923
|
+
/// Index trait implementation — access a single byte by index.
|
|
1924
|
+
/// Panics if the string is empty.
|
|
1913
1925
|
impl(String, Index(usize)(
|
|
1914
1926
|
Output : u8,
|
|
1915
1927
|
index : (fn(self: *(Self), idx: usize) -> *(Self.Output))(
|
package/std/string/unicode.yo
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
// upper := unicode_to_uppercase(`hello wörld`); // "HELLO WÖRLD"
|
|
1
|
+
//! Unicode-aware case conversion using full case folding rules.
|
|
2
|
+
//!
|
|
3
|
+
//! # Example
|
|
4
|
+
//!
|
|
5
|
+
//! ```rust
|
|
6
|
+
//! { unicode_to_lowercase, unicode_to_uppercase } :: import "std/string/unicode";
|
|
7
|
+
//!
|
|
8
|
+
//! lower := unicode_to_lowercase(`HELLO WÖRLD`); // "hello wörld"
|
|
9
|
+
//! upper := unicode_to_uppercase(`hello wörld`); // "HELLO WÖRLD"
|
|
10
|
+
//! ```
|
|
12
11
|
|
|
13
12
|
open import "../string";
|
|
14
13
|
{ ArrayList } :: import "../collections/array_list";
|
|
@@ -164,8 +163,8 @@ _special_to_upper :: (fn(cp: i32, out: *(ArrayList(u8))) -> bool)({
|
|
|
164
163
|
});
|
|
165
164
|
|
|
166
165
|
// Convert a String to lowercase using Unicode-aware case mapping.
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
/// Convert a `String` to lowercase using Unicode case mapping rules.
|
|
167
|
+
/// Handles both ASCII and non-ASCII codepoints, plus special multi-char expansions (e.g., ẞ → ss).
|
|
169
168
|
unicode_to_lowercase :: (fn(input: String) -> String)({
|
|
170
169
|
(bytes : ArrayList(u8)) = input.as_bytes();
|
|
171
170
|
(out : ArrayList(u8)) = ArrayList(u8).with_capacity(bytes.len());
|
|
@@ -202,8 +201,8 @@ unicode_to_lowercase :: (fn(input: String) -> String)({
|
|
|
202
201
|
});
|
|
203
202
|
|
|
204
203
|
// Convert a String to uppercase using Unicode-aware case mapping.
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
/// Convert a `String` to uppercase using Unicode case mapping rules.
|
|
205
|
+
/// Handles both ASCII and non-ASCII codepoints, plus special multi-char expansions (e.g., ß → SS).
|
|
207
206
|
unicode_to_uppercase :: (fn(input: String) -> String)({
|
|
208
207
|
(bytes : ArrayList(u8)) = input.as_bytes();
|
|
209
208
|
(out : ArrayList(u8)) = ArrayList(u8).with_capacity(bytes.len());
|
package/std/sync/channel.yo
CHANGED
|
@@ -1,36 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// ch := Channel(i32).new(usize(10));
|
|
19
|
-
// t := Thread.spawn(() => {
|
|
20
|
-
// ch.send(i32(42));
|
|
21
|
-
// });
|
|
22
|
-
// val := ch.recv(); // blocks until data available
|
|
23
|
-
// assert((val.unwrap() == i32(42)), "received value");
|
|
24
|
-
// t.join();
|
|
1
|
+
//! Bounded multi-producer multi-consumer (MPMC) channel.
|
|
2
|
+
//! Uses blocking send/recv via condition variables — does not require IO.
|
|
3
|
+
//!
|
|
4
|
+
//! # Example
|
|
5
|
+
//!
|
|
6
|
+
//! ```rust
|
|
7
|
+
//! { Channel } :: import "std/sync/channel";
|
|
8
|
+
//! { Thread } :: import "std/thread";
|
|
9
|
+
//!
|
|
10
|
+
//! ch := Channel(i32).new(usize(10));
|
|
11
|
+
//! t := Thread.spawn(() => {
|
|
12
|
+
//! ch.send(i32(42));
|
|
13
|
+
//! });
|
|
14
|
+
//! val := ch.recv(); // blocks until data available
|
|
15
|
+
//! assert((val.unwrap() == i32(42)), "received value");
|
|
16
|
+
//! t.join();
|
|
17
|
+
//! ```
|
|
25
18
|
|
|
26
19
|
{ Deque } :: import "../collections/deque";
|
|
27
20
|
{ Mutex } :: import "./mutex";
|
|
28
21
|
{ Cond } :: import "./cond";
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
// Channel - Bounded MPMC channel
|
|
32
|
-
// ============================================================================
|
|
33
|
-
|
|
23
|
+
/// Thread-safe bounded channel for passing values between threads.
|
|
34
24
|
Channel :: (fn(comptime(T) : Type) -> comptime(Type))
|
|
35
25
|
object(
|
|
36
26
|
_buf : Deque(T),
|