# build.ludic - a template and the model, made into this frame's nodes. / and # are the template's own; a tag its file linked to a component is that one, # given its attributes as props (over the defaults its own tag gives: ), its on-* as what `emit` runs, and its content as . function bd_kids(ui_st: mut UiState, kids: []UiTpl, e0: UiEnv, key: string, out: []UiNode) -> void { var last_if = true var e = e0 for i in 0 .. len(kids) { let k = kids[i] ui_st.ui_at = k.where let ck = mm_join(ui_st, key, "/", mm_int(ui_st, i)) if k.tag == "state" or k.tag == "style" { continue } if k.tag == "let" { e = bd_let(ui_st, k, e) continue } if k.tag == "fragment" or k.tag == "#text" or (k.tag == "template" and tpl_attr(k, "slot") == null) { bd_group(ui_st, k, e, ck, out) } else if k.tag == "provide" { bd_provide(ui_st, k, e, ck, out) } else if k.tag == "template" { continue } else if k.tag == "if" { last_if = bd_test(ui_st, k, e) if last_if { bd_kids(ui_st, k.kids, e, ck, out) } } else if k.tag == "else" { if not last_if { bd_kids(ui_st, k.kids, e, ck, out) } last_if = true } else if k.tag == "each" { bd_each(ui_st, k, e, ck, out) } else if k.tag == "slot" { bd_slot(ui_st, k, e, ck, out) } else if not bd_comp(ui_st, k, e, ck, out) { ui_kept(out, bd_elem(ui_st, k, e, ck)) } } } function bd_test(ui_st: mut UiState, k: UiTpl, e: UiEnv) -> bool { let t = tpl_attr(k, "test") if t == null { ui_err(ui_st, " needs a test=\"{...}\"") return false } return ui_eval_bool(ui_st, t, e) } function bd_name(k: UiTpl, attr: string, dflt: string) -> string { let x = tpl_attr(k, attr) if x == null or x.op != X_LIT { return dflt } return Value.as_str(x.v) } function bd_each(ui_st: mut UiState, k: UiTpl, e: UiEnv, key: string, out: []UiNode) -> void { let src = tpl_attr(k, "in") if src == null { ui_err(ui_st, " needs an in=\"{...}\"") return } let list = ui_eval(ui_st, src, e) let as_name = bd_name(k, "as", "item") let at_name = bd_name(k, "index", "index") let by = tpl_attr(k, "key") for j in 0 .. Value.count(list) { let le = env_new(ui_st, e) env_bind(le, as_name, Value.at(list, j)) env_bind(le, at_name, mm_ival(ui_st, j)) var id = mm_int(ui_st, j) if by != null { id = ui_eval_text(ui_st, by, le) } bd_kids(ui_st, k.kids, le, mm_join(ui_st, key, "#", id), out) } } # is what the component's user put inside it; their