From b3b50ca260bfb634ebdfc66dab9186b504602236 Mon Sep 17 00:00:00 2001 From: Kacy Fortner Date: Tue, 7 Jul 2026 23:25:33 +0000 Subject: [PATCH] replace an outgrown sort idiom; name the format-spec bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit two small readability payments from the elegance sprint's safe list. logscan's sorted_keys carried a twelve-line insertion sort that predates working ordered string comparison — the sort existed because list.sort() couldn't be trusted before the pointer-compare fix. it is now m.keys().sort(), and the golden check proves the output unchanged. the format-spec lowering used bare byte values for alignment and fill characters; they now carry names (ALIGN_LEFT_BYTE and friends), so the code says what the 60 meant. --- self-host/bootstrap/ir_driver.ir | 15 ++++++++----- self-host/ir_emitter_core.pith | 16 +++++++++----- tools/logscan/logscan_lib.pith | 37 +++++++++++--------------------- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/self-host/bootstrap/ir_driver.ir b/self-host/bootstrap/ir_driver.ir index 79774bd..c0047e8 100644 --- a/self-host/bootstrap/ir_driver.ir +++ b/self-host/bootstrap/ir_driver.ir @@ -91687,6 +91687,11 @@ global ir_emitter_core_ir_active_generic_params list global ir_emitter_core_ir_active_generic_concrete_types list global ir_emitter_core_ir_active_generic_module_path str:m41s72 global ir_emitter_core_ir_current_arc_func str:m41s72 +global ir_emitter_core_ALIGN_LEFT_BYTE 60 +global ir_emitter_core_ALIGN_CENTER_BYTE 94 +global ir_emitter_core_ALIGN_RIGHT_BYTE 62 +global ir_emitter_core_FILL_ZERO_BYTE 48 +global ir_emitter_core_FILL_SPACE_BYTE 32 global ir_emitter_core_ir_tail_match_node 0 func ir_emitter_core___init_globals_41 0 int call 0 pith_map_new_default map 0 @@ -102410,7 +102415,7 @@ call 9 pith_cstring_eq bool 2 7 8 call 10 pith_cstring_release void 1 8 brif 9 L1050 L1051 label L1050 -iconst 11 60 +load 11 ir_emitter_core_ALIGN_LEFT_BYTE load 12 c0 call 13 pith_cstring_release void 1 12 ret 11 @@ -102422,13 +102427,13 @@ call 16 pith_cstring_eq bool 2 14 15 call 17 pith_cstring_release void 1 15 brif 16 L1053 L1054 label L1053 -iconst 18 94 +load 18 ir_emitter_core_ALIGN_CENTER_BYTE load 19 c0 call 20 pith_cstring_release void 1 19 ret 18 label L1054 label L1052 -iconst 21 62 +load 21 ir_emitter_core_ALIGN_RIGHT_BYTE load 22 c0 call 23 pith_cstring_release void 1 22 ret 21 @@ -102484,13 +102489,13 @@ call 33 pith_cstring_release void 1 30 and 34 26 31 brif 34 L1059 L1060 label L1059 -iconst 35 48 +load 35 ir_emitter_core_FILL_ZERO_BYTE load 36 c0 call 37 pith_cstring_release void 1 36 ret 35 label L1060 label L1058 -iconst 38 32 +load 38 ir_emitter_core_FILL_SPACE_BYTE load 39 c0 call 40 pith_cstring_release void 1 39 ret 38 diff --git a/self-host/ir_emitter_core.pith b/self-host/ir_emitter_core.pith index 7da9999..0115b84 100644 --- a/self-host/ir_emitter_core.pith +++ b/self-host/ir_emitter_core.pith @@ -1483,13 +1483,19 @@ fn ir_interp_spec_precision(spec: String) -> Int: i = i + 1 return p +ALIGN_LEFT_BYTE := 60 # '<' +ALIGN_CENTER_BYTE := 94 # '^' +ALIGN_RIGHT_BYTE := 62 # '>' +FILL_ZERO_BYTE := 48 # '0' +FILL_SPACE_BYTE := 32 # ' ' + fn ir_interp_spec_align(spec: String) -> Int: c0 := spec[0] if c0 == "<": - return 60 + return ALIGN_LEFT_BYTE if c0 == "^": - return 94 - return 62 + return ALIGN_CENTER_BYTE + return ALIGN_RIGHT_BYTE fn ir_interp_spec_fill(spec: String) -> Int: mut i := 0 @@ -1497,8 +1503,8 @@ fn ir_interp_spec_fill(spec: String) -> Int: if c0 == "<" or c0 == ">" or c0 == "^": i = 1 if i < spec.len() and spec[i] == "0": - return 48 - return 32 + return FILL_ZERO_BYTE + return FILL_SPACE_BYTE fn ir_emit_interp_spec_part(node: Node) -> Int: spec := node.value diff --git a/tools/logscan/logscan_lib.pith b/tools/logscan/logscan_lib.pith index 19952a0..4662a46 100644 --- a/tools/logscan/logscan_lib.pith +++ b/tools/logscan/logscan_lib.pith @@ -8,7 +8,7 @@ import std.compress.gzip as gzip import std.data.table as table import std.regex as regex -## one parsed access-log line. +# # one parsed access-log line. pub struct Hit: ip: String stamp: String @@ -18,8 +18,8 @@ pub struct Hit: size: Int millis: Int -## the whole analysis: parsed hits plus the derived aggregates the -## report and csv export read. +# # the whole analysis: parsed hits plus the derived aggregates the +# # report and csv export read. pub struct Report: total: Int parse_errors: Int @@ -33,19 +33,19 @@ pub struct Report: # combined-log-ish format: # 127.0.0.1 - - [06/Jul/2026:14:03:22] "GET /path HTTP/1.1" 200 512 45 -## the line grammar as one pattern: ip, bracketed stamp, quoted -## request (method and path captured), then status, size, and millis. +# # the line grammar as one pattern: ip, bracketed stamp, quoted +# # request (method and path captured), then status, size, and millis. pub fn line_pattern() -> Regex!: q := chr(34) return regex.compile("^([^ ]+) [^ ]+ [^ ]+ \\[([^\\]]+)\\] " + q + "([^ ]+) ([^ " + q + "]+)[^" + q + "]*" + q + " (\\d+) (\\d+) (\\d+)") -## parse one log line; none when the line is malformed. +# # parse one log line; none when the line is malformed. pub fn parse_line(re: Regex, line: String) -> Hit?: caps := re.captures(line) if caps == none: return none if let c = caps: - status := parse_int(c[5]) catch -1 + status := parse_int(c[5]) catch - 1 if status < 0: return none size := parse_int(c[6]) catch 0 @@ -71,8 +71,8 @@ fn hour_of(stamp: String) -> String: # --- aggregation ------------------------------------------------------- -## read a log (gzip-decompressed when the path ends in .gz) and fold -## every line into a report. +# # read a log (gzip-decompressed when the path ends in .gz) and fold +# # every line into a report. pub fn analyze_file(path: String) -> Report!: mut text := "" if path.ends_with(".gz"): @@ -82,7 +82,7 @@ pub fn analyze_file(path: String) -> Report!: text = fs.read(path)! return analyze_text(text) -## fold raw log text into a report. +# # fold raw log text into a report. pub fn analyze_text(text: String) -> Report: mut by_class: Map[String, Int] := {} mut by_path_hits: Map[String, Int] := {} @@ -129,7 +129,7 @@ fn top_paths(r: Report, n: Int) -> List[String]: # --- output ------------------------------------------------------------ -## the human-readable summary printed by the cli. +# # the human-readable summary printed by the cli. pub fn render_report(r: Report) -> String: nl := chr(10) mut out := "requests: " + r.total.to_string() + " malformed: " + r.parse_errors.to_string() + " bytes: " + r.bytes_served.to_string() + nl @@ -147,20 +147,9 @@ pub fn render_report(r: Report) -> String: return out fn sorted_keys(m: Map[String, Int]) -> List[String]: - mut ks: List[String] := [] - for k in m.keys(): - mut placed := false - mut i := 0 - while i < ks.len() and not placed: - if k < ks[i]: - ks.insert(i, k) - placed = true - i = i + 1 - if not placed: - ks.push(k) - return ks + return m.keys().sort() -## per-path stats as csv, via the data.table module. +# # per-path stats as csv, via the data.table module. pub fn export_csv(r: Report) -> String: mut rows: List[List[String]] := [] for p in top_paths(r, 1000000):