mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-23 20:23:32 +00:00
feat(codemode): support loop sequence syntax (#35618)
This commit is contained in:
parent
8dc9ac07a2
commit
b046bbe4e3
2 changed files with 68 additions and 5 deletions
|
|
@ -1088,7 +1088,7 @@ class Interpreter<R> {
|
|||
}
|
||||
|
||||
let declaration: { readonly pattern: AstNode; readonly mutable: boolean } | undefined
|
||||
let assignmentName: string | undefined
|
||||
let assignment: AstNode | undefined
|
||||
|
||||
if (left.type === "VariableDeclaration") {
|
||||
const declarations = getArray(left, "declarations")
|
||||
|
|
@ -1098,8 +1098,13 @@ class Interpreter<R> {
|
|||
|
||||
const declarator = asNode(declarations[0], "declarations[0]")
|
||||
declaration = { pattern: getNode(declarator, "id"), mutable: getString(left, "kind") !== "const" }
|
||||
} else if (left.type === "Identifier") {
|
||||
assignmentName = getString(left, "name")
|
||||
} else if (
|
||||
left.type === "Identifier" ||
|
||||
left.type === "MemberExpression" ||
|
||||
left.type === "ArrayPattern" ||
|
||||
left.type === "ObjectPattern"
|
||||
) {
|
||||
assignment = left
|
||||
} else {
|
||||
throw new InterpreterRuntimeError("Unsupported for...of binding.", left)
|
||||
}
|
||||
|
|
@ -1108,8 +1113,8 @@ class Interpreter<R> {
|
|||
if (declaration) {
|
||||
self.pushScope()
|
||||
yield* self.declarePattern(declaration.pattern, value, declaration.mutable, left)
|
||||
} else if (assignmentName) {
|
||||
self.setIdentifierValue(assignmentName, value, left)
|
||||
} else if (assignment) {
|
||||
yield* self.assignPattern(assignment, value, left)
|
||||
}
|
||||
|
||||
const result = yield* self.evaluateStatement(body).pipe(
|
||||
|
|
@ -1507,6 +1512,16 @@ class Interpreter<R> {
|
|||
return this.evaluateUnaryExpression(node)
|
||||
case "AssignmentExpression":
|
||||
return this.evaluateAssignmentExpression(node)
|
||||
case "SequenceExpression": {
|
||||
const self = this
|
||||
return Effect.gen(function* () {
|
||||
let result: unknown
|
||||
for (const expression of getArray(node, "expressions")) {
|
||||
result = yield* self.evaluateExpression(asNode(expression, "expressions"))
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
case "CallExpression":
|
||||
return this.evaluateCallExpression(node)
|
||||
case "ArrowFunctionExpression":
|
||||
|
|
|
|||
|
|
@ -464,6 +464,54 @@ describe("H5: builtin coercion functions work as array callbacks", () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe("for...of assignment destructuring", () => {
|
||||
test("assigns entry pairs into predeclared variables", async () => {
|
||||
expect(
|
||||
await value(`
|
||||
let key
|
||||
let item
|
||||
const out = []
|
||||
for ([key, item] of Object.entries({ a: 1, b: 2 })) out.push(key + item)
|
||||
return { key, item, out }
|
||||
`),
|
||||
).toEqual({ key: "b", item: 2, out: ["a1", "b2"] })
|
||||
})
|
||||
|
||||
test("assigns object patterns and defaults", async () => {
|
||||
expect(
|
||||
await value(`
|
||||
let id
|
||||
let label
|
||||
const labels = []
|
||||
for ({ id, label = "unknown" } of [{ id: 1 }, { id: 2, label: "two" }]) labels.push(label)
|
||||
return { id, label, labels }
|
||||
`),
|
||||
).toEqual({ id: 2, label: "two", labels: ["unknown", "two"] })
|
||||
})
|
||||
})
|
||||
|
||||
describe("sequence expressions", () => {
|
||||
test("evaluate left to right and return the final value", async () => {
|
||||
expect(await value(`let x = 0; const result = (x += 1, x *= 3, x + 2); return { x, result }`)).toEqual({
|
||||
x: 3,
|
||||
result: 5,
|
||||
})
|
||||
})
|
||||
|
||||
test("support comma-separated for-loop updates", async () => {
|
||||
expect(
|
||||
await value(`
|
||||
const pairs = []
|
||||
for (let left = 0, right = 3; left < right; left++, right--) pairs.push([left, right])
|
||||
return pairs
|
||||
`),
|
||||
).toEqual([
|
||||
[0, 3],
|
||||
[1, 2],
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe("destructuring assignment", () => {
|
||||
test("assigns object and array patterns to existing bindings", async () => {
|
||||
expect(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue