diff --git a/src/builtins.ts b/src/builtins.ts index ab473c1..2d73896 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -461,5 +461,16 @@ export const builtins: { [name: string]: NativeFunction } = { const metrics = measureCtx.measureText(str); return { kind: 'float', value: metrics.width }; } + }, + + 'debug': { + kind: 'native', + name: 'debug', + arity: 2, + fn: (label, value) => { + const l = expectString(label, 'debug'); + console.log(`[DEBUG] ${l}: `, value); + return value; + } } } diff --git a/src/interpreter.ts b/src/interpreter.ts index 1175b6a..a856707 100644 --- a/src/interpreter.ts +++ b/src/interpreter.ts @@ -87,6 +87,11 @@ export function evaluate(ast: AST, env: Env): Value { const val = evaluate(ast.value, newEnv); + // Don't bind _ + if (ast.name !== '_') { + newEnv.set(ast.name, val); + } + newEnv.set(ast.name, val); return evaluate(ast.body, newEnv); diff --git a/src/parser.ts b/src/parser.ts index db8e956..9c7032b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -114,7 +114,7 @@ export class Parser { } // Let - if (this.current().kind === 'ident' && this.peek().kind === 'equals') { + if ((this.current().kind === 'ident' || this.current().kind === 'underscore') && this.peek().kind === 'equals') { return this.parseLet(); } @@ -278,8 +278,20 @@ export class Parser { } private parseLet(): AST { - const nameToken = this.expect('ident'); - const name = (nameToken as { value: string }).value; + const nameToken = this.current(); + let name: string; + + if (nameToken.kind === 'underscore') { + name = '_'; + this.advance(); + } else if (nameToken.kind === 'ident') { + name = (nameToken as { value: string }).value; + this.advance(); + } else { + throw new Error(`Expected ident or underscore, got ${nameToken.kind}`); + + } + this.expect('equals'); const value = this.parseExpressionNoMatch(); this.expect('semicolon'); diff --git a/src/ui-components.cg b/src/ui-components.cg index dca77fb..eabb3c5 100644 --- a/src/ui-components.cg +++ b/src/ui-components.cg @@ -11,6 +11,7 @@ button = config \ }; insertChar = text pos char \ + _ = debug "insertChar" char; before = slice text 0 pos; after = slice text pos (len text); before & char & after;