feat(stdlib): add String_Chars, String_FromBool, fix Fmt and Net
- String.bux: add String_Chars(s, index) for char-at-index access - String.bux: add String_FromBool(b) conversion - Fmt.bux: rewrite with correct stdlib imports (was using non-existent names) - Net.bux: fix String_Len -> bux_strlen (String_Len not imported) - All lib modules compile successfully
This commit is contained in:
+93
-35
@@ -1,42 +1,100 @@
|
|||||||
|
// Fmt.bux — String formatting with positional placeholders {0}, {1}, {2}...
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// Fmt_Fmt1("Hello, {0}!", "World")
|
||||||
|
// Fmt_FmtInt("Count: {0}", 42)
|
||||||
|
// Fmt_FmtBool("Active: {0}", true)
|
||||||
|
// Fmt_Fmt2("Name: {0}, Age: {1}", name, String_FromInt(age))
|
||||||
|
|
||||||
module Std::Fmt {
|
module Std::Fmt {
|
||||||
/* String formatting with positional placeholders {0}, {1}, {2}...
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* Fmt_Fmt1("Hello, {0}!", "World")
|
|
||||||
* Fmt_FmtInt("Count: {0}", 42)
|
|
||||||
* Fmt_FmtFloat("Pi: {0}", 3.14159)
|
|
||||||
* Fmt_FmtBool("Active: {0}", true)
|
|
||||||
* Fmt_Fmt2("Name: {0}, Age: {1}", name, String_FromInt(age))
|
|
||||||
*/
|
|
||||||
|
|
||||||
func Fmt_Fmt1(pattern: String, a: String) -> String {
|
import Std::String::{
|
||||||
return String_Format1(pattern, a);
|
String_Eq,
|
||||||
}
|
String_FromInt,
|
||||||
|
String_FromFloat,
|
||||||
|
String_FromBool,
|
||||||
|
StringBuilder,
|
||||||
|
StringBuilder_New,
|
||||||
|
StringBuilder_Append,
|
||||||
|
StringBuilder_Build,
|
||||||
|
String_Chars
|
||||||
|
};
|
||||||
|
|
||||||
func Fmt_Fmt2(pattern: String, a: String, b: String) -> String {
|
extern func bux_strlen(s: String) -> uint;
|
||||||
return String_Format2(pattern, a, b);
|
extern func bux_str_to_int(s: String) -> int64;
|
||||||
}
|
extern func bux_alloc(size: uint) -> *void;
|
||||||
|
|
||||||
func Fmt_Fmt3(pattern: String, a: String, b: String, c: String) -> String {
|
// Core formatting engine: replace {0}..{9} in template with args
|
||||||
return String_Format3(pattern, a, b, c);
|
func Fmt_Format(tmpl: String, argStrs: *String, argCount: int) -> String {
|
||||||
}
|
let sb: StringBuilder = StringBuilder_New();
|
||||||
|
var i: uint = 0;
|
||||||
func Fmt_FmtInt(pattern: String, n: int64) -> String {
|
let tmplLen: uint = bux_strlen(tmpl);
|
||||||
return String_Format1(pattern, String_FromInt(n));
|
while i < tmplLen {
|
||||||
}
|
// Check for {
|
||||||
|
let ch: String = String_Chars(tmpl, i);
|
||||||
func Fmt_FmtInt2(pattern: String, n1: int64, n2: int64) -> String {
|
if String_Eq(ch, "{") {
|
||||||
return String_Format2(pattern, String_FromInt(n1), String_FromInt(n2));
|
let digitIdx: uint = i + 1;
|
||||||
}
|
if digitIdx < tmplLen {
|
||||||
|
let digitCh: String = String_Chars(tmpl, digitIdx);
|
||||||
func Fmt_FmtFloat(pattern: String, f: float64) -> String {
|
let d: int64 = bux_str_to_int(digitCh);
|
||||||
return String_Format1(pattern, String_FromFloat(f));
|
if d >= 0 && d < argCount as int64 {
|
||||||
}
|
// Consume {d}
|
||||||
|
i = i + 2; // skip past digit
|
||||||
func Fmt_FmtBool(pattern: String, b: bool) -> String {
|
// Check for closing }
|
||||||
if b {
|
if i < tmplLen {
|
||||||
return String_Format1(pattern, "true");
|
let closeCh: String = String_Chars(tmpl, i);
|
||||||
|
if String_Eq(closeCh, "}") {
|
||||||
|
i = i + 1; // skip }
|
||||||
|
let argStr: String = *(argStrs + (d * 8) as uint);
|
||||||
|
StringBuilder_Append(&sb, argStr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Normal character: append it
|
||||||
|
StringBuilder_Append(&sb, ch);
|
||||||
|
i = i + 1;
|
||||||
}
|
}
|
||||||
return String_Format1(pattern, "false");
|
return StringBuilder_Build(&sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convenience wrappers
|
||||||
|
func Fmt_Fmt1(tmpl: String, a1: String) -> String {
|
||||||
|
var args: *String = bux_alloc(8) as *String;
|
||||||
|
*(args + 0) = a1;
|
||||||
|
return Fmt_Format(tmpl, args, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fmt_FmtInt(tmpl: String, val: int64) -> String {
|
||||||
|
let s: String = String_FromInt(val);
|
||||||
|
return Fmt_Fmt1(tmpl, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fmt_FmtBool(tmpl: String, val: bool) -> String {
|
||||||
|
let s: String = String_FromBool(val);
|
||||||
|
return Fmt_Fmt1(tmpl, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fmt_FmtFloat(tmpl: String, val: float64) -> String {
|
||||||
|
let s: String = String_FromFloat(val);
|
||||||
|
return Fmt_Fmt1(tmpl, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fmt_Fmt2(tmpl: String, a1: String, a2: String) -> String {
|
||||||
|
var args: *String = bux_alloc(16) as *String;
|
||||||
|
*(args + 0) = a1;
|
||||||
|
*(args + 8) = a2;
|
||||||
|
return Fmt_Format(tmpl, args, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fmt_Fmt3(tmpl: String, a1: String, a2: String, a3: String) -> String {
|
||||||
|
var args: *String = bux_alloc(24) as *String;
|
||||||
|
*(args + 0) = a1;
|
||||||
|
*(args + 8) = a2;
|
||||||
|
*(args + 16) = a3;
|
||||||
|
return Fmt_Format(tmpl, args, 3);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ func Net_Connect(fd: int, addr: String, port: int) -> bool {
|
|||||||
|
|
||||||
/* Send data. Returns bytes sent or -1 on error. */
|
/* Send data. Returns bytes sent or -1 on error. */
|
||||||
func Net_Send(fd: int, data: String) -> int {
|
func Net_Send(fd: int, data: String) -> int {
|
||||||
return bux_socket_send(fd, data, String_Len(data) as int);
|
return bux_socket_send(fd, data, bux_strlen(data) as int);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive up to maxLen bytes. Returns empty string on error/EOF. */
|
/* Receive up to maxLen bytes. Returns empty string on error/EOF. */
|
||||||
|
|||||||
@@ -161,6 +161,11 @@ func String_Join2(a: String, b: String, sep: String) -> String {
|
|||||||
// String find/replace/format
|
// String find/replace/format
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// String_Chars — return single-character string at index (for iteration)
|
||||||
|
func String_Chars(s: String, index: uint) -> String {
|
||||||
|
return bux_str_slice(s, index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
func String_Find(haystack: String, needle: String) -> String {
|
func String_Find(haystack: String, needle: String) -> String {
|
||||||
return bux_strstr(haystack, needle);
|
return bux_strstr(haystack, needle);
|
||||||
}
|
}
|
||||||
@@ -185,6 +190,11 @@ func String_ToFloat(s: String) -> float64 {
|
|||||||
return bux_str_to_float(s);
|
return bux_str_to_float(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func String_FromBool(b: bool) -> String {
|
||||||
|
if b { return "true"; }
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
|
||||||
func String_FromFloat(f: float64) -> String {
|
func String_FromFloat(f: float64) -> String {
|
||||||
return bux_float_to_string(f);
|
return bux_float_to_string(f);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user