Skip to content

Commit

Permalink
Merge pull request #1630 from DanielXMoore/for-each-amp
Browse files Browse the repository at this point in the history
Fix placeholders in `for each` loops
  • Loading branch information
edemaine authored Dec 2, 2024
2 parents 24c6391 + 103354b commit 06addc3
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
1 change: 1 addition & 0 deletions source/parser/for.civet
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ function processForInOf($0: [
type: "Declaration"
children: [declaration, " = ", trimFirstSpace(expRef), "[", counterRef, "]"]
names: assignmentNames
implicitLift: true
}, ";"]

declaration =
Expand Down
8 changes: 7 additions & 1 deletion source/parser/lib.civet
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,13 @@ function processPlaceholders(statements: StatementTuple[]): void
// Ampersand placeholder & lifts to nearest call expression,
// excluding the call itself, or else to the nearest block statement.
let child
let implicitLift: boolean?
{ ancestor, child } = findAncestor exp, (ancestor, child) =>
// Skip this node of its child told us to
prevImplicitLift := implicitLift
{implicitLift} = ancestor as Declaration
return if prevImplicitLift

{type} := ancestor
if type is "IfStatement"
liftedIfs.add ancestor
Expand Down Expand Up @@ -1646,7 +1652,7 @@ function processPlaceholders(statements: StatementTuple[]): void
typeSuffix ??= placeholder.typeSuffix
// NOTE: Replace last child instead of placeholder itself
// so that we preserve any whitespace that's been glommed as a prefix
replaceNode placeholder.children.-1, ref
placeholder.children.-1 = ref

// Function wrapping can change parent; use original for replaceNode
{parent} := ancestor
Expand Down
3 changes: 3 additions & 0 deletions source/parser/types.civet
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ export type Declaration =
decl: "let" | "const" | "var"
splices?: unknown
thisAssignments?: ThisAssignments
// Should placeholders in contents be lifted above the parent block,
// because they actual came from code outside the block?
implicitLift?: boolean

export type Binding =
type: "Binding"
Expand Down
11 changes: 11 additions & 0 deletions test/function-block-shorthand.civet
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,17 @@ describe "&. function block shorthand", ->
ParseErrors: unknown:1:6 Lone placeholder (&) is not a valid left-hand side
"""

testCase """
for each
---
for each bit of &
Number bit
---
$ => { const results=[];for (let i = 0, len = $.length; i < len; i++) {const bit = $[i];
results.push(Number(bit))
};return results;}
"""

describe "multiple &", ->
testCase """
self-addition
Expand Down

0 comments on commit 06addc3

Please sign in to comment.