Xml.free gives back a parsed tree's records and lists (never its strings) and the parser's cursor is freed; ludic.ui frees a template's XML once built, sel_parse's and ex_parse's readers, lss_rule's declarations holder, and px_cmp no longer makes a list of its operators per call
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3816d9924b
commit
7b20f305ff
8 changed files with 40 additions and 8 deletions
|
|
@ -40,7 +40,9 @@ function uc_load(ui_st: mut UiState, k: UiClass) -> void {
|
||||||
if k.lss != "" { lss_text(ui_st, f, k.lss) }
|
if k.lss != "" { lss_text(ui_st, f, k.lss) }
|
||||||
f.sheet = sheet_of(f)
|
f.sheet = sheet_of(f)
|
||||||
tp_lines(ui_st, k.xml)
|
tp_lines(ui_st, k.xml)
|
||||||
let root = tpl_read(ui_st, Xml.parse(k.xml), k.xml_path)
|
let doc = Xml.parse(k.xml)
|
||||||
|
let root = tpl_read(ui_st, doc, k.xml_path)
|
||||||
|
Xml.free(doc) # the template keeps the tree's strings, never its nodes
|
||||||
k.sheet = f.sheet
|
k.sheet = f.sheet
|
||||||
lib_link(ui_st, f, root)
|
lib_link(ui_st, f, root)
|
||||||
k.root = root
|
k.root = root
|
||||||
|
|
|
||||||
|
|
@ -48,10 +48,13 @@ function px_bin(op: string, a: UiExpr, b: UiExpr) -> UiExpr {
|
||||||
}
|
}
|
||||||
function px_cmp(r: UiRd) -> UiExpr {
|
function px_cmp(r: UiRd) -> UiExpr {
|
||||||
let a = px_sum(r)
|
let a = px_sum(r)
|
||||||
let ops = ["==", "!=", "<=", ">=", "<", ">"]
|
# literals, longest first: a list of them was made on every call
|
||||||
for k in 0 .. len(ops) {
|
if rd_op(r, "==") { return px_bin("==", a, px_sum(r)) }
|
||||||
if rd_op(r, ops[k]) { return px_bin(ops[k], a, px_sum(r)) }
|
if rd_op(r, "!=") { return px_bin("!=", a, px_sum(r)) }
|
||||||
}
|
if rd_op(r, "<=") { return px_bin("<=", a, px_sum(r)) }
|
||||||
|
if rd_op(r, ">=") { return px_bin(">=", a, px_sum(r)) }
|
||||||
|
if rd_op(r, "<") { return px_bin("<", a, px_sum(r)) }
|
||||||
|
if rd_op(r, ">") { return px_bin(">", a, px_sum(r)) }
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
function px_sum(r: UiRd) -> UiExpr {
|
function px_sum(r: UiRd) -> UiExpr {
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ function ex_parse(src: string, err: []string) -> UiExpr {
|
||||||
rd_ws(r)
|
rd_ws(r)
|
||||||
if r.err == "" and r.i < len(r.s) { rd_fail(r, "the end") }
|
if r.err == "" and r.i < len(r.s) { rd_fail(r, "the end") }
|
||||||
if r.err != "" { push(err, r.err) }
|
if r.err != "" { push(err, r.err) }
|
||||||
|
unsafe { free(r) } # the reader only: what the expression keeps is copied out
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
# text with {holes}: a literal when it has none, the expression itself when it is one hole and
|
# text with {holes}: a literal when it has none, the expression itself when it is one hole and
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,9 @@ function lib_read(ui_st: mut UiState, src: string, path: string) -> UiFile {
|
||||||
let f = lib_new(ui_st, path)
|
let f = lib_new(ui_st, path)
|
||||||
f.src = src
|
f.src = src
|
||||||
tp_lines(ui_st, src)
|
tp_lines(ui_st, src)
|
||||||
let root = tpl_read(ui_st, Xml.parse(src), path)
|
let doc = Xml.parse(src)
|
||||||
|
let root = tpl_read(ui_st, doc, path)
|
||||||
|
Xml.free(doc) # the template keeps the tree's strings, never its nodes
|
||||||
var tops = root.kids
|
var tops = root.kids
|
||||||
if root.tag != "ui" { tops = [root] }
|
if root.tag != "ui" { tops = [root] }
|
||||||
for i in 0 .. len(tops) { lib_top(ui_st, f, tops[i]) }
|
for i in 0 .. len(tops) { lib_top(ui_st, f, tops[i]) }
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ function sel_parse(src: string, err: []string) -> UiSel {
|
||||||
comb = 0
|
comb = 0
|
||||||
}
|
}
|
||||||
if r.err != "" { push(err, r.err) }
|
if r.err != "" { push(err, r.err) }
|
||||||
|
unsafe { free(r) } # the reader only: every name read from it is a copy
|
||||||
|
@alloc_ok("only when a template is wrong: a broken screen, never a working one")
|
||||||
if cur == null { push(err, `"{src}" selects nothing`) }
|
if cur == null { push(err, `"{src}" selects nothing`) }
|
||||||
return cur
|
return cur
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@ function lss_rule(f: UiFile, sels: string, body: string, err: []string) -> void
|
||||||
free(each[i])
|
free(each[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe { free(each) }
|
unsafe {
|
||||||
|
free(each)
|
||||||
|
free(decls) # the holder only: each rule keeps its keys and values lists
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function lss_rule_add(f: UiFile, decls: UiRule, sel: string, err: []string) -> void {
|
function lss_rule_add(f: UiFile, decls: UiRule, sel: string, err: []string) -> void {
|
||||||
let r = new UiRule
|
let r = new UiRule
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,7 @@ namespace Json {
|
||||||
}
|
}
|
||||||
namespace Xml {
|
namespace Xml {
|
||||||
alias parse(text) = xml_parse
|
alias parse(text) = xml_parse
|
||||||
|
alias free(node) = xml_free # the tree's records and lists; its strings are kept
|
||||||
alias tag(node) = xml_tag
|
alias tag(node) = xml_tag
|
||||||
alias text(node) = xml_text
|
alias text(node) = xml_text
|
||||||
alias attr(node, key) = xml_attr
|
alias attr(node, key) = xml_attr
|
||||||
|
|
|
||||||
|
|
@ -322,8 +322,26 @@ function xml_parse(rt_xml_st: mut RtXmlState, s: pointer) -> Xml {
|
||||||
if p.i >= p.n { break }
|
if p.i >= p.n { break }
|
||||||
if p.s[p.i] == '<' { # '<'
|
if p.s[p.i] == '<' { # '<'
|
||||||
if xp_skip_misc(p) { } # prolog / comment / doctype
|
if xp_skip_misc(p) { } # prolog / comment / doctype
|
||||||
else { return xp_element(rt_xml_st, p) }
|
else {
|
||||||
|
let root = xp_element(rt_xml_st, p)
|
||||||
|
free(p)
|
||||||
|
return root
|
||||||
|
}
|
||||||
} else { p.i += 1 }
|
} else { p.i += 1 }
|
||||||
}
|
}
|
||||||
|
free(p)
|
||||||
return xml_new("")
|
return xml_new("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# the tree's records and lists given back once a reader has built what it keeps from it; its
|
||||||
|
# strings (tags, text, names, values) are not, since what was built may hold them. Every element
|
||||||
|
# is in its parent's `mixed`, with the runs of text
|
||||||
|
function xml_free(n: Xml) -> void {
|
||||||
|
if n == null { return }
|
||||||
|
for i in 0 .. len(n.mixed) { xml_free(n.mixed[i]) }
|
||||||
|
free(n.akeys)
|
||||||
|
free(n.avals)
|
||||||
|
free(n.kids)
|
||||||
|
free(n.mixed)
|
||||||
|
free(n)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue