Skip to content

Conversation

@PolLamothe
Copy link
Contributor

Summary

This PR addresses Issue #145 by implementing support for comprehensions and the Walrus operator (:=) in the Control Flow Graph (CFG) generation.

Type of Change

  • feat (new feature)
  • test (added unit/integration tests)

Related Issues

Closes #145

Changes

  • Comprehensions: Added support for list, dict, and set comprehensions in the CFG output.
  • Walrus Operator: Implemented parsing logic for AssignmentExpressions.
  • Testing: Added comprehensive test cases covering nested walrus operators and complex comprehension structures.

Testing

  • go test ./... passes locally
  • Added new test files for walrus parsing logic
  • Verified successful parsing of testdata/python/edge_cases/python310_features.py

Comments

Hi! This task was a bit more challenging than the previous one due to the way the Walrus operator affects scope. I've implemented the parsing and added dedicated tests for it. Let me know if the CFG representation for comprehensions aligns with the project's standards!

@PolLamothe PolLamothe changed the title [FEATURE] Add CFG support for Walrus operator Feat: Add CFG support for Walrus operator Feb 4, 2026
@DaisukeYoda DaisukeYoda self-requested a review February 4, 2026 10:39
Copy link
Member

@DaisukeYoda DaisukeYoda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this! Please check the comments I left.

Comment on lines 464 to 480
case parser.NodeNamedExpr:
// Handle named expressions (walrus operator)
// Check if the value is a comprehension
if stmt.Value != nil {
if valNode, ok := stmt.Value.(*parser.Node); ok {
if valNode.Type == parser.NodeListComp || valNode.Type == parser.NodeDictComp ||
valNode.Type == parser.NodeSetComp || valNode.Type == parser.NodeGeneratorExp {
// Process the comprehension
b.processComprehension(valNode)
// Add the statement after comprehension processing
b.currentBlock.AddStatement(stmt)
}
}
}
// Regular named expression - just add to current block
b.currentBlock.AddStatement(stmt)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the case parser.NodeNamedExpr branch is unreachable. processStatement receives statement-level nodes from node.Body, but walrus expressions like (x := [...]) come wrapped in expression_statement → parenthesized_expression → named_expression. The switch receives expression_statement, not NodeNamedExpr directly, so this code path is never executed.

}
}
// Regular named expression - just add to current block
b.currentBlock.AddStatement(stmt)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing return after processing comprehension causes AddStatement(stmt) to be called twice:
once inside the if block (line 474) and again unconditionally (line 479).

Comment on lines +723 to +741
foundWalrus := false
for _, block := range cfg.Blocks {
for _, stmt := range block.Statements {
stmt.Walk(func(n *parser.Node) bool {
if n.Type == parser.NodeNamedExpr {
foundWalrus = true
return false
}
return true
})
if foundWalrus {
break
}
}
if foundWalrus {
break
}
}
assert.True(t, foundWalrus, "Should find walrus operator")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test only checks for the existence of the walrus node, but doesn't verify that comprehension CFG blocks (comp_init, comp_header, comp_exit) and edges are actually created.
Consider adding assertions for block labels and edge types.

@PolLamothe
Copy link
Contributor Author

Thanks for the comments, sorry for these mistakes, I will fix them!

@DaisukeYoda
Copy link
Member

No worries at all! CFG + AST traversal is genuinely hard. Appreciate you taking this on!

- implement named expression parsing in ast builder
- add comprehension processing in return and assign statements
- add detailed structural tests for walrus and comprehensions
@PolLamothe
Copy link
Contributor Author

I tried to understand better AST and CFG and how we manipulate them.
I added verification of the comprehension in the Walrus operator.
I had to update the ast_builder.
Tell me what you think about this update !

@PolLamothe
Copy link
Contributor Author

I just saw that the test failed, I'm sorry i forgot to run all of them, i only ran my own.
I'm looking into it!

@PolLamothe
Copy link
Contributor Author

The problem seem to be that i'm wrapping every expression in a NodeExpr container even the simple assignation (ex : x = 10), I'm working on fixing this !

@DaisukeYoda
Copy link
Member

Hi! Your approach works, but you might find it simpler to change only cfg_builder instead of ast_builder. This avoids breaking existing tests.

In the NodeExpr case, you can recursively check if NodeNamedExpr contains a comprehension:

case parser.NodeExpr:
    if stmt.Value != nil {
        if valNode, ok := stmt.Value.(*parser.Node); ok {
            // Direct comprehension
            if isComprehension(valNode) {
                b.processComprehension(valNode)
                b.currentBlock.AddStatement(stmt)
                return
            }
            // Walrus containing comprehension: (x := [i for i in ...])
            if valNode.Type == parser.NodeNamedExpr {
                if inner, ok := valNode.Value.(*parser.Node); ok && isComprehension(inner) {
                    b.processComprehension(inner)
                    b.currentBlock.AddStatement(stmt)
                    return
                }
            }
        }
    }
    b.currentBlock.AddStatement(stmt)

This way the AST structure stays unchanged and the fix is localized to CFG building.

- handling comprehension in cfg_builder.go instead of ast_builder.go
- update simple Walrus test to not expect a NodeExpr container
@PolLamothe
Copy link
Contributor Author

Thanks for your help ! I applied what you told me, hope it's good this time 😄 !

@DaisukeYoda
Copy link
Member

@PolLamothe Thanks! It looks good now.

Tip: When ready for re-review, you can click the 🔄 icon next to the reviewer's name.

@PolLamothe
Copy link
Contributor Author

Ok ! i saw it earlier but didn't know if i should use it, thanks for letting me know !

@DaisukeYoda DaisukeYoda merged commit 9976dfd into ludo-technologies:main Feb 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add CFG support for Walrus operator (:=)

2 participants