fix: merge duplicate click props + upgrade streaming examples

- Duplicate prop keys now merge into Block expressions
  click: a then click: b → Block([a, b])
- All actions fire in one click (was silently overwriting)
- streaming-mood.ds upgraded to semicolons
- streaming-stats.ds upgraded to semicolons
- Browser-verified: Happy button fires 3 actions (mood+color+energy)
- All 7 examples pass regression
This commit is contained in:
enzotar 2026-02-26 17:44:21 -08:00
parent 10b2717281
commit c47852957f
3 changed files with 38 additions and 42 deletions

View file

@ -1373,7 +1373,34 @@ impl Parser {
} else {
first
};
props.push((key, val));
// Merge duplicate keys: `click: a` then `click: b` → Block([a, b])
if let Some(existing) = props.iter_mut().find(|(k, _)| *k == key) {
// Merge with existing value
match &existing.1 {
Expr::Block(exprs) => {
let mut merged = exprs.clone();
match val {
Expr::Block(new_exprs) => merged.extend(new_exprs),
other => merged.push(other),
}
existing.1 = Expr::Block(merged);
}
_ => {
let prev = existing.1.clone();
match val {
Expr::Block(mut new_exprs) => {
new_exprs.insert(0, prev);
existing.1 = Expr::Block(new_exprs);
}
other => {
existing.1 = Expr::Block(vec![prev, other]);
}
}
}
}
} else {
props.push((key, val));
}
self.skip_newlines();
if self.check(&TokenKind::Comma) {
self.advance();

View file

@ -3,7 +3,7 @@
-- Only mood, energy, color are exposed (clicks is internal).
--
-- Run with:
-- dreamstack stream examples/streaming-mood.ds --port 3004 --relay ws://localhost:9100/source/mood
-- dreamstack stream examples/streaming-mood.ds --port 3004
let mood = "neutral"
let energy = 50
@ -22,29 +22,12 @@ view mood_tracker =
text "Energy: {energy}%"
text "Color: {color}"
row [
button "😄 Happy" {
click: mood = "happy"
click: color = "green"
click: energy = energy + 10
}
button "😐 Neutral" {
click: mood = "neutral"
click: color = "gray"
}
button "😤 Angry" {
click: mood = "angry"
click: color = "red"
click: energy = energy - 10
}
button "😄 Happy" { click: mood = "happy"; color = "green"; energy += 10 }
button "😐 Neutral" { click: mood = "neutral"; color = "gray" }
button "😤 Angry" { click: mood = "angry"; color = "red"; energy -= 10 }
]
row [
button "☕ Caffeine" {
click: energy = energy + 25
click: clicks += 1
}
button "😴 Rest" {
click: energy = energy - 15
click: clicks += 1
}
button "☕ Caffeine" { click: energy += 25; clicks += 1 }
button "😴 Rest" { click: energy -= 15; clicks += 1 }
]
]

View file

@ -22,23 +22,9 @@ view stats =
text "Average: {average}"
text "Max: {max}"
row [
button "+5" {
click: total += 1
click: sum += 5
}
button "+10" {
click: total += 1
click: sum += 10
}
button "+25" {
click: total += 1
click: sum += 25
click: max = 25
}
button "+50" {
click: total += 1
click: sum += 50
click: max = 50
}
button "+5" { click: total += 1; sum += 5 }
button "+10" { click: total += 1; sum += 10 }
button "+25" { click: total += 1; sum += 25; max = 25 }
button "+50" { click: total += 1; sum += 50; max = 50 }
]
]