From b30711877db94f888a2648282740bd29bb1c95e0 Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Mon, 28 Sep 2026 22:34:19 +0300 Subject: [PATCH] ludic.ui: negative numbers' texts made once per value like the positive ones, big ones kept by value in a ring of 16 (mm_int made a string per call for every coordinate), and a stylesheet without a comment is not copied to strip one Found by the windowed walk's exit scan (mm_int 1.2 MB, lss_strip 451 KB unreachable). Co-Authored-By: Claude Opus 5.5 --- packages/ludic.ui/backend.ludic | 4 ++++ packages/ludic.ui/memo_join.ludic | 30 +++++++++++++++++++++++++++++- packages/ludic.ui/style.ludic | 7 +++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/ludic.ui/backend.ludic b/packages/ludic.ui/backend.ludic index e9eacd62..a77c1efc 100644 --- a/packages/ludic.ui/backend.ludic +++ b/packages/ludic.ui/backend.ludic @@ -39,6 +39,10 @@ export state UiState { uv_false: Val = null mm: UiMemo = null # memo.ludic: splits, gradients and keys by their text mm_ints: []string = null + mm_negs: []string = new []string # memo_join.ludic: negative numbers' texts, and the last big ones + mm_big_v: []int = new []int + mm_big_s: []string = new []string + mm_big_at: int = 0 fc_none: Val = Value.null() # focus.ludic: the value a key's down and up carry, made once mm_ivals: []Val = null ev_depth: int = 0 # eval.ludic: a call's arguments, in lists kept one a depth diff --git a/packages/ludic.ui/memo_join.ludic b/packages/ludic.ui/memo_join.ludic index 117cab86..558716b2 100644 --- a/packages/ludic.ui/memo_join.ludic +++ b/packages/ludic.ui/memo_join.ludic @@ -42,7 +42,8 @@ function mm_join(ui_st: mut UiState, a: string, sep: string, b: string) -> strin const MM_INT_MOST: int = 65536 @alloc_ok("a memo miss: a number's text made the first time it is shown") function mm_int(ui_st: mut UiState, i: int) -> string { - if i < 0 or i >= MM_INT_MOST { return string(i) } + if i < 0 and i > 0 - MM_INT_MOST { return mm_int_neg(ui_st, 0 - i) } + if i < 0 or i >= MM_INT_MOST { return mm_int_big(ui_st, i) } if ui_st.mm_ints == null { ui_st.mm_ints = new []string for k in 0 .. 1024 { push(ui_st.mm_ints, string(k)) } @@ -62,3 +63,30 @@ function mm_ival(ui_st: mut UiState, i: int) -> Val { } return ui_st.mm_ivals[i] } +# a negative whole number's text (a coordinate, a delta), made once per value like mm_int's +@alloc_ok("a memo miss: a negative number's text made the first time it is shown") +function mm_int_neg(ui_st: mut UiState, n: int) -> string { + let l = ui_st.mm_negs + while len(l) <= n { push(l, "") } + if len(l[n]) == 0 { l[n] = string(0 - n) } + return l[n] +} +# past MM_INT_MOST: the last MM_BIG seen, kept by value, so a number held for a while is made once +const MM_BIG: int = 16 +@alloc_ok("a number past the table: at most MM_BIG texts kept, replaced oldest first") +function mm_int_big(ui_st: mut UiState, i: int) -> string { + for k in 0 .. len(ui_st.mm_big_v) { + if ui_st.mm_big_v[k] == i { return ui_st.mm_big_s[k] } + } + let s = string(i) + if len(ui_st.mm_big_v) < MM_BIG { + push(ui_st.mm_big_v, i) + push(ui_st.mm_big_s, s) + } else { + let at = ui_st.mm_big_at % MM_BIG + ui_st.mm_big_v[at] = i + ui_st.mm_big_s[at] = s + ui_st.mm_big_at = at + 1 + } + return s +} diff --git a/packages/ludic.ui/style.ludic b/packages/ludic.ui/style.ludic index 88c5a824..07d32596 100644 --- a/packages/ludic.ui/style.ludic +++ b/packages/ludic.ui/style.ludic @@ -92,6 +92,7 @@ function lss_upto(r: UiRd, c: int) -> string { return out } function lss_strip(src: string) -> string { + if not lss_has_comment(src) { return src } # no comment: nothing to strip, nothing made var out = "" var at = 0 var i = 0 @@ -107,3 +108,9 @@ function lss_strip(src: string) -> string { if at < len(src) { out = out + src[at..len(src)] } return out } +function lss_has_comment(src: string) -> bool { + for i in 0 .. len(src) - 1 { + if src[i] == 47 and src[i + 1] == 42 { return true } + } + return false +}