mt-lang 0.4.24 → 0.4.25
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +8 -8
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/control_flow/builder.rb +12 -0
- data/lib/milk_tea/tooling/cli/commands/std.rb +84 -0
- data/lib/milk_tea/tooling/cli.rb +25 -0
- data/lib/milk_tea/tooling/linter/fix_engine.rb +100 -0
- data/lib/milk_tea/tooling/linter/release_rules.rb +69 -11
- data/lib/milk_tea/tooling/linter/visitors.rb +58 -31
- data/lib/milk_tea/tooling/linter.rb +8 -1
- data/lib/milk_tea/tooling/std_catalog.rb +277 -0
- data/lib/milk_tea/tooling.rb +1 -0
- data/std/async/libuv_runtime.mt +20 -23
- data/std/async/mailbox.mt +2 -2
- data/std/base64.mt +3 -6
- data/std/behavior_tree.mt +1 -6
- data/std/binary.mt +2 -5
- data/std/color.mt +20 -20
- data/std/cookie.mt +1 -4
- data/std/deque.mt +2 -8
- data/std/encoding.mt +1 -4
- data/std/fmt.mt +1 -4
- data/std/graph.mt +5 -1
- data/std/htn.mt +9 -1
- data/std/http/server.mt +1 -4
- data/std/http.mt +14 -17
- data/std/jobs.mt +9 -10
- data/std/json.mt +17 -28
- data/std/linked_map.mt +3 -9
- data/std/map.mt +1 -4
- data/std/net/channel.mt +6 -6
- data/std/net/lobby.mt +3 -3
- data/std/net/manager.mt +0 -1
- data/std/net/mux.mt +1 -1
- data/std/net/packet.mt +4 -1
- data/std/net/punch.mt +3 -2
- data/std/net/rpc.mt +1 -3
- data/std/net/session.mt +12 -25
- data/std/net/sync.mt +3 -3
- data/std/net/turn.mt +7 -3
- data/std/net.mt +145 -159
- data/std/noise.mt +11 -7
- data/std/ordered_map.mt +2 -8
- data/std/ordered_set.mt +3 -5
- data/std/path.mt +1 -4
- data/std/process.mt +7 -18
- data/std/random.mt +2 -2
- data/std/sdl3/runtime.mt +1 -1
- data/std/steering.mt +27 -4
- data/std/string.mt +1 -4
- data/std/tar.mt +8 -10
- data/std/terminal.mt +21 -40
- data/std/thread.mt +3 -4
- data/std/tls.mt +22 -29
- data/std/toml.mt +23 -31
- data/std/uri.mt +2 -1
- data/std/utility.mt +2 -2
- data/std/vec.mt +7 -17
- metadata +5 -3
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MilkTea
|
|
4
|
+
# Discovers the hand-written standard library modules shipped in std/, and
|
|
5
|
+
# resolves module names to source paths for tooling commands.
|
|
6
|
+
#
|
|
7
|
+
# Generated modules (bindgen output under std/c/ and imported-binding
|
|
8
|
+
# wrappers such as raylib or zstd) are excluded from discovery but stay
|
|
9
|
+
# resolvable, so `std show` can still print them.
|
|
10
|
+
class StdCatalog
|
|
11
|
+
Entry = Struct.new(:name, :description, :category, :path, keyword_init: true)
|
|
12
|
+
|
|
13
|
+
GENERATED_HEADER_PREFIX = "# generated by mtc"
|
|
14
|
+
PLATFORM_SUFFIXES = %w[linux windows wasm].freeze
|
|
15
|
+
EXCLUDED_DIRECTORIES = %w[c].freeze
|
|
16
|
+
|
|
17
|
+
CATEGORY_ORDER = [
|
|
18
|
+
"Core & Patterns",
|
|
19
|
+
"Collections",
|
|
20
|
+
"Memory",
|
|
21
|
+
"Text & Formatting",
|
|
22
|
+
"Math & Simulation",
|
|
23
|
+
"Data & Serialization",
|
|
24
|
+
"Concurrency & Time",
|
|
25
|
+
"Files & System",
|
|
26
|
+
"Network",
|
|
27
|
+
"Security",
|
|
28
|
+
"AI & Behavior",
|
|
29
|
+
"Game & Graphics",
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
# name => [category, description]. Must cover every hand-written module
|
|
33
|
+
# discovered under std/; a test enforces that coverage.
|
|
34
|
+
REGISTRY = {
|
|
35
|
+
"asset_pack" => ["Game & Graphics", "MTAP asset pack reader and writer for bundled runtime assets."],
|
|
36
|
+
"async" => ["Concurrency & Time", "Async/await runtime facade over a pluggable event-loop backend."],
|
|
37
|
+
"async.libuv_runtime" => ["Concurrency & Time", "libuv-backed async runtime implementation."],
|
|
38
|
+
"async.mailbox" => ["Concurrency & Time", "Typed mailboxes for message passing between async tasks."],
|
|
39
|
+
"async.runtime" => ["Concurrency & Time", "Async backend selection and event-loop plumbing shared by async code."],
|
|
40
|
+
"base64" => ["Text & Formatting", "Base64 encode and decode."],
|
|
41
|
+
"behavior_tree" => ["AI & Behavior", "Behavior trees with sequence, selector, decorator, and leaf nodes."],
|
|
42
|
+
"binary" => ["Data & Serialization", "Binary reader/writer with explicit endianness and error reporting."],
|
|
43
|
+
"binary_heap" => ["Collections", "Binary heap over a flat array with sift-up/sift-down operations."],
|
|
44
|
+
"bitset" => ["Collections", "Fixed-capacity bit array with set, clear, test, and population count."],
|
|
45
|
+
"blackboard" => ["AI & Behavior", "Typed key-value shared state for AI agents."],
|
|
46
|
+
"box" => ["Core & Patterns", "Explicit single-value heap storage for owned boxed values."],
|
|
47
|
+
"bytes" => ["Data & Serialization", "Byte buffer type with slicing, comparison, and stream I/O."],
|
|
48
|
+
"cli" => ["Files & System", "Command-line parsing helpers for flags, options, and positionals."],
|
|
49
|
+
"cmd" => ["Core & Patterns", "Command pattern with paired do/undo callbacks for undo/redo stacks."],
|
|
50
|
+
"color" => ["Game & Graphics", "RGBA color conversion, blending, and named presets."],
|
|
51
|
+
"cookie" => ["Data & Serialization", "HTTP cookie parsing and serialization."],
|
|
52
|
+
"counter" => ["Collections", "Occurrence counter keyed by value, a counting multiset."],
|
|
53
|
+
"crypto" => ["Security", "Digests, HMAC, and secure random via the platform crypto bindings."],
|
|
54
|
+
"cstring" => ["Text & Formatting", "Null-terminated C string helpers backed by libc memory routines."],
|
|
55
|
+
"ctype" => ["Text & Formatting", "Character classification: alnum, digit, space, and case tests."],
|
|
56
|
+
"curl.runtime" => ["Network", "libcurl runtime glue for handle setup and error reporting."],
|
|
57
|
+
"deque" => ["Collections", "Double-ended queue with amortized O(1) operations at both ends."],
|
|
58
|
+
"encoding" => ["Text & Formatting", "UTF-8 validation, codepoint iteration, and encoding helpers."],
|
|
59
|
+
"env" => ["Files & System", "Environment variable access returning Option values."],
|
|
60
|
+
"errno" => ["Files & System", "errno code constants and error message lookup."],
|
|
61
|
+
"fmt" => ["Text & Formatting", "Value formatting helpers for integers, floats, and fixed buffers."],
|
|
62
|
+
"fs" => ["Files & System", "File and directory operations with platform-specific variants."],
|
|
63
|
+
"fsm" => ["AI & Behavior", "Finite state machines with table-driven transitions and dispatch."],
|
|
64
|
+
"goap" => ["AI & Behavior", "Goal-oriented action planning (GOAP) with forward search."],
|
|
65
|
+
"graph" => ["Game & Graphics", "Weighted graph algorithms such as shortest paths and reachability."],
|
|
66
|
+
"gzip" => ["Data & Serialization", "Gzip and zlib compression and decompression."],
|
|
67
|
+
"hash" => ["Core & Patterns", "Canonical hash, equality, and ordering for common primitive types."],
|
|
68
|
+
"htn" => ["AI & Behavior", "Hierarchical Task Network (HTN) planner."],
|
|
69
|
+
"http" => ["Network", "HTTP client for requests, responses, and chunked bodies."],
|
|
70
|
+
"http.server" => ["Network", "Small HTTP server with routing, static files, and JSON responses."],
|
|
71
|
+
"input" => ["Game & Graphics", "Input action mapping that decouples logical actions from physical devices."],
|
|
72
|
+
"intern" => ["Text & Formatting", "String interning table producing unique identifier handles."],
|
|
73
|
+
"iter" => ["Core & Patterns", "Composable lazy iteration adaptors over sequences."],
|
|
74
|
+
"jobs" => ["Concurrency & Time", "Job scheduler for fan-out parallel work with completion tracking."],
|
|
75
|
+
"json" => ["Data & Serialization", "JSON parsing and serialization over cjson with arena-backed values."],
|
|
76
|
+
"libc" => ["Files & System", "Curated libc facade for memory, string, process, and math functions."],
|
|
77
|
+
"linear_algebra" => ["Math & Simulation", "Vectors and matrices for 2D/3D graphics and physics."],
|
|
78
|
+
"linked_map" => ["Collections", "Hash map with a doubly-linked order list for O(1) reordering."],
|
|
79
|
+
"linked_map_view" => ["Collections", "Read-only snapshot views over linked_map instances."],
|
|
80
|
+
"linked_set" => ["Collections", "Insertion-ordered hash set backed by a linked list."],
|
|
81
|
+
"log" => ["Files & System", "Leveled logging with configurable output sinks."],
|
|
82
|
+
"lru_cache" => ["Collections", "Least-recently-used cache with bounded capacity."],
|
|
83
|
+
"map" => ["Collections", "Chained hash map with pluggable hashing for generic keys and values."],
|
|
84
|
+
"math" => ["Math & Simulation", "Mathematical constants and functions beyond the language builtins."],
|
|
85
|
+
"mem.arena" => ["Memory", "Region allocator: bump allocation with O(1) mark/reset."],
|
|
86
|
+
"mem.endian" => ["Memory", "Byte-swap and endian conversion helpers."],
|
|
87
|
+
"mem.heap" => ["Memory", "General-purpose heap allocator wrapper with alignment control."],
|
|
88
|
+
"mem.pool" => ["Memory", "Fixed-slot pool allocator for uniform-size objects."],
|
|
89
|
+
"mem.ptr" => ["Memory", "Safe pointer load/store wrappers around raw memory access."],
|
|
90
|
+
"mem.stack" => ["Memory", "Stack allocator with mark/release layered on the arena."],
|
|
91
|
+
"mem.tracking" => ["Memory", "Allocation tracker for leak detection and usage diagnostics."],
|
|
92
|
+
"multiset" => ["Collections", "Hash multiset that counts duplicate values."],
|
|
93
|
+
"net" => ["Network", "UDP and TCP sockets, address resolution, and packet I/O."],
|
|
94
|
+
"net.channel" => ["Network", "Multiplexed message channels over a single connection."],
|
|
95
|
+
"net.clock" => ["Network", "Synchronized network clock with ping and offset estimation."],
|
|
96
|
+
"net.discovery" => ["Network", "LAN service discovery via UDP broadcast."],
|
|
97
|
+
"net.lobby" => ["Network", "Lobby listing and joining built on discovery."],
|
|
98
|
+
"net.manager" => ["Network", "Connection and session manager for multiplayer topologies."],
|
|
99
|
+
"net.mux" => ["Network", "Stream multiplexer with reliable and unordered delivery flags."],
|
|
100
|
+
"net.nat" => ["Network", "NAT type detection and address binding via STUN."],
|
|
101
|
+
"net.packet" => ["Network", "Framed packet reading and writing over byte streams."],
|
|
102
|
+
"net.punch" => ["Network", "UDP hole punching for peer-to-peer connections."],
|
|
103
|
+
"net.rpc" => ["Network", "Request/response RPC framing over net channels."],
|
|
104
|
+
"net.session" => ["Network", "Client session state machine with heartbeats and timeouts."],
|
|
105
|
+
"net.stun" => ["Network", "STUN client for public address and port discovery."],
|
|
106
|
+
"net.sync" => ["Network", "State synchronization primitives for replicated values."],
|
|
107
|
+
"net.turn" => ["Network", "TURN relay client for NAT-restricted peers."],
|
|
108
|
+
"noise" => ["Math & Simulation", "Coherent Perlin noise and fractal variants."],
|
|
109
|
+
"oauth2" => ["Data & Serialization", "OAuth2 token requests and refresh flows."],
|
|
110
|
+
"option" => ["Core & Patterns", "Option[T] optional values, some(value) or none, with combinators."],
|
|
111
|
+
"ordered_map" => ["Collections", "Hash map that preserves insertion order."],
|
|
112
|
+
"ordered_set" => ["Collections", "Hash set that preserves insertion order."],
|
|
113
|
+
"parse" => ["Text & Formatting", "Numeric string parsing for integers and floats."],
|
|
114
|
+
"path" => ["Files & System", "Path join, split, and normalization utilities."],
|
|
115
|
+
"pcre2.runtime" => ["Text & Formatting", "Compiled regex matching runtime over the pcre2 bindings."],
|
|
116
|
+
"pool" => ["Collections", "Fixed-capacity reusable object storage."],
|
|
117
|
+
"priority_queue" => ["Collections", "Priority queue backed by a binary heap."],
|
|
118
|
+
"process" => ["Files & System", "Child process spawning with pipes and exit status."],
|
|
119
|
+
"queue" => ["Collections", "First-in first-out queue."],
|
|
120
|
+
"random" => ["Math & Simulation", "PCG pseudo-random number generation with seeding and ranges."],
|
|
121
|
+
"raylib.debug_console" => ["Game & Graphics", "In-game debug console overlay with command history."],
|
|
122
|
+
"raylib.easing" => ["Game & Graphics", "Easing curves for animation interpolation."],
|
|
123
|
+
"raylib.packed_assets" => ["Game & Graphics", "Load images, textures, and audio from assets.mtpack packs."],
|
|
124
|
+
"raylib.runtime" => ["Game & Graphics", "raylib app lifecycle helpers: window loop, asset directory, fatal errors."],
|
|
125
|
+
"raylib.tracy_gpu" => ["Game & Graphics", "Tracy profiler GPU zone calibration for raylib."],
|
|
126
|
+
"result" => ["Core & Patterns", "Result[T, E] success/failure type for recoverable errors."],
|
|
127
|
+
"ring_buffer" => ["Collections", "Fixed-capacity circular buffer with overwrite behavior."],
|
|
128
|
+
"sdl3.runtime" => ["Game & Graphics", "SDL3 app lifecycle helpers and main-loop wrappers."],
|
|
129
|
+
"serialize" => ["Data & Serialization", "Struct field serialization helpers layered on std.binary."],
|
|
130
|
+
"set" => ["Collections", "Hash set of unique values."],
|
|
131
|
+
"signal" => ["Concurrency & Time", "Fixed-capacity observer and publish-subscribe signals."],
|
|
132
|
+
"simd" => ["Math & Simulation", "SIMD load, store, and reduction helpers."],
|
|
133
|
+
"sparse_set" => ["Collections", "Sparse set with dense iteration for integer-keyed data."],
|
|
134
|
+
"spatial" => ["Math & Simulation", "Uniform spatial hash grid for broad-phase queries."],
|
|
135
|
+
"stack" => ["Collections", "Last-in first-out stack."],
|
|
136
|
+
"steering" => ["AI & Behavior", "Craig Reynolds steering behaviors for autonomous motion."],
|
|
137
|
+
"stdio" => ["Files & System", "Stdin, stdout, and stderr FILE wrappers and console I/O."],
|
|
138
|
+
"str" => ["Text & Formatting", "Borrowed string slice helpers: length, compare, search, split."],
|
|
139
|
+
"string" => ["Text & Formatting", "Heap-owned growable string type with builder operations."],
|
|
140
|
+
"sync" => ["Concurrency & Time", "Mutex, condition variable, and once primitives over libuv."],
|
|
141
|
+
"tar" => ["Data & Serialization", "TAR archive reading and writing with 512-byte blocks."],
|
|
142
|
+
"terminal" => ["Files & System", "Terminal size, color, and raw-mode helpers."],
|
|
143
|
+
"thread" => ["Concurrency & Time", "Threads via libuv with join and handle management."],
|
|
144
|
+
"time" => ["Concurrency & Time", "Wall-clock timestamps and monotonic time helpers."],
|
|
145
|
+
"timer" => ["Concurrency & Time", "Countdown and repeating timers."],
|
|
146
|
+
"tls" => ["Security", "TLS client and server streams over libuv handles."],
|
|
147
|
+
"toml" => ["Data & Serialization", "TOML parser for configuration files."],
|
|
148
|
+
"tween" => ["Game & Graphics", "Tweening and easing for smooth value interpolation."],
|
|
149
|
+
"uri" => ["Data & Serialization", "URI parsing and construction, including file and web schemes."],
|
|
150
|
+
"url" => ["Data & Serialization", "URL parsing: scheme, host, path, query, and percent-encoding."],
|
|
151
|
+
"utility" => ["AI & Behavior", "Utility AI with score-based action selection."],
|
|
152
|
+
"vec" => ["Collections", "Growable contiguous array Vec[T], the default dynamic sequence."],
|
|
153
|
+
}.freeze
|
|
154
|
+
|
|
155
|
+
class << self
|
|
156
|
+
def std_root
|
|
157
|
+
File.join(MilkTea.root.to_s, "std")
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def entries
|
|
161
|
+
discover
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Resolves a module name ("mem.arena", "mem/arena", "c.cjson", "fs") to a
|
|
165
|
+
# source path. Prefers the active platform variant, matching the
|
|
166
|
+
# compiler's import resolution rule. Returns nil when unresolvable.
|
|
167
|
+
def resolve(name)
|
|
168
|
+
clean = name.to_s.strip
|
|
169
|
+
return nil if clean.empty? || clean.include?("..")
|
|
170
|
+
|
|
171
|
+
relative = clean.tr(".", "/").delete_suffix(".mt")
|
|
172
|
+
root = std_root
|
|
173
|
+
|
|
174
|
+
variant = File.join(root, "#{relative}.#{MilkTea.host_platform}.mt")
|
|
175
|
+
return variant if File.file?(variant)
|
|
176
|
+
|
|
177
|
+
shared = File.join(root, "#{relative}.mt")
|
|
178
|
+
return shared if File.file?(shared)
|
|
179
|
+
|
|
180
|
+
nil
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def discover
|
|
184
|
+
root = std_root
|
|
185
|
+
by_name = {}
|
|
186
|
+
|
|
187
|
+
module_files(root).each do |path|
|
|
188
|
+
add_module(by_name, logical_name(path), path)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
namespace_directories(root).each do |directory|
|
|
192
|
+
namespace = File.basename(directory)
|
|
193
|
+
module_files(directory).each do |path|
|
|
194
|
+
add_module(by_name, "#{namespace}.#{logical_name(path)}", path)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
by_name.values.sort_by(&:name)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def add_module(by_name, name, path)
|
|
202
|
+
return if generated?(path)
|
|
203
|
+
|
|
204
|
+
category, description = REGISTRY.fetch(name, [nil, nil])
|
|
205
|
+
description ||= doc_comment_summary(path)
|
|
206
|
+
entry = by_name[name]
|
|
207
|
+
unless entry
|
|
208
|
+
by_name[name] = Entry.new(name:, description:, category:, path:)
|
|
209
|
+
return
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
entry.path = path if prefer_path?(path, entry.path)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# A shared file beats any variant; among variants the host platform
|
|
216
|
+
# wins, then the first alphabetically.
|
|
217
|
+
def prefer_path?(candidate, current)
|
|
218
|
+
candidate_rank = path_rank(candidate)
|
|
219
|
+
current_rank = path_rank(current)
|
|
220
|
+
order = candidate_rank <=> current_rank
|
|
221
|
+
order.negative? || (order.zero? && candidate < current)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def path_rank(path)
|
|
225
|
+
host = MilkTea.host_platform.to_s
|
|
226
|
+
[platform_variant?(path) ? 1 : 0, platform_of(path) == host ? 0 : 1]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def module_files(directory)
|
|
230
|
+
Dir.glob(File.join(directory, "*.mt")).sort
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def namespace_directories(root)
|
|
234
|
+
Dir.children(root).map { |child| File.join(root, child) }
|
|
235
|
+
.select { |path| File.directory?(path) }
|
|
236
|
+
.reject { |path| EXCLUDED_DIRECTORIES.include?(File.basename(path)) }
|
|
237
|
+
.sort
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def logical_name(path)
|
|
241
|
+
stem = File.basename(path, ".mt")
|
|
242
|
+
platform = platform_of(path)
|
|
243
|
+
platform ? stem.delete_suffix(".#{platform}") : stem
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def platform_variant?(path)
|
|
247
|
+
PLATFORM_SUFFIXES.include?(platform_of(path))
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def platform_of(path)
|
|
251
|
+
stem = File.basename(path, ".mt")
|
|
252
|
+
suffix = stem[/\.([^.]+)\z/, 1]
|
|
253
|
+
suffix && PLATFORM_SUFFIXES.include?(suffix) ? suffix : nil
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def generated?(path)
|
|
257
|
+
File.open(path, "r") { |file| file.readline.start_with?(GENERATED_HEADER_PREFIX) }
|
|
258
|
+
rescue EOFError, Errno::ENOENT
|
|
259
|
+
false
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def doc_comment_summary(path)
|
|
263
|
+
File.foreach(path) do |line|
|
|
264
|
+
stripped = line.strip
|
|
265
|
+
next if stripped.empty?
|
|
266
|
+
|
|
267
|
+
return stripped.sub(/\A##\s?/, "").rstrip if stripped.start_with?("##")
|
|
268
|
+
|
|
269
|
+
break
|
|
270
|
+
end
|
|
271
|
+
nil
|
|
272
|
+
rescue Errno::ENOENT
|
|
273
|
+
nil
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
data/lib/milk_tea/tooling.rb
CHANGED
|
@@ -15,6 +15,7 @@ require_relative "tooling/error_formatter"
|
|
|
15
15
|
require_relative "tooling/formatter"
|
|
16
16
|
require_relative "tooling/linter"
|
|
17
17
|
require_relative "tooling/docs_app"
|
|
18
|
+
require_relative "tooling/std_catalog"
|
|
18
19
|
require_relative "tooling/project_scaffold"
|
|
19
20
|
require_relative "tooling/toolchain_cli"
|
|
20
21
|
require_relative "tooling/bindgen_cli"
|
data/std/async/libuv_runtime.mt
CHANGED
|
@@ -79,23 +79,22 @@ function work_as_req(work: ptr[NativeWorkRequest]) -> ptr[NativeRequest]:
|
|
|
79
79
|
return unsafe: ptr[NativeRequest]<-work
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
function close_all_handles_cb(handle: ptr[NativeHandle],
|
|
82
|
+
function close_all_handles_cb(handle: ptr[NativeHandle], _arg: ptr[void]) -> void:
|
|
83
83
|
if libuv.is_closing(handle) == 0:
|
|
84
84
|
libuv.close(handle, close_all_handles_close_cb)
|
|
85
|
-
unsafe: arg
|
|
86
85
|
|
|
87
86
|
|
|
88
|
-
function close_all_handles_close_cb(
|
|
89
|
-
|
|
87
|
+
function close_all_handles_close_cb(_handle: ptr[NativeHandle]) -> void:
|
|
88
|
+
pass
|
|
90
89
|
|
|
91
90
|
|
|
92
|
-
function noop_waiter(
|
|
93
|
-
|
|
91
|
+
function noop_waiter(_frame: ptr[void]) -> void:
|
|
92
|
+
pass
|
|
94
93
|
|
|
95
94
|
|
|
96
95
|
function require_current_runtime() -> Runtime:
|
|
97
96
|
if not current_runtime_active:
|
|
98
|
-
fatal(c"async runtime requires an active runtime; use async.wait or async.run, or call the
|
|
97
|
+
fatal(c"async runtime requires an active runtime; use async.wait or async.run, or call the *_on helpers")
|
|
99
98
|
return current_runtime
|
|
100
99
|
|
|
101
100
|
|
|
@@ -337,20 +336,19 @@ public function sleep_on(runtime: Runtime, timeout: ptr_uint) -> Task[int]:
|
|
|
337
336
|
let loop = live_loop(runtime)
|
|
338
337
|
|
|
339
338
|
let state = heap.must_alloc_zeroed[SleepState](1)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
state.released = false
|
|
339
|
+
state.ready = false
|
|
340
|
+
state.status = 0
|
|
341
|
+
state.waiter_frame = null
|
|
342
|
+
state.waiter = noop_waiter
|
|
343
|
+
state.waiter_registered = false
|
|
344
|
+
state.timer = null
|
|
345
|
+
state.closing = false
|
|
346
|
+
state.closed = false
|
|
347
|
+
state.released = false
|
|
350
348
|
|
|
351
349
|
let timer_size = libuv.handle_size(libuv.uv_handle_type.UV_TIMER)
|
|
352
350
|
let timer = unsafe: ptr[NativeTimerHandle]<-heap.must_alloc_zeroed_bytes(1, timer_size)
|
|
353
|
-
|
|
351
|
+
state.timer = timer
|
|
354
352
|
|
|
355
353
|
let init_status = libuv.timer_init(loop, timer)
|
|
356
354
|
if init_status != 0:
|
|
@@ -367,11 +365,10 @@ public function sleep_on(runtime: Runtime, timeout: ptr_uint) -> Task[int]:
|
|
|
367
365
|
|
|
368
366
|
let start_status = libuv.timer_start(timer, sleep_timer_fire, timeout, 0)
|
|
369
367
|
if start_status != 0:
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
libuv.close(timer_as_handle(timer), sleep_timer_close)
|
|
368
|
+
state.status = start_status
|
|
369
|
+
state.ready = true
|
|
370
|
+
state.closing = true
|
|
371
|
+
libuv.close(timer_as_handle(timer), sleep_timer_close)
|
|
375
372
|
|
|
376
373
|
return sleep_task(state)
|
|
377
374
|
|
data/std/async/mailbox.mt
CHANGED
|
@@ -45,8 +45,8 @@ function handle_as_async(handle: ptr[NativeHandle]) -> ptr[NativeAsyncHandle]:
|
|
|
45
45
|
return unsafe: ptr[NativeAsyncHandle]<-handle
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
function mailbox_async_callback(
|
|
49
|
-
|
|
48
|
+
function mailbox_async_callback(_handle: ptr[NativeAsyncHandle]) -> void:
|
|
49
|
+
pass
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
function mailbox_destroy_state[T](state_frame: ptr[void]) -> void:
|
data/std/base64.mt
CHANGED
|
@@ -163,18 +163,15 @@ public function decode(text_value: str) -> Result[bytes.Bytes, Error]:
|
|
|
163
163
|
|
|
164
164
|
let combined = (ulong<-raw0 << 18) | (ulong<-raw1 << 12) | (ulong<-raw2 << 6) | ulong<-raw3
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
read(output + out_index) = ubyte<-( (combined >> 16) & 0xFF)
|
|
166
|
+
read(output + out_index) = ubyte<-( (combined >> 16) & 0xFF)
|
|
168
167
|
out_index += 1
|
|
169
168
|
|
|
170
169
|
if out_index < output_len:
|
|
171
|
-
|
|
172
|
-
read(output + out_index) = ubyte<-( (combined >> 8) & 0xFF)
|
|
170
|
+
read(output + out_index) = ubyte<-( (combined >> 8) & 0xFF)
|
|
173
171
|
out_index += 1
|
|
174
172
|
|
|
175
173
|
if out_index < output_len:
|
|
176
|
-
|
|
177
|
-
read(output + out_index) = ubyte<-(combined & 0xFF)
|
|
174
|
+
read(output + out_index) = ubyte<-(combined & 0xFF)
|
|
178
175
|
out_index += 1
|
|
179
176
|
|
|
180
177
|
return Result[bytes.Bytes, Error].success(value = bytes.Bytes(data = output, len = output_len))
|
data/std/behavior_tree.mt
CHANGED
|
@@ -233,11 +233,8 @@ function tick_node[Context](tree: ref[Tree[Context]], node_id: ptr_uint, context
|
|
|
233
233
|
match child_status:
|
|
234
234
|
Status.success:
|
|
235
235
|
return Status.success
|
|
236
|
-
Status.failure:
|
|
237
|
-
return Status.running
|
|
238
|
-
Status.running:
|
|
236
|
+
Status.failure | Status.running:
|
|
239
237
|
return Status.running
|
|
240
|
-
|
|
241
238
|
NodeKind.until_failure:
|
|
242
239
|
let child_ptr = read(node).children.first() else:
|
|
243
240
|
return Status.failure
|
|
@@ -251,8 +248,6 @@ function tick_node[Context](tree: ref[Tree[Context]], node_id: ptr_uint, context
|
|
|
251
248
|
Status.running:
|
|
252
249
|
return Status.running
|
|
253
250
|
|
|
254
|
-
return Status.failure
|
|
255
|
-
|
|
256
251
|
|
|
257
252
|
extending Node[Context]:
|
|
258
253
|
static function create(kind: NodeKind) -> Node[Context]:
|
data/std/binary.mt
CHANGED
|
@@ -95,10 +95,7 @@ extending Writer:
|
|
|
95
95
|
|
|
96
96
|
|
|
97
97
|
public editable function write_bool(value: bool) -> void:
|
|
98
|
-
if value:
|
|
99
|
-
writer_append_byte(ref_of(this), 1)
|
|
100
|
-
else:
|
|
101
|
-
writer_append_byte(ref_of(this), 0)
|
|
98
|
+
if value: writer_append_byte(ref_of(this), 1) else: writer_append_byte(ref_of(this), 0)
|
|
102
99
|
|
|
103
100
|
|
|
104
101
|
public editable function write_bytes(data: span[ubyte]) -> void:
|
|
@@ -268,7 +265,7 @@ extending Reader:
|
|
|
268
265
|
|
|
269
266
|
public editable function read_span(count: ptr_uint) -> Result[span[ubyte], Error]:
|
|
270
267
|
if count == 0:
|
|
271
|
-
let empty =
|
|
268
|
+
let empty = span[ubyte](data = this.data.data, len = 0)
|
|
272
269
|
return Result[span[ubyte], Error].success(value = empty)
|
|
273
270
|
|
|
274
271
|
reader_check_remaining(ref_of(this), count)?
|
data/std/color.mt
CHANGED
|
@@ -51,7 +51,7 @@ function fmod(x: float, m: float) -> float:
|
|
|
51
51
|
# x - floor(x / m) * m
|
|
52
52
|
let div = x / m
|
|
53
53
|
let fl = float<-(int<-div)
|
|
54
|
-
if div < 0.0 and
|
|
54
|
+
if div < 0.0 and (int<-div) != div:
|
|
55
55
|
return x - (fl - 1.0) * m
|
|
56
56
|
return x - fl * m
|
|
57
57
|
|
|
@@ -143,9 +143,9 @@ extending Color:
|
|
|
143
143
|
|
|
144
144
|
|
|
145
145
|
public function to_hsl() -> (float, float, float):
|
|
146
|
-
let rf =
|
|
147
|
-
let gf =
|
|
148
|
-
let bf =
|
|
146
|
+
let rf = this.r / 255.0
|
|
147
|
+
let gf = this.g / 255.0
|
|
148
|
+
let bf = this.b / 255.0
|
|
149
149
|
|
|
150
150
|
let mx = fmax(fmax(rf, gf), bf)
|
|
151
151
|
let mn = fmin(fmin(rf, gf), bf)
|
|
@@ -171,9 +171,9 @@ extending Color:
|
|
|
171
171
|
|
|
172
172
|
|
|
173
173
|
public function to_hsv() -> (float, float, float):
|
|
174
|
-
let rf =
|
|
175
|
-
let gf =
|
|
176
|
-
let bf =
|
|
174
|
+
let rf = this.r / 255.0
|
|
175
|
+
let gf = this.g / 255.0
|
|
176
|
+
let bf = this.b / 255.0
|
|
177
177
|
|
|
178
178
|
let mx = fmax(fmax(rf, gf), bf)
|
|
179
179
|
let mn = fmin(fmin(rf, gf), bf)
|
|
@@ -198,10 +198,10 @@ extending Color:
|
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
public function lerp(target: Color, t: float) -> Color:
|
|
201
|
-
let r =
|
|
202
|
-
let g =
|
|
203
|
-
let b =
|
|
204
|
-
let a =
|
|
201
|
+
let r = this.r + (float<-target.r - float<-this.r) * t
|
|
202
|
+
let g = this.g + (float<-target.g - float<-this.g) * t
|
|
203
|
+
let b = this.b + (float<-target.b - float<-this.b) * t
|
|
204
|
+
let a = this.a + (float<-target.a - float<-this.a) * t
|
|
205
205
|
return Color(r = ubyte<-r, g = ubyte<-g, b = ubyte<-b, a = ubyte<-a)
|
|
206
206
|
|
|
207
207
|
|
|
@@ -211,12 +211,12 @@ extending Color:
|
|
|
211
211
|
if this.a == 255:
|
|
212
212
|
return this
|
|
213
213
|
|
|
214
|
-
let sa =
|
|
215
|
-
let da =
|
|
214
|
+
let sa = this.a / 255.0
|
|
215
|
+
let da = background.a / 255.0
|
|
216
216
|
|
|
217
|
-
let r_out =
|
|
218
|
-
let g_out =
|
|
219
|
-
let b_out =
|
|
217
|
+
let r_out = this.r * sa + background.r * da * (1.0 - sa)
|
|
218
|
+
let g_out = this.g * sa + background.g * da * (1.0 - sa)
|
|
219
|
+
let b_out = this.b * sa + background.b * da * (1.0 - sa)
|
|
220
220
|
let a_out = sa + da * (1.0 - sa)
|
|
221
221
|
|
|
222
222
|
return Color(
|
|
@@ -228,9 +228,9 @@ extending Color:
|
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
public function scale(factor: float) -> Color:
|
|
231
|
-
let r = fmin(fmax(
|
|
232
|
-
let g = fmin(fmax(
|
|
233
|
-
let b = fmin(fmax(
|
|
231
|
+
let r = fmin(fmax(this.r * factor, 0.0), 255.0)
|
|
232
|
+
let g = fmin(fmax(this.g * factor, 0.0), 255.0)
|
|
233
|
+
let b = fmin(fmax(this.b * factor, 0.0), 255.0)
|
|
234
234
|
return Color(r = ubyte<-r, g = ubyte<-g, b = ubyte<-b, a = this.a)
|
|
235
235
|
|
|
236
236
|
|
|
@@ -242,4 +242,4 @@ extending Color:
|
|
|
242
242
|
|
|
243
243
|
|
|
244
244
|
public function with_alpha(a: ubyte) -> Color:
|
|
245
|
-
return
|
|
245
|
+
return this.with(a = a)
|
data/std/cookie.mt
CHANGED
|
@@ -138,10 +138,7 @@ function ascii_lower(text_value: str) -> string.String:
|
|
|
138
138
|
var index: ptr_uint = 0
|
|
139
139
|
while index < text_value.len:
|
|
140
140
|
let value = text_value.byte_at(index)
|
|
141
|
-
if value >= 65 and value <= 90:
|
|
142
|
-
result.push_byte(value + 32)
|
|
143
|
-
else:
|
|
144
|
-
result.push_byte(value)
|
|
141
|
+
if value >= 65 and value <= 90: result.push_byte(value + 32) else: result.push_byte(value)
|
|
145
142
|
index += 1
|
|
146
143
|
|
|
147
144
|
return result
|
data/std/deque.mt
CHANGED
|
@@ -114,10 +114,7 @@ extending Deque[T]:
|
|
|
114
114
|
new_capacity = 4
|
|
115
115
|
|
|
116
116
|
while new_capacity < min_capacity:
|
|
117
|
-
if new_capacity > heap.ptr_uint_max / 2:
|
|
118
|
-
new_capacity = min_capacity
|
|
119
|
-
else:
|
|
120
|
-
new_capacity *= 2
|
|
117
|
+
if new_capacity > heap.ptr_uint_max / 2: new_capacity = min_capacity else: new_capacity *= 2
|
|
121
118
|
|
|
122
119
|
let new_data = heap.must_alloc[T](new_capacity)
|
|
123
120
|
let old_data = this.data
|
|
@@ -191,10 +188,7 @@ extending Deque[T]:
|
|
|
191
188
|
let data = this.data else:
|
|
192
189
|
fatal(c"deque.push_front missing storage")
|
|
193
190
|
|
|
194
|
-
if this.len == 0:
|
|
195
|
-
this.head = 0
|
|
196
|
-
else:
|
|
197
|
-
this.head = Deque[T].previous_index(this.head, this.capacity)
|
|
191
|
+
if this.len == 0: this.head = 0 else: this.head = Deque[T].previous_index(this.head, this.capacity)
|
|
198
192
|
|
|
199
193
|
unsafe:
|
|
200
194
|
let data_ptr = ptr[T]<-data
|
data/std/encoding.mt
CHANGED
|
@@ -26,10 +26,7 @@ public function utf8_codepoint_count(text: str) -> ptr_uint:
|
|
|
26
26
|
while index < text.len:
|
|
27
27
|
let b = text.byte_at(index)
|
|
28
28
|
let len = utf8_codepoint_length(b)
|
|
29
|
-
if len == 0:
|
|
30
|
-
index += 1
|
|
31
|
-
else:
|
|
32
|
-
index += len
|
|
29
|
+
if len == 0: index += 1 else: index += len
|
|
33
30
|
count += 1
|
|
34
31
|
|
|
35
32
|
if index != text.len:
|
data/std/fmt.mt
CHANGED
|
@@ -32,10 +32,7 @@ public function append_cstr(output: ref[string.String], c_text: cstr) -> void:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
public function append_bool(output: ref[string.String], bool_value: bool) -> void:
|
|
35
|
-
if bool_value:
|
|
36
|
-
output.append("true")
|
|
37
|
-
else:
|
|
38
|
-
output.append("false")
|
|
35
|
+
if bool_value: output.append("true") else: output.append("false")
|
|
39
36
|
|
|
40
37
|
|
|
41
38
|
function append_formatted_float(output: ref[string.String], format: cstr, number: double) -> void:
|
data/std/graph.mt
CHANGED
|
@@ -612,7 +612,11 @@ extending DenseGraph[T]:
|
|
|
612
612
|
return ShortestPaths(dist = dist, prev = prev)
|
|
613
613
|
|
|
614
614
|
|
|
615
|
-
public function astar(
|
|
615
|
+
public function astar(
|
|
616
|
+
source: ptr_uint,
|
|
617
|
+
target: ptr_uint,
|
|
618
|
+
heuristic: fn(node: ptr_uint) -> float
|
|
619
|
+
) -> vec.Vec[ptr_uint]:
|
|
616
620
|
var path = vec.Vec[ptr_uint].create()
|
|
617
621
|
let n = this.node_count()
|
|
618
622
|
if n == 0 or source >= n or target >= n:
|
data/std/htn.mt
CHANGED
|
@@ -110,7 +110,15 @@ function plan_task[World, Context](
|
|
|
110
110
|
|
|
111
111
|
for subtask_name_ptr in method.subtasks:
|
|
112
112
|
let subtask_name = unsafe: read(subtask_name_ptr)
|
|
113
|
-
let sub_plan = plan_task(
|
|
113
|
+
let sub_plan = plan_task(
|
|
114
|
+
planner,
|
|
115
|
+
context,
|
|
116
|
+
current_world,
|
|
117
|
+
subtask_name,
|
|
118
|
+
depth + 1,
|
|
119
|
+
iterations,
|
|
120
|
+
reason
|
|
121
|
+
)
|
|
114
122
|
match sub_plan:
|
|
115
123
|
Option.none:
|
|
116
124
|
success = false
|
data/std/http/server.mt
CHANGED
|
@@ -69,10 +69,7 @@ public function request_query_param(request: Request, key: str) -> Option[str]:
|
|
|
69
69
|
|
|
70
70
|
return Option[str].some(value = decoded.as_str())
|
|
71
71
|
|
|
72
|
-
if amp >= query_str.len:
|
|
73
|
-
start = query_str.len
|
|
74
|
-
else:
|
|
75
|
-
start = amp + 1
|
|
72
|
+
if amp >= query_str.len: start = query_str.len else: start = amp + 1
|
|
76
73
|
|
|
77
74
|
return Option[str].none
|
|
78
75
|
|