enzotar
26d6c4f17a
feat: v2 built-in functions — 90+ native functions
...
Array: len, push, pop, filter, map, concat, contains, reverse, slice,
indexOf, find, some, every, flat, sort (mutating ops re-trigger signal)
Math: abs, min, max, floor, ceil, round, random, sqrt, pow, sin, cos,
tan, atan2, clamp, lerp
String: split, join, trim, upper, lower, replace, starts_with, ends_with,
char_at, substring
Conversion: int, float, string, bool
Console: log, debug, warn
Timer: delay
Also adds ExprStatement support for top-level expressions (log, push, etc).
110 tests, 0 failures.
2026-02-25 20:30:08 -08:00
enzotar
2aa2c7ad8e
feat: step sequencer demo — reactive pads, playhead, BPM
...
Step sequencer: 4 instruments × 8 steps, timer-driven playhead,
toggleable pads, BPM controls with streaming. 75 lines of .ds code.
Parser fixes:
- UI elements checked before LParen (button (if ...) is element, not call)
- Element args support parenthesized expressions: button (if cond ...)
- StringInterp recognized as valid string start in parse_primary/parse_element
Codegen fixes:
- emit_expr checks local_vars: loop var i emits 'i' not 'i.value'
- Array index mutations re-trigger signal: pads.value = [...pads.value]
110 tests, 0 failures.
2026-02-25 19:33:12 -08:00
enzotar
2d07b1652a
feat: v2 phase 1 — array access, timer, string interpolation
...
Array access: Expr::Index in AST, [expr] postfix parsing, codegen for
reads (grid.value[i.value]) and writes (event handler assignments with
root signal extraction for stream diff broadcasting).
Timer: 'every N -> expr' declaration. Every keyword in lexer. EveryDecl
in AST. parse_every_decl in parser. setInterval codegen with DS.flush.
String interpolation: already committed separately.
Type checker: handles Expr::Index (infers array element type).
110 tests, 0 failures.
2026-02-25 19:20:20 -08:00
enzotar
392e478351
feat: WebRTC transport — peer-to-peer data channels with auto-fallback
...
Relay:
- /signal/{channel} path for SDP/ICE exchange via WebSocket
- handle_signaling broadcasts text messages between signaling peers
- signaling_tx broadcast channel in ChannelState
- 46 ds-stream tests (+2 signaling path tests)
JS Runtime:
- _initWebRTC(signalingUrl, streamUrl, mode) with RTCPeerConnection
- Unordered DataChannel (ordered:false, maxRetransmits:0) for low latency
- Auto-fallback: WebSocket starts immediately, WebRTC upgrades in ≤5s
- Data channel override of _streamSend for transparent binary protocol
Parser/AST:
- StreamTransport enum (WebSocket, WebRTC)
- transport field in StreamDecl
- Parses: stream x on url { mode: signal, transport: webrtc }
Codegen:
- WebRTC: emits DS._initWebRTC(sigUrl, streamUrl, mode)
- WebSocket: emits DS._initStream(url, mode) (unchanged)
97 tests, 0 failures
2026-02-25 15:02:31 -08:00
enzotar
439a775dec
feat(compiler): complete bitstream integration — all 9 changes
...
- AST: StreamDecl, StreamMode, Declaration::Stream, StreamFrom struct variant
- Lexer: Pixel, Delta, Signals keywords
- Parser: parse_stream_decl with mode block, fixed TokenKind::On match
- Signal graph: streamable flag, SignalManifest, Declaration::Stream detection
- Checker: StreamFrom { source, .. } pattern
- Codegen: DS._initStream(), DS._connectStream(), DS._streamDiff() hooks
- Runtime JS: full streaming layer with binary protocol encoding
- Layout: to_bytes/from_bytes on LayoutRect
82 tests pass (5 new: 3 parser stream + 2 analyzer streamable)
2026-02-25 13:26:59 -08:00
enzotar
d86818ca6a
feat(compiler): full bitstream integration across 7 pipeline stages
...
AST: StreamDecl, StreamMode, Expr::StreamFrom { source, mode }
Lexer: Pixel, Delta, Signals keywords
Parser: parse_stream_decl() with mode parsing, StreamFrom expression
Signal Graph: streamable flag on SignalNode, auto-detect stream decls
Type Checker: StreamFrom returns Type::Stream
Codegen: emit_stream_init phase, StreamFrom → DS.streamConnect(),
streaming runtime JS (WebSocket relay, binary protocol, signal frames,
remote input handler, auto-reconnect)
CLI: 'dreamstack stream' command — compile+serve with streaming enabled,
auto-inject stream declaration for the first view
All 77 workspace tests pass, 0 failures.
2026-02-25 13:13:21 -08:00
enzotar
ea64617569
feat: physics language integration — scene container with Rapier2D WASM
...
- Add scene container to AST, lexer, parser, analyzer, and codegen
- Add circle/rect/line as UI elements for physics body declaration
- Compile scene {} to canvas + async WASM init + Rapier2D PhysicsWorld
- Reactive gravity via DS.effect() — bodies wake on gravity change
- Mouse drag interaction with impulse-based body movement
- Compile-time hex color parsing for body colors
- Fix is_signal_ref matching numeric literals (700.value bug)
- Fix body variable uniqueness (next_node_id per body)
- Fix gravity signal detection (check AST Ident before emit_expr)
- Add physics.ds example with 5 bodies + 4 gravity control buttons
- Update DREAMSTACK.md and IMPLEMENTATION_PLAN.md with Phase 10-11
- 39 tests pass across all crates, 22KB output
2026-02-25 10:58:43 -08:00
enzotar
a35d44bd59
feat: two-way binding, form props, and async resources
...
Phase 8 features:
- bind prop: two-way signal <-> input sync
- placeholder, value, style, disabled props
- DS.resource() for reactive async data fetching
- DS.fetchJSON() convenience wrapper
- Props-only element parsing: input { bind: x }
- examples/form.ds: contact form with validation
Fixed: double .value.value bug in bind codegen.
2026-02-25 08:08:37 -08:00
enzotar
adff40d47f
feat: hash-based router + keyed list reconciliation
...
Phase 7 features:
- route "/path" -> body declarations with hash-based routing
- navigate "/path" built-in function
- DS.route signal tracks current hash path
- DS.matchRoute() with :param pattern matching
- DS.keyedList() for keyed DOM reconciliation
- Route-aware mounting: views + routes compose
- examples/router.ds: 3-page app (home/about/counter)
- State persists across route changes (10818 bytes)
2026-02-25 07:54:00 -08:00
enzotar
ca45c688df
feat: for-in list rendering + component system
...
Phase 6 features:
- ForIn reactive list rendering: for item in items -> body
- Optional index binding: for item, idx in items -> body
- Component declarations: component Name(props) = body
- Component instantiation: ComponentUse { name, props }
Added across 5 crates:
- ds-parser: For/In/Component tokens, ForIn/ComponentDecl AST nodes
- ds-codegen: reactive list effect, component function emission
- ds-types: ForIn/ComponentUse type inference
- local_vars tracking for non-reactive for-in loop vars
Includes examples/list.ds showcasing for-in + when + signals.
2026-02-25 01:33:28 -08:00
enzotar
a634152318
feat: DreamStack compiler foundation — Phase 0/1
...
Complete compiler pipeline from .ds source to reactive browser apps:
- ds-parser: lexer (string interpolation, operators, keywords) + recursive
descent parser with operator precedence + full AST types
- ds-analyzer: signal graph extraction (source/derived classification),
topological sort for glitch-free propagation, DOM binding analysis
- ds-codegen: JavaScript emitter with embedded reactive runtime (~3KB
signal/derived/effect system) and dark-theme CSS design system
- ds-cli: build (compile to HTML+JS), dev (live server), check (analyze)
Verified working: source signals, derived signals, event handlers,
conditional rendering (when), 12 unit tests passing, 6.8KB output.
2026-02-25 00:03:06 -08:00