From f378149146722756b157856cc69b666d175538e1 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Mon, 9 Feb 2026 15:22:07 -0700 Subject: [PATCH] nested rebind now works --- src/cg/05-palette.cg | 73 +++++++++++++++++++++++++++++++++++++++ src/cg/10-os.cg | 81 ++++---------------------------------------- src/compiler.ts | 13 +++---- src/main.ts | 2 +- 4 files changed, 84 insertions(+), 85 deletions(-) create mode 100644 src/cg/05-palette.cg diff --git a/src/cg/05-palette.cg b/src/cg/05-palette.cg new file mode 100644 index 0000000..44c73de --- /dev/null +++ b/src/cg/05-palette.cg @@ -0,0 +1,73 @@ +listRow = config \ + color = (config.selected | True \ "rgba(255,255,255,0.2)" | False \ "transparent"); + + Clickable { + event = config.onClick, + child = Stack { + children = [ + Rect { w = config.w, h = config.h, color = color }, + centerV config.h ( + Positioned { + x = 10, + y = 10, + child = Text { content = config.child, color = "white" } + } + ) + ] + } + }; + +palette = config \ + focusedIndex = 0; + windowHeight = 400; + windowWidth = 600; + + results = take 10 (config.search config.state.query); + + padding = 0; + + textInputHeight = 40; + contentWidth = windowWidth - (padding * 2); + contentHeight = windowHeight - (padding * 2); + listHeight = contentHeight - 40; + + Positioned { + x = (config.viewport.width - windowWidth) / 2, + y = (config.viewport.height - windowHeight) / 2, + + child = Stack { + children = [ + Rect { w = windowWidth, h = windowHeight, color = "#063351", radius = 0, strokeWidth = 1, strokeColor = "#1A5F80" }, + Padding { + amount = padding, + child = Column { + gap = 0, + children = [ + textInput { + key = "query", + initialValue = config.state.query, + initialFocus = True, + color = "white", + backgroundColor = "rgba(0,0,0,0.2)", + w = contentWidth, + h = textInputHeight, + onChange = text \ Batch [config.state.query := text, config.state.focusedIndex := 0], + onKeyDown = key \ key + | ArrowUp \ config.state.focusedIndex := max 0 (config.state.focusedIndex - 1) + | ArrowDown \ config.state.focusedIndex := (config.state.focusedIndex + 1) + | _ \ NoOp + }, + Clip { + w = contentWidth, + h = listHeight, + child = Column { + gap = 1, + children = mapWithIndex (t i \ listRow { child = t, w = contentWidth, h = textInputHeight, selected = (config.state.focusedIndex == i), onClick = NoOp }) results + } + } + ] + } + } + ] + } + }; diff --git a/src/cg/10-os.cg b/src/cg/10-os.cg index 4b6aaed..49e6036 100644 --- a/src/cg/10-os.cg +++ b/src/cg/10-os.cg @@ -2,8 +2,6 @@ osState = { palette = { query = "", focusedIndex = 0, - windowHeight = 400, - windowWidth = 600, } }; @@ -12,83 +10,16 @@ init = {}; update = state event \ event | _ \ state; -listRow = config \ - color = (config.selected | True \ "rgba(255,255,255,0.2)" | False \ "transparent"); - - Clickable { - event = config.onClick, - child = Stack { - children = [ - Rect { w = config.w, h = config.h, color = color }, - centerV config.h ( - Positioned { - x = 10, - y = 10, - child = Text { content = config.child, color = "white" } - } - ) - ] - } - }; - -palette = state viewport \ - results = take 10 (storeSearch osState.palette.query); - - state = osState.palette; - - padding = 0; - - textInputHeight = 40; - contentWidth = state.windowWidth - (padding * 2); - contentHeight = state.windowHeight - (padding * 2); - listHeight = contentHeight - 40; - - Positioned { - x = (viewport.width - state.windowWidth) / 2, - y = (viewport.height - state.windowHeight) / 2, - - child = Stack { - children = [ - Rect { w = state.windowWidth, h = state.windowHeight, color = "#063351", radius = 0, strokeWidth = 1, strokeColor = "#1A5F80" }, - Padding { - amount = padding, - child = Column { - gap = 0, - children = [ - textInput { - key = "query", - initialValue = osState.palette.query, - initialFocus = True, - color = "white", - backgroundColor = "rgba(0,0,0,0.2)", - w = contentWidth, - h = textInputHeight, - onChange = text \ Batch [osState.palette.query := text, osState.palette.focusedIndex := 0], - onKeyDown = key \ key - | ArrowUp \ osState.palette.focusedIndex := max 0 (osState.palette.focusedIndex - 1) - | ArrowDown \ osState.palette.focusedIndex := (osState.palette.focusedIndex + 1) - | _ \ NoOp - }, - Clip { - w = contentWidth, - h = listHeight, - child = Column { - gap = 1, - children = mapWithIndex (t i \ listRow { child = t, w = contentWidth, h = textInputHeight, selected = (osState.palette.focusedIndex == i), onClick = NoOp }) results - } - } - ] - } - } - ] - } - }; - view = state viewport \ Stack { children = [ Rect { w = viewport.width, h = viewport.height, color = "#012" }, - palette state viewport + palette { + state = osState.palette, + search = storeSearch, + onSelect = item \ debug "selected" item, + viewport = viewport, + } ] }; diff --git a/src/compiler.ts b/src/compiler.ts index 1952ad3..143869f 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -74,15 +74,10 @@ export function compile(ast: AST): string { if (ast.target.kind === 'variable') { return `({ _tag: "Rebind", _0: "${ast.target.name}", _1: ${compile(ast.value)} })`; } else if (ast.target.kind === 'record-access') { - let current: AST = ast.target; - const path: string[] = []; - while (current.kind === 'record-access') { - path.unshift(current.field); - current = current.record; - } - if (current.kind === 'variable') { - return `({ _tag: "Rebind", _0: "${current.name}", _1: ${JSON.stringify(path)}, _2: ${compile(ast.value)} })`; - } + const field = ast.target.field; + const obj = compile(ast.target.record); + const value = compile(ast.value); + return `(() => { ${obj}.${sanitize(field)} = ${value}; return { _tag: "Rerender" }; })()`; } throw new Error('Invalid rebind target'); } diff --git a/src/main.ts b/src/main.ts index c8da7c8..ac318c0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { Parser } from './parser' import { runAppCompiled } from './runtime-compiled' import { _rt } from './runtime-js' -const modules = import.meta.glob('./cg/*.cg', { as: 'raw', eager: true }); +const modules = import.meta.glob('./cg/*.cg', { query: 'raw', import: 'default', eager: true }); const cgCode = Object.keys(modules) .sort() .map(key => modules[key])