From 27197c273ca8619c7c1fd11fcdadbc363004a783 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Fri, 8 Mar 2024 18:30:13 -0800 Subject: [PATCH] [CLEANUP] Drop support for `{{#with}}` keyword This was dropped on Ember side a while back, just never cleaned up Ironically this probably meant when Ember dropped the deprecation/ error, nothing was actually stopping `{{#with}}` from anymore, so perhaps for a while we have actually _re-introduced_ support for the syntax for some time? Extracted from #1557 --- .../lib/suites/components.ts | 14 ++--- .../integration-tests/lib/suites/debugger.ts | 2 +- .../integration-tests/lib/suites/scope.ts | 12 ++-- .../test/ember-component-test.ts | 36 +++++------ .../test/helpers/array-test.ts | 16 ++--- .../integration-tests/test/updating-test.ts | 35 ++++------- .../@glimmer/compiler/lib/builder/builder.ts | 4 +- .../passes/1-normalization/keywords/block.ts | 62 ------------------- .../compiler/lib/passes/2-encoding/content.ts | 11 ---- .../compiler/lib/passes/2-encoding/mir.ts | 7 --- .../compiler/lib/wire-format-debug.ts | 8 --- .../@glimmer/compiler/test/compiler-test.ts | 4 +- .../lib/compile/wire-format/api.d.ts | 9 --- .../opcode-compiler/lib/syntax/statements.ts | 24 ------- 14 files changed, 56 insertions(+), 188 deletions(-) diff --git a/packages/@glimmer-workspace/integration-tests/lib/suites/components.ts b/packages/@glimmer-workspace/integration-tests/lib/suites/components.ts index 56e989173c..d4a60da81c 100644 --- a/packages/@glimmer-workspace/integration-tests/lib/suites/components.ts +++ b/packages/@glimmer-workspace/integration-tests/lib/suites/components.ts @@ -268,7 +268,7 @@ export class GlimmerishComponents extends RenderTest { }) 'invoking dynamic component (local) via angle brackets'() { this.registerComponent('Glimmer', 'Foo', 'hello world!'); - this.render(`{{#with (component 'Foo') as |Other|}}{{/with}}`); + this.render(`{{#let (component 'Foo') as |Other|}}{{/let}}`); this.assertHTML(`hello world!`); this.assertStableRerender(); @@ -280,7 +280,7 @@ export class GlimmerishComponents extends RenderTest { 'invoking dynamic component (local path) via angle brackets'() { this.registerHelper('hash', (_positional, named) => named); this.registerComponent('Glimmer', 'Foo', 'hello world!'); - this.render(`{{#with (hash Foo=(component 'Foo')) as |Other|}}{{/with}}`); + this.render(`{{#let (hash Foo=(component 'Foo')) as |Other|}}{{/let}}`); this.assertHTML(`hello world!`); this.assertStableRerender(); @@ -291,7 +291,7 @@ export class GlimmerishComponents extends RenderTest { }) 'invoking dynamic component (local) via angle brackets (ill-advised "htmlish element name" but supported)'() { this.registerComponent('Glimmer', 'Foo', 'hello world!'); - this.render(`{{#with (component 'Foo') as |div|}}
{{/with}}`); + this.render(`{{#let (component 'Foo') as |div|}}
{{/let}}`); this.assertHTML(`hello world!`); this.assertStableRerender(); @@ -302,7 +302,7 @@ export class GlimmerishComponents extends RenderTest { }) 'invoking dynamic component (local) via angle brackets supports attributes'() { this.registerComponent('Glimmer', 'Foo', '
hello world!
'); - this.render(`{{#with (component 'Foo') as |Other|}}{{/with}}`); + this.render(`{{#let (component 'Foo') as |Other|}}{{/let}}`); this.assertHTML(`
hello world!
`); this.assertStableRerender(); @@ -313,7 +313,7 @@ export class GlimmerishComponents extends RenderTest { }) 'invoking dynamic component (local) via angle brackets supports args'() { this.registerComponent('Glimmer', 'Foo', 'hello {{@name}}!'); - this.render(`{{#with (component 'Foo') as |Other|}}{{/with}}`); + this.render(`{{#let (component 'Foo') as |Other|}}{{/let}}`); this.assertHTML(`hello world!`); this.assertStableRerender(); @@ -324,7 +324,7 @@ export class GlimmerishComponents extends RenderTest { }) 'invoking dynamic component (local) via angle brackets supports passing a block'() { this.registerComponent('Glimmer', 'Foo', 'hello {{yield}}!'); - this.render(`{{#with (component 'Foo') as |Other|}}world{{/with}}`); + this.render(`{{#let (component 'Foo') as |Other|}}world{{/let}}`); this.assertHTML(`hello world!`); this.assertStableRerender(); @@ -351,7 +351,7 @@ export class GlimmerishComponents extends RenderTest { Foo ); this.render( - `{{#with (component 'Foo') as |Other|}}template{{/with}}`, + `{{#let (component 'Foo') as |Other|}}template{{/let}}`, { outer: 'outer' } ); diff --git a/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts b/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts index 1b3e22cb37..c8cdea29e4 100644 --- a/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts +++ b/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts @@ -75,7 +75,7 @@ export class DebuggerSuite extends RenderTest { }); this.render( - '{{#with this.foo as |bar|}}{{#if this.a.b}}true{{debugger}}{{else}}false{{debugger}}{{/if}}{{/with}}', + '{{#let this.foo as |bar|}}{{#if this.a.b}}true{{debugger}}{{else}}false{{debugger}}{{/if}}{{/let}}', expectedContext ); this.assert.strictEqual(callbackExecuted, 1); diff --git a/packages/@glimmer-workspace/integration-tests/lib/suites/scope.ts b/packages/@glimmer-workspace/integration-tests/lib/suites/scope.ts index 87f8764d13..72ff264e8e 100644 --- a/packages/@glimmer-workspace/integration-tests/lib/suites/scope.ts +++ b/packages/@glimmer-workspace/integration-tests/lib/suites/scope.ts @@ -9,11 +9,11 @@ export class ScopeSuite extends RenderTest { 'correct scope - conflicting local names'() { this.render({ layout: stripTight` - {{#with @a as |item|}}{{@a}}: {{item}}, - {{#with @b as |item|}} {{@b}}: {{item}}, - {{#with @c as |item|}} {{@c}}: {{item}}{{/with}} - {{/with}} - {{/with}}`, + {{#let @a as |item|}}{{@a}}: {{item}}, + {{#let @b as |item|}} {{@b}}: {{item}}, + {{#let @c as |item|}} {{@c}}: {{item}}{{/let}} + {{/let}} + {{/let}}`, args: { a: '"A"', b: '"B"', c: '"C"' }, }); @@ -25,7 +25,7 @@ export class ScopeSuite extends RenderTest { 'correct scope - conflicting block param and attr names'() { this.render({ layout: - 'Outer: {{@conflict}} {{#with @item as |conflict|}}Inner: {{@conflict}} Block: {{conflict}}{{/with}}', + 'Outer: {{@conflict}} {{#let @item as |conflict|}}Inner: {{@conflict}} Block: {{conflict}}{{/let}}', args: { item: '"from block"', conflict: '"from attr"' }, }); diff --git a/packages/@glimmer-workspace/integration-tests/test/ember-component-test.ts b/packages/@glimmer-workspace/integration-tests/test/ember-component-test.ts index 5d5b965e91..e68e47cbce 100644 --- a/packages/@glimmer-workspace/integration-tests/test/ember-component-test.ts +++ b/packages/@glimmer-workspace/integration-tests/test/ember-component-test.ts @@ -372,14 +372,14 @@ class CurlyScopeTest extends CurlyTest { stripTight`
[Outside: {{this.zomg}}] - {{#with this.zomg as |lol|}} + {{#let this.zomg as |lol|}} [Inside: {{this.zomg}}] [Inside: {{lol}}] [Block: {{this.zomg}}] [Block: {{lol}}] - {{/with}} + {{/let}}
`, { zomg: 'zomg' } ); @@ -419,14 +419,14 @@ class CurlyScopeTest extends CurlyTest { stripTight`
[Outside: {{this.zomg}}] - {{#with this.zomg as |lol|}} + {{#let this.zomg as |lol|}} [Inside: {{this.zomg}}] [Inside: {{lol}}] {{#foo-bar foo=this.zomg}} [Block: {{this.zomg}}] [Block: {{lol}}] {{/foo-bar}} - {{/with}} + {{/let}}
`, { zomg: 'zomg' } ); @@ -991,9 +991,9 @@ class CurlyClosureComponentsTest extends CurlyTest { this.render( stripTight` - {{#with (hash comp=(component 'foo-bar')) as |my|}} + {{#let (hash comp=(component 'foo-bar')) as |my|}} {{#component my.comp arg1="World!"}}Test1{{/component}} Test2 - {{/with}} + {{/let}} ` ); @@ -1007,9 +1007,9 @@ class CurlyClosureComponentsTest extends CurlyTest { this.render( stripTight` - {{#with (hash comp=(component 'foo-bar')) as |my|}} + {{#let (hash comp=(component 'foo-bar')) as |my|}} {{#component my.comp}}World!{{/component}} Test - {{/with}} + {{/let}} ` ); @@ -1023,9 +1023,9 @@ class CurlyClosureComponentsTest extends CurlyTest { this.render( stripTight` - {{#with (hash comp=(component 'foo-bar')) as |my|}} + {{#let (hash comp=(component 'foo-bar')) as |my|}} {{component my.comp arg1="World!"}} Test - {{/with}} + {{/let}} ` ); @@ -1039,9 +1039,9 @@ class CurlyClosureComponentsTest extends CurlyTest { this.render( stripTight` - {{#with (hash comp=(component 'foo-bar')) as |my|}} + {{#let (hash comp=(component 'foo-bar')) as |my|}} {{component my.comp}} World! - {{/with}} + {{/let}} ` ); @@ -1131,9 +1131,9 @@ class CurlyClosureComponentsTest extends CurlyTest { this.render( stripTight` - {{#with (hash comp=(component 'foo-bar')) as |my|}} + {{#let (hash comp=(component 'foo-bar')) as |my|}} {{my.comp}} World! - {{/with}} + {{/let}} ` ); @@ -1190,11 +1190,11 @@ class CurlyClosureComponentsTest extends CurlyTest { this.render( stripTight` - {{#with (component "foo-bar" "outer 1" "outer 2" a="outer a" b="outer b" c="outer c" e="outer e") as |outer|}} - {{#with (component outer "inner 1" a="inner a" d="inner d" e="inner e") as |inner|}} + {{#let (component "foo-bar" "outer 1" "outer 2" a="outer a" b="outer b" c="outer c" e="outer e") as |outer|}} + {{#let (component outer "inner 1" a="inner a" d="inner d" e="inner e") as |inner|}} {{#component inner "invocation 1" "invocation 2" a="invocation a" b="invocation b"}}---{{/component}} - {{/with}} - {{/with}} + {{/let}} + {{/let}} ` ); diff --git a/packages/@glimmer-workspace/integration-tests/test/helpers/array-test.ts b/packages/@glimmer-workspace/integration-tests/test/helpers/array-test.ts index c500eda4c4..47c2635018 100644 --- a/packages/@glimmer-workspace/integration-tests/test/helpers/array-test.ts +++ b/packages/@glimmer-workspace/integration-tests/test/helpers/array-test.ts @@ -6,11 +6,11 @@ class ArrayTest extends RenderTest { @test 'returns an array'() { this.render(strip` - {{#with (array "Sergio") as |people|}} + {{#let (array "Sergio") as |people|}} {{#each people as |personName|}} {{personName}} {{/each}} - {{/with}}`); + {{/let}}`); this.assertHTML('Sergio'); @@ -20,11 +20,11 @@ class ArrayTest extends RenderTest { @test 'can have more than one value'() { this.render(strip` - {{#with (array "Sergio" "Robert") as |people|}} + {{#let (array "Sergio" "Robert") as |people|}} {{#each people as |personName|}} {{personName}}, {{/each}} - {{/with}}`); + {{/let}}`); this.assertHTML('Sergio,Robert,'); @@ -34,11 +34,11 @@ class ArrayTest extends RenderTest { @test 'binds values when variables are used'() { this.render( - strip`{{#with (array this.personOne) as |people|}} + strip`{{#let (array this.personOne) as |people|}} {{#each people as |personName|}} {{personName}} {{/each}} - {{/with}}`, + {{/let}}`, { personOne: 'Tom', } @@ -58,11 +58,11 @@ class ArrayTest extends RenderTest { @test 'binds multiple values when variables are used'() { this.render( - strip`{{#with (array this.personOne this.personTwo) as |people|}} + strip`{{#let (array this.personOne this.personTwo) as |people|}} {{#each people as |personName|}} {{personName}}, {{/each}} - {{/with}}`, + {{/let}}`, { personOne: 'Tom', personTwo: 'Yehuda', diff --git a/packages/@glimmer-workspace/integration-tests/test/updating-test.ts b/packages/@glimmer-workspace/integration-tests/test/updating-test.ts index 0ebfaefc67..a08ad7ae78 100644 --- a/packages/@glimmer-workspace/integration-tests/test/updating-test.ts +++ b/packages/@glimmer-workspace/integration-tests/test/updating-test.ts @@ -560,17 +560,6 @@ class UpdatingTest extends RenderTest { this.testStatefulHelper(assert, options); } - @test - 'helpers passed as arguments to {{#with}} are not torn down when switching between blocks'() { - let options = { - template: '{{#with (stateful-foo) as |unused|}}Yes{{/with}}', - truthyValue: {}, - falsyValue: null, - }; - - this.testStatefulHelper(assert, options); - } - @test 'helpers passed as arguments to {{#each}} are not torn down when switching between blocks'() { let options = { @@ -900,7 +889,7 @@ class UpdatingTest extends RenderTest { const person = { name: new Name('Godfrey', 'Chan') }; - this.render('
{{#with this.person.name.first as |f|}}{{f}}{{/with}}
', { + this.render('
{{#let this.person.name.first as |f|}}{{f}}{{/let}}
', { person, }); @@ -943,7 +932,7 @@ class UpdatingTest extends RenderTest { ----- - {{#with this.value as |foo|}} + {{#let this.value as |foo|}} foo: "{{foo}}"; bar: "{{bar}}"; value: "{{this.value}}"; @@ -953,26 +942,26 @@ class UpdatingTest extends RenderTest { ----- - {{#with foo as |bar|}} + {{#let foo as |bar|}} foo: "{{foo}}"; bar: "{{bar}}"; value: "{{this.value}}"; echo foo: "{{echo foo}}"; echo bar: "{{echo bar}}"; echo value: "{{echo this.value}}"; - {{/with}} - {{/with}} + {{/let}} + {{/let}} ----- - {{#with this.value as |bar|}} + {{#let this.value as |bar|}} foo: "{{foo}}"; bar: "{{bar}}"; value: "{{this.value}}"; echo foo: "{{echo this.foo}}"; echo bar: "{{echo bar}}"; echo value: "{{echo this.value}}"; - {{/with}} + {{/let}}
`; @@ -1108,7 +1097,7 @@ class UpdatingTest extends RenderTest { @test 'block arguments (ensure balanced push/pop)'() { let person = { name: { first: 'Godfrey', last: 'Chan' } }; - this.render('
{{#with this.person.name.first as |f|}}{{f}}{{/with}}{{this.f}}
', { + this.render('
{{#let this.person.name.first as |f|}}{{f}}{{/let}}{{this.f}}
', { person, f: 'Outer', }); @@ -1128,9 +1117,9 @@ class UpdatingTest extends RenderTest { this.render( stripTight`
- [{{#with this.person as |name|}}{{this.name}}{{/with}}] - [{{#with this.person as |name|}}{{#with this.name as |test|}}{{test}}{{/with}}{{/with}}] - [{{#with this.person as |name|}}{{#with (noop this.name) as |test|}}{{test}}{{/with}}{{/with}}] + [{{#let this.person as |name|}}{{this.name}}{{/let}}] + [{{#let this.person as |name|}}{{#let this.name as |test|}}{{test}}{{/let}}{{/let}}] + [{{#let this.person as |name|}}{{#let (noop this.name) as |test|}}{{test}}{{/let}}{{/let}}]
`, { person: 'Yehuda', name: 'Godfrey' } @@ -1148,7 +1137,7 @@ class UpdatingTest extends RenderTest { @test 'The with helper should consider an empty array truthy'() { - this.render('
{{#with this.condition as |c|}}{{c.length}}{{/with}}
', { + this.render('
{{#let this.condition as |c|}}{{c.length}}{{/let}}
', { condition: [], }); diff --git a/packages/@glimmer/compiler/lib/builder/builder.ts b/packages/@glimmer/compiler/lib/builder/builder.ts index 51efc4c07f..bfb4158867 100644 --- a/packages/@glimmer/compiler/lib/builder/builder.ts +++ b/packages/@glimmer/compiler/lib/builder/builder.ts @@ -341,8 +341,8 @@ function buildKeyword( : null; switch (name) { - case 'with': - return [Op.With, expect(params, 'with requires params')[0], block, inverse]; + case 'let': + return [Op.Let, expect(params, 'let requires params'), block]; case 'if': return [Op.If, expect(params, 'if requires params')[0], block, inverse]; case 'each': { diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/block.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/block.ts index fc8a7fcd1a..8f52d24f2d 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/block.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/block.ts @@ -281,68 +281,6 @@ export const BLOCK_KEYWORDS = keywords('Block') ); }, }) - .kw('with', { - assert(node: ASTv2.InvokeBlock): Result<{ - value: ASTv2.ExpressionNode; - }> { - let { args } = node; - - if (!args.named.isEmpty()) { - return Err( - generateSyntaxError( - `{{#with}} cannot receive named parameters, received ${args.named.entries - .map((e) => e.name.chars) - .join(', ')}`, - args.named.loc - ) - ); - } - - if (args.positional.size > 1) { - return Err( - generateSyntaxError( - `{{#with}} can only receive one positional parameter. Received ${args.positional.size} parameters`, - args.positional.loc - ) - ); - } - - let value = args.nth(0); - - if (value === null) { - return Err( - generateSyntaxError( - `{{#with}} requires a value as its first positional parameter, did not receive any parameters`, - args.loc - ) - ); - } - - return Ok({ value }); - }, - - translate( - { node, state }: { node: ASTv2.InvokeBlock; state: NormalizationState }, - { value }: { value: ASTv2.ExpressionNode } - ): Result { - let block = node.blocks.get('default'); - let inverse = node.blocks.get('else'); - - let valueResult = VISIT_EXPRS.visit(value, state); - let blockResult = VISIT_STMTS.NamedBlock(block, state); - let inverseResult = inverse ? VISIT_STMTS.NamedBlock(inverse, state) : Ok(null); - - return Result.all(valueResult, blockResult, inverseResult).mapOk( - ([value, block, inverse]) => - new mir.With({ - loc: node.loc, - value, - block, - inverse, - }) - ); - }, - }) .kw('let', { assert(node: ASTv2.InvokeBlock): Result<{ positional: ASTv2.PositionalArguments; diff --git a/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts b/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts index e13a92a53a..38e6aaf2ad 100644 --- a/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts +++ b/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts @@ -76,8 +76,6 @@ export class ContentEncoder { return this.If(stmt); case 'Each': return this.Each(stmt); - case 'With': - return this.With(stmt); case 'Let': return this.Let(stmt); case 'WithDynamicVars': @@ -212,15 +210,6 @@ export class ContentEncoder { ]; } - With({ value, block, inverse }: mir.With): WireFormat.Statements.With { - return [ - SexpOpcodes.With, - EXPR.expr(value), - CONTENT.NamedBlock(block)[1], - inverse ? CONTENT.NamedBlock(inverse)[1] : null, - ]; - } - Let({ positional, block }: mir.Let): WireFormat.Statements.Let { return [SexpOpcodes.Let, EXPR.Positional(positional), CONTENT.NamedBlock(block)[1]]; } diff --git a/packages/@glimmer/compiler/lib/passes/2-encoding/mir.ts b/packages/@glimmer/compiler/lib/passes/2-encoding/mir.ts index fe0fad55bf..c743f5670f 100644 --- a/packages/@glimmer/compiler/lib/passes/2-encoding/mir.ts +++ b/packages/@glimmer/compiler/lib/passes/2-encoding/mir.ts @@ -43,12 +43,6 @@ export class Each extends node('Each').fields<{ inverse: NamedBlock | null; }>() {} -export class With extends node('With').fields<{ - value: ExpressionNode; - block: NamedBlock; - inverse: NamedBlock | null; -}>() {} - export class Let extends node('Let').fields<{ positional: Positional; block: NamedBlock; @@ -242,7 +236,6 @@ export type Statement = | AppendComment | If | Each - | With | Let | WithDynamicVars | InvokeComponent; diff --git a/packages/@glimmer/compiler/lib/wire-format-debug.ts b/packages/@glimmer/compiler/lib/wire-format-debug.ts index 69aa363630..ef087107f2 100644 --- a/packages/@glimmer/compiler/lib/wire-format-debug.ts +++ b/packages/@glimmer/compiler/lib/wire-format-debug.ts @@ -232,14 +232,6 @@ export default class WireFormatDebugger { opcode[4] ? this.formatBlock(opcode[4]) : null, ]; - case Op.With: - return [ - 'with', - this.formatOpcode(opcode[1]), - this.formatBlock(opcode[2]), - opcode[3] ? this.formatBlock(opcode[3]) : null, - ]; - case Op.Let: return ['let', this.formatParams(opcode[1]), this.formatBlock(opcode[2])]; diff --git a/packages/@glimmer/compiler/test/compiler-test.ts b/packages/@glimmer/compiler/test/compiler-test.ts index fe68c1ac1d..8eee50e5bf 100644 --- a/packages/@glimmer/compiler/test/compiler-test.ts +++ b/packages/@glimmer/compiler/test/compiler-test.ts @@ -78,8 +78,8 @@ test('Text curlies', '
{{title}}{{title}}
', [ test( `Smoke test (blocks don't produce 'this' fallback)`, - `{{#with person as |name|}}{{#with this.name as |test|}}{{test}}{{/with}}{{/with}}`, - ['!with', ['^person'], { as: 'name' }, [['!with', ['this.name'], { as: 'test' }, ['test']]]] + `{{#let person as |name|}}{{#let this.name as |test|}}{{test}}{{/let}}{{/let}}`, + ['!let', ['^person'], { as: 'name' }, [['!let', ['this.name'], { as: 'test' }, ['test']]]] ); test( diff --git a/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts b/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts index 83048652b9..f10ec4758f 100644 --- a/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts @@ -49,7 +49,6 @@ import type { TrustingDynamicAttrOpcode, UndefinedOpcode, WithDynamicVarsOpcode, - WithOpcode, YieldOpcode, } from './opcodes.js'; @@ -314,13 +313,6 @@ export namespace Statements { inverse: Nullable, ]; - export type With = [ - op: WithOpcode, - value: Expression, - block: SerializedInlineBlock, - inverse: Nullable, - ]; - export type Let = [op: LetOpcode, positional: Core.Params, block: SerializedInlineBlock]; export type WithDynamicVars = [ @@ -360,7 +352,6 @@ export namespace Statements { | InElement | If | Each - | With | Let | WithDynamicVars | InvokeComponent; diff --git a/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts b/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts index 4dfe248bbf..a4a50b4207 100644 --- a/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts +++ b/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts @@ -322,30 +322,6 @@ STATEMENTS.add(SexpOpcodes.Each, (op, [, value, key, block, inverse]) => ) ); -STATEMENTS.add(SexpOpcodes.With, (op, [, value, block, inverse]) => { - ReplayableIf( - op, - - () => { - expr(op, value); - op(Op.Dup, $sp, 0); - op(Op.ToBoolean); - - return 2; - }, - - () => { - InvokeStaticBlockWithStack(op, block, 1); - }, - - () => { - if (inverse) { - InvokeStaticBlock(op, inverse); - } - } - ); -}); - STATEMENTS.add(SexpOpcodes.Let, (op, [, positional, block]) => { let count = CompilePositional(op, positional); InvokeStaticBlockWithStack(op, block, count);