feat(lang): L11 views and templates - the UI is markup, not code
A `view Name { field = x; function q(..); on e(..) }` declaration is the one bridge between a
program and its UI: it writes view_<name>() -> UiView, whose model is a Value of every field and
whose call runs a query or an event by name.
ludic.ui is a template runtime:
- HTML-shaped XML screens and components, loaded at run time;
- {expression} bindings, if/else/each, props, slots, per-instance state;
- on-press / onclick actions (event, set, emit);
- component libraries (export="true", <import src as>).
Styling:
- stylesheets in <style> or importable .lss files (@import);
- CSS selectors (#id, .class, [attr=v], descendant and > combinators, :hover, :disabled,
:first-child, :last-child, :nth-child, :not) weighed by specificity;
- the box model and flex under CSS's property names.
Also:
- default parameters, and positional-then-named calls;
- Value gains a float kind;
- a function shadowing a runtime one is refused;
- an index is evaluated before the slice is read;
- runtime errors name the right file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
334469ef61
commit
66a2bc2214
64 changed files with 74806 additions and 63975 deletions
|
|
@ -577,7 +577,9 @@ function parse_fn() -> Node {
|
|||
eat_op("(")
|
||||
if is_reserved_word(n.s) { perr(`'{n.s}' is a reserved word and cannot name a function`) }
|
||||
while not is_op(")") {
|
||||
let p = node(N_PARAM); p.s = eat_id(); eat_op(":"); p.ty = ptype(); push(n.kids, p)
|
||||
let p = node(N_PARAM); p.s = eat_id(); eat_op(":"); p.ty = ptype()
|
||||
if is_op("=") { pi += 1; p.a = expr() } # L11: a default, for a call that leaves it out
|
||||
push(n.kids, p)
|
||||
if is_op(",") { pi += 1 }
|
||||
}
|
||||
eat_op(")")
|
||||
|
|
@ -1014,6 +1016,7 @@ function parse_one_decl() -> void {
|
|||
if is_id("namespace") { parse_namespace(); return } # #76 namespace block
|
||||
if is_id("registry") and (toks[pi + 1].kind == TK_ID) and (toks[pi + 2].text == "of") { parse_registry(); return } # L8
|
||||
if is_id("def") and (toks[pi + 1].kind == TK_ID) and (toks[pi + 2].kind == TK_ID) { parse_def(); return } # L8
|
||||
if is_id("view") and (toks[pi + 1].kind == TK_ID) and (toks[pi + 2].text == "{") { parse_view(); return } # L11
|
||||
if is_id("var") { push(prog, parse_var()); return }
|
||||
if is_id("const") { push(prog, parse_const()); return }
|
||||
var is_unsafe = false
|
||||
|
|
@ -1510,4 +1513,5 @@ function parse_program() -> void {
|
|||
parse_one_decl()
|
||||
}
|
||||
registries_finish() # L8: each registry gets its defs
|
||||
views_finish() # L11: each view gets its model and call
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue