std: restructure — std/ modules, namespace tail, std/xml.sx
allocators/fs/process/socket/log/trace/test move under modules/std/ (allocators.sx becomes std/mem.sx; the Allocator protocol moves into the std.sx prelude, impls stay in mem.sx). New std/xml.sx holds xml_escape as xml.escape. std.sx gains the carried namespace tail — flat-importing std.sx now also provides mem./xml./log. — with the remaining modules (fs/process/socket/json/cli/hash/test) deferred from the tail until the global last-wins maps are fully own-wins (pulling them into every closure collides bare names corpus-wide; they stay direct imports: modules/std/fs.sx etc.). log.sx's internal emit renamed log_emit (it clobbered consumer fns named emit program-wide). bundle.sx uses xml.escape via the carried alias. Consumer import paths swept mechanically; .ir snapshots recaptured for the larger std closure. m3te + game build unchanged.
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
// the Metal backend takes — caller branches on OS).
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/opengl.sx";
|
||||
#import "modules/gpu/types.sx";
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// non-iOS targets don't reach the Metal-touching code paths.
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/std/objc.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/gpu/types.sx";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "../std.sx";
|
||||
#import "../compiler.sx";
|
||||
#import "../fs.sx";
|
||||
#import "../process.sx";
|
||||
#import "../std/fs.sx";
|
||||
#import "../std/process.sx";
|
||||
|
||||
// =====================================================================
|
||||
// platform.bundle — sx-side Apple `.app` bundler.
|
||||
@@ -269,7 +269,7 @@ build_info_plist :: (opts: BuildOptions, exe_name: string, bundle_id: string) ->
|
||||
<string>{}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST, xml_escape(bundle_id), xml_escape(exe_name), xml_escape(exe_name), IOS_MIN_OS, platform_key);
|
||||
PLIST, xml.escape(bundle_id), xml.escape(exe_name), xml.escape(exe_name), IOS_MIN_OS, platform_key);
|
||||
}
|
||||
|
||||
// macOS (and any non-iOS Apple target) — the minimal plist both
|
||||
@@ -293,7 +293,7 @@ PLIST, xml_escape(bundle_id), xml_escape(exe_name), xml_escape(exe_name), IOS_MI
|
||||
<string>0.1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST, xml_escape(bundle_id), xml_escape(exe_name), xml_escape(exe_name))
|
||||
PLIST, xml.escape(bundle_id), xml.escape(exe_name), xml.escape(exe_name))
|
||||
}
|
||||
|
||||
// Read a `.mobileprovision` and write it to
|
||||
@@ -868,15 +868,15 @@ lib_name_from_so_basename :: (basename: string) -> string {
|
||||
// Otherwise it falls back to the legacy NativeActivity shape with an
|
||||
// `android.app.lib_name` meta-data entry pointing at the .so.
|
||||
build_android_manifest :: (opts: BuildOptions, package: string, lib_name: string) -> string {
|
||||
pkg_esc := xml_escape(package);
|
||||
lib_esc := xml_escape(lib_name);
|
||||
pkg_esc := xml.escape(package);
|
||||
lib_esc := xml.escape(lib_name);
|
||||
if opts.jni_main_count() > 0 {
|
||||
// First `#jni_main` decl drives the Activity. The foreign_path
|
||||
// uses `/` separators; Java fully-qualified class names use
|
||||
// `.` so we rewrite.
|
||||
foreign := opts.jni_main_foreign_path_at(0);
|
||||
cls := slash_to_dot(foreign);
|
||||
cls_esc := xml_escape(cls);
|
||||
cls_esc := xml.escape(cls);
|
||||
return format(#string MANIFEST
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/opengl.sx";
|
||||
#import "modules/sdl3.sx";
|
||||
|
||||
@@ -36,7 +36,14 @@ Source_Location :: struct {
|
||||
}
|
||||
string :: []u8 #builtin;
|
||||
|
||||
#import "allocators.sx";
|
||||
#import "std/mem.sx";
|
||||
|
||||
// --- Allocator protocol (impls live in std/mem.sx) ---
|
||||
|
||||
Allocator :: protocol #inline {
|
||||
alloc :: (size: s64) -> *void;
|
||||
dealloc :: (ptr: *void);
|
||||
}
|
||||
|
||||
// --- Context ---
|
||||
|
||||
@@ -215,37 +222,6 @@ substr :: (s: string, start: s64, len: s64) -> string {
|
||||
buf
|
||||
}
|
||||
|
||||
// Replace XML special characters with their entity references. Used
|
||||
// when emitting Info.plist / AndroidManifest content from sx values
|
||||
// that may contain user-supplied text (bundle id, app name, etc).
|
||||
xml_escape :: (s: string) -> string {
|
||||
result := "";
|
||||
i := 0;
|
||||
seg_start := 0;
|
||||
while i < s.len {
|
||||
c := s[i];
|
||||
// 38='&', 60='<', 62='>', 34='"', 39='\''
|
||||
ent := "";
|
||||
if c == 38 { ent = "&"; }
|
||||
if c == 60 { ent = "<"; }
|
||||
if c == 62 { ent = ">"; }
|
||||
if c == 34 { ent = """; }
|
||||
if c == 39 { ent = "'"; }
|
||||
if ent.len > 0 {
|
||||
if i > seg_start {
|
||||
result = concat(result, substr(s, seg_start, i - seg_start));
|
||||
}
|
||||
result = concat(result, ent);
|
||||
seg_start = i + 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
if seg_start < s.len {
|
||||
result = concat(result, substr(s, seg_start, s.len - seg_start));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
// Join path components with the POSIX separator ('/'). Skips empty
|
||||
// components and collapses duplicate separators at component
|
||||
// boundaries. Used for bundle paths where Apple .app and Android APK
|
||||
@@ -513,4 +489,13 @@ List :: struct ($T: Type) {
|
||||
list.len = 0;
|
||||
list.cap = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- The stdlib namespace tail: flat-importing std.sx carries these ---
|
||||
|
||||
mem :: #import "std/mem.sx";
|
||||
xml :: #import "std/xml.sx";
|
||||
log :: #import "std/log.sx";
|
||||
// fs/process/socket/json/cli/hash/test join the tail once the global
|
||||
// last-wins maps are fully own-wins (their decls collide across programs
|
||||
// when pulled into every closure) — import them directly meanwhile:
|
||||
// #import "modules/std/fs.sx"; etc.
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/compiler.sx";
|
||||
proc :: #import "modules/process.sx";
|
||||
proc :: #import "modules/std/process.sx";
|
||||
|
||||
libc :: #library "c";
|
||||
|
||||
@@ -54,7 +54,7 @@ ns_get_argc :: () -> *s32 #foreign libc "_NSGetArgc";
|
||||
// value), `EX_UNAVAILABLE` when the platform is unsupported.
|
||||
// 2. TERMINATORS. `exit_ok()` / `exit_usage()` end the process with the
|
||||
// matching code. They route through the canonical
|
||||
// `process.exit(code: u8)` (modules/process.sx) — there is NO second
|
||||
// `process.exit(code: u8)` (modules/std/process.sx) — there is NO second
|
||||
// hand-rolled `_exit` binding in this module; the unsupported-platform
|
||||
// path below goes through `proc.exit(EX_UNAVAILABLE)` too.
|
||||
//
|
||||
@@ -62,7 +62,7 @@ ns_get_argc :: () -> *s32 #foreign libc "_NSGetArgc";
|
||||
// `parsed.json` (true iff `--json` appears in the argv — see `Parsed.json`).
|
||||
// The convention a front-end follows: in json mode stdout carries ONLY the
|
||||
// machine result, and human diagnostics go to stderr (e.g. via
|
||||
// `modules/log.sx`'s `log.err`). Detect json mode by reading `parsed.json`.
|
||||
// `modules/std/log.sx`'s `log.err`). Detect json mode by reading `parsed.json`.
|
||||
// =====================================================================
|
||||
|
||||
EX_OK :u8: 0; // success
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "std.sx";
|
||||
#import "modules/std.sx";
|
||||
|
||||
// =====================================================================
|
||||
// fs.sx — file system stdlib (POSIX backend, macOS values).
|
||||
@@ -31,7 +31,7 @@
|
||||
// =====================================================================
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/fs.sx";
|
||||
#import "modules/std/fs.sx";
|
||||
|
||||
// Low 32 bits. SHA-256 is defined over 32-bit words; every add/rotate
|
||||
// result is masked back through this so the carry never escapes bit 31.
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
#import "modules/std.sx";
|
||||
// `Array`/`Object` methods take an explicit `alloc: Allocator`; bare-import
|
||||
// visibility is non-transitive, so the module that names the type imports it.
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/fs.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/std/fs.sx";
|
||||
|
||||
// The writer's failure contract: a too-small caller buffer (Overflow) or
|
||||
// a short/failed file write (Io). Surfaced on the error channel — never a
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "std.sx";
|
||||
#import "modules/std.sx";
|
||||
|
||||
// =====================================================================
|
||||
// log.sx — plain leveled logging (ERR step E4.1), orthogonal to the
|
||||
@@ -18,12 +18,12 @@ libc :: #library "c";
|
||||
write :: (fd: s32, buf: [*]u8, count: usize) -> isize #foreign libc;
|
||||
|
||||
// Prefix the level, append a newline, write the whole line to stderr.
|
||||
emit :: (level: string, msg: string) {
|
||||
log_emit :: (level: string, msg: string) {
|
||||
line := concat(concat(level, msg), "\n");
|
||||
write(2, line.ptr, xx line.len);
|
||||
}
|
||||
|
||||
warn :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "emit(\"WARN: \", result);"; }
|
||||
info :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "emit(\"INFO: \", result);"; }
|
||||
debug :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "emit(\"DEBUG: \", result);"; }
|
||||
err :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "emit(\"ERROR: \", result);"; }
|
||||
warn :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "log_emit(\"WARN: \", result);"; }
|
||||
info :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "log_emit(\"INFO: \", result);"; }
|
||||
debug :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "log_emit(\"DEBUG: \", result);"; }
|
||||
err :: ($fmt: string, ..$args) { #insert build_format(fmt); #insert "log_emit(\"ERROR: \", result);"; }
|
||||
@@ -1,11 +1,4 @@
|
||||
#import "std.sx";
|
||||
|
||||
// --- Allocator protocol (inline: ctx + fn-ptrs, no vtable indirection) ---
|
||||
|
||||
Allocator :: protocol #inline {
|
||||
alloc :: (size: s64) -> *void;
|
||||
dealloc :: (ptr: *void);
|
||||
}
|
||||
#import "modules/std.sx";
|
||||
|
||||
// --- CAllocator: stateless allocator that delegates directly to libc ---
|
||||
//
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "std.sx";
|
||||
trace :: #import "trace.sx";
|
||||
#import "modules/std.sx";
|
||||
trace :: #import "modules/std/trace.sx";
|
||||
|
||||
// =====================================================================
|
||||
// process.sx — subprocess + environment stdlib (POSIX backend).
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "std.sx";
|
||||
#import "modules/std.sx";
|
||||
|
||||
assert :: (condition: bool) {
|
||||
if !condition {
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "std.sx";
|
||||
#import "modules/std.sx";
|
||||
|
||||
// =====================================================================
|
||||
// trace.sx — error return-trace formatting (ERR step E3.3).
|
||||
32
library/modules/std/xml.sx
Normal file
32
library/modules/std/xml.sx
Normal file
@@ -0,0 +1,32 @@
|
||||
// XML helpers. `escape` replaces XML special characters with entity
|
||||
// references — used when emitting Info.plist / AndroidManifest content
|
||||
// from sx values that may contain user-supplied text.
|
||||
#import "modules/std.sx";
|
||||
|
||||
escape :: (s: string) -> string {
|
||||
result := "";
|
||||
i := 0;
|
||||
seg_start := 0;
|
||||
while i < s.len {
|
||||
c := s[i];
|
||||
// 38='&', 60='<', 62='>', 34='"', 39='\''
|
||||
ent := "";
|
||||
if c == 38 { ent = "&"; }
|
||||
if c == 60 { ent = "<"; }
|
||||
if c == 62 { ent = ">"; }
|
||||
if c == 34 { ent = """; }
|
||||
if c == 39 { ent = "'"; }
|
||||
if ent.len > 0 {
|
||||
if i > seg_start {
|
||||
result = concat(result, substr(s, seg_start, i - seg_start));
|
||||
}
|
||||
result = concat(result, ent);
|
||||
seg_start = i + 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
if seg_start < s.len {
|
||||
result = concat(result, substr(s, seg_start, s.len - seg_start));
|
||||
}
|
||||
result
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/math";
|
||||
#import "modules/ui/types.sx";
|
||||
#import "modules/ui/render.sx";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/opengl.sx";
|
||||
#import "modules/gpu/types.sx";
|
||||
#import "modules/gpu/api.sx";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
#import "modules/ui/glyph_cache.sx"; // `font: GlyphCache` — name it, import it (non-transitive).
|
||||
#import "modules/opengl.sx";
|
||||
#import "modules/gpu/api.sx";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/allocators.sx";
|
||||
#import "modules/std/mem.sx";
|
||||
|
||||
// --- State(T) — a handle to persistent storage ---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user