From 6ab98c144883ac282c3e884f7727fb9426a36c42 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 13 Feb 2026 12:15:56 -0700 Subject: [PATCH] let statements _within_ match patterns now need parens. adding sections to palette options. etc. --- src/cg/03-ui-components.cg | 20 ++++++------- src/cg/05-palette.cg | 57 +++++++++++++++++++++++--------------- src/cg/10-os.cg | 7 ++++- src/compiler.ts | 4 +-- src/parser.ts | 2 +- 5 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/cg/03-ui-components.cg b/src/cg/03-ui-components.cg index e84a184..0b49e32 100644 --- a/src/cg/03-ui-components.cg +++ b/src/cg/03-ui-components.cg @@ -126,37 +126,37 @@ textInput = config \ ui.stateful { # update : State \ Event \ State update = state event \ event - | Key { key = c, printable = True, meta = False, ctrl = False } \ + | Key { key = c, printable = True, meta = False, ctrl = False } \ ( newText = insertChar state.text state.cursorPos c; newCursorPos = state.cursorPos + 1; newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w; newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [config.onChange newText] } + { state = newState, emit = [config.onChange newText] }) - | Key { key = "ArrowLeft" } \ + | Key { key = "ArrowLeft" } \ ( newCursorPos = max 0 (state.cursorPos - 1); newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w; newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [] } + { state = newState, emit = [] }) - | Key { key = "ArrowRight" } \ + | Key { key = "ArrowRight" } \ ( newCursorPos = min (len state.text) (state.cursorPos + 1); newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w; newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [] } + { state = newState, emit = [] }) - | Key { key = "Backspace" } \ + | Key { key = "Backspace" } \ ( newText = deleteChar state.text state.cursorPos; newCursorPos = max 0 (state.cursorPos - 1); newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w; newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [config.onChange newText] } + { state = newState, emit = [config.onChange newText] }) - | Clicked coords \ + | Clicked coords \ ( newCursorPos = findCursorPos state.text coords.x state.scrollOffset 8; newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w; newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [] } + { state = newState, emit = [] }) | Focused \ { state = state.{ focused = True }, emit = [] } | Blurred \ { state = state.{ focused = False }, emit = [] } diff --git a/src/cg/05-palette.cg b/src/cg/05-palette.cg index ab02ce8..b290de9 100644 --- a/src/cg/05-palette.cg +++ b/src/cg/05-palette.cg @@ -30,18 +30,24 @@ # | Some (Item _) \ next # | None \ currentIndex); - paletteState = { query = "" }; +nextSelectable = items index direction \ + next = index + direction; + nth next items + | Some (Section _) \ nextSelectable items next direction + | Some (Item _) \ next + | None \ index; + palette = config \ focusedIndex = 0; windowHeight = 400; windowWidth = 600; - results = take 8 (config.search paletteState.query); - # results = config.search paletteState.query; # once you get scrolling.. + # results = take 8 (config.search paletteState.query); + results = config.search paletteState.query; # once you get scrolling.. dialogPadding = 0; @@ -78,9 +84,14 @@ palette = config \ update = state event \ event | Key { printable = True } \ { state = state.{ focusedIndex = 0 }, emit = [] } - | Key { key = "ArrowUp" } \ { state = state.{ focusedIndex = max 0 (state.focusedIndex - 1) }, emit = [] } - | Key { key = "ArrowDown" } \ { state = state.{ focusedIndex = min (len results - 1) (state.focusedIndex + 1) }, emit = [] } - | Key { key = "Enter" } \ { state = state, emit = [config.onSelect (unwrapOr "" (nth state.focusedIndex results))] } + | Key { key = "ArrowUp" } \ + { state = state.{ focusedIndex = nextSelectable results state.focusedIndex (0 - 1) }, emit = [] } + | Key { key = "ArrowDown" } \ + { state = state.{ focusedIndex = nextSelectable results state.focusedIndex 1 }, emit = [] } + | Key { key = "Enter" } \ + (nth state.focusedIndex results + | Some (Item data) \ { state = state, emit = [config.onSelect data.label] } + | _ \ { state = state, emit = [] }) | _ \ { state = state, emit = [] }, view = state \ @@ -113,22 +124,24 @@ palette = config \ child = ui.column { gap = 1, children = [ - box { - w = contentWidth, - h = 30, - color = "transparent", - paddingLeft = 6, - paddingTop = 8, - child = ui.text { content = "Store values", color = "#bbb" }, - }, - - ...(mapWithIndex (t i \ paletteRow { - child = t, - w = contentWidth, - h = textInputHeight, - selected = (state.focusedIndex == i), - onClick = onSelect - }) results) + ...(mapWithIndex (entry i \ entry + | Section title \ box { + w = contentWidth, + h = 30, + color = "transparent", + paddingLeft = 6, + paddingTop = 8, + child = ui.text { content = title, color = "#bbb" }, + } + | Item data \ paletteRow { + child = data.label, + w = contentWidth, + h = textInputHeight, + selected = (state.focusedIndex == i), + onClick = config.onSelect data.label + } + | _ \ empty + ) results) ] } } diff --git a/src/cg/10-os.cg b/src/cg/10-os.cg index 1eb05a2..c3ba4fd 100644 --- a/src/cg/10-os.cg +++ b/src/cg/10-os.cg @@ -162,7 +162,12 @@ renderWindows = _ \ search = q \ storeRes = storeSearch q; - [...storeRes, q]; + [ + Section "STORE", + ...map (name \ Item { label = name }) storeRes, + Section "EVAL", + Item { label = q } + ]; os = ui.stateful { key = "os", diff --git a/src/compiler.ts b/src/compiler.ts index 4fbe5b2..324f510 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -38,9 +38,7 @@ export function compile(ast: AST, useStore = true, bound = new Set(), to if (ast.func.kind === 'constructor') { const ctorName = ast.func.name; const arg = compile(ast.args[0], useStore, bound, topLevel); - return `((_a) => _a && typeof _a === 'object' && !Array.isArray(_a) && !_a._tag - ? { _tag: "${ctorName}", ..._a } - : { _tag: "${ctorName}", _0: _a })(${arg})`; + return `({ _tag: "${ctorName}", _0: ${arg} })`; } const args = ast.args.map(a => compile(a, useStore, bound, topLevel)).join(')('); diff --git a/src/parser.ts b/src/parser.ts index 9d54ced..a984fd3 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -366,7 +366,7 @@ export class Parser { this.expect('equals'); const value = this.parseExpression(); this.expect('semicolon'); - const body = this.parseExpressionNoMatch(); + const body = this.parseExpression(); return { kind: 'let', name, value, body, ...this.getPos(nameToken) }; }