> For the complete documentation index, see [llms.txt](https://gofast.disasm.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gofast.disasm.dev/examples/expand-variable-declarations.md).

# Expand Variable Declarations

```go
// ExpandVarDeclarationVisitor splits multi-declarator var statements
// AND extracts side-effect expressions from SequenceExpressions
type ExpandVarDeclarationVisitor struct {
	ast.NoopVisitor
}

func (v *ExpandVarDeclarationVisitor) VisitBlockStatement(n *ast.BlockStatement) {
	// Recursively visit children first
	for i := range n.List {
		n.List[i].VisitWith(v)
	}

	var newStmts []ast.Statement
	for _, s := range n.List {
		varDecl, ok := s.Stmt.(*ast.VariableDeclaration)
		if !ok {
			// Not a var declaration, keep as is
			newStmts = append(newStmts, s)
			continue
		}

		// 1) If this var declaration has multiple declarators (e.g. `var a=1, b=2`)
		//    split them into separate statements: `var a=1; var b=2;`
		if len(varDecl.List) > 1 {
			for _, decl := range varDecl.List {
				newVarDecl := &ast.VariableDeclaration{
					Token: varDecl.Token,
					List:  ast.VariableDeclarators{decl},
				}
				newStmts = append(newStmts, ast.Statement{Stmt: newVarDecl})
			}
			continue
		}

		// Exactly one declarator. Flatten any SequenceExpression in the initializer.
		singleDecl := varDecl.List[0] // guaranteed length=1

		// Flatten sequence expressions if any
		sideEffects, finalExpr := flattenSequenceExpressions(singleDecl.Initializer)

		// sideEffects => 0..N expressions we turn into ExpressionStatements
		// finalExpr   => the final expression that remains as the "real" initializer
		for _, expr := range sideEffects {
			newStmts = append(newStmts, ast.Statement{
				Stmt: &ast.ExpressionStatement{Expression: &expr},
			})
		}

		// Update the declarator's initializer to the final expression
		singleDecl.Initializer = nil
		if finalExpr != nil {
			// Overwrite with the last expression
			singleDecl.Initializer = finalExpr
		}

		// Now push the single-declarator var
		newStmts = append(newStmts, ast.Statement{Stmt: varDecl})
	}

	n.List = newStmts
}

// flattenSequenceExpressions takes a pointer to an Expression (which might be nil)
// and returns:
//
//	sideEffects: []ast.Expression for all but the last element in a sequence
//	finalExpr:   the last Expression (or nil if none).
//
// For example, if the initializer is a SequenceExpression representing (b=0, -1090),
// we return sideEffects=[(b=0)] and finalExpr=(-1090). That way we can turn (b=0)
// into its own statement, and keep (-1090) as the var initializer.
func flattenSequenceExpressions(init *ast.Expression) (sideEffects []ast.Expression, finalExpr *ast.Expression) {
	if init == nil {
		return nil, nil
	}
	// Gather all sub-expressions from potential nested SequenceExpressions
	items := gatherSequenceItems(*init)
	if len(items) == 0 {
		return nil, nil
	}
	if len(items) == 1 {
		// no side effects, single expression is final
		return nil, &items[0]
	}
	// side effects are everything except the last
	sideEffects = items[:len(items)-1]
	last := items[len(items)-1]
	return sideEffects, &last
}

// gatherSequenceItems flattens nested SequenceExpressions into a single slice of Expressions.
// Example: if `expr` is (b=0, c=1, d=2) => SequenceExpression with 3 items => returns a slice of length 3.
// If `expr` is not a SequenceExpression, we return it as a single item.
func gatherSequenceItems(expr ast.Expression) []ast.Expression {
	seq, ok := expr.Expr.(*ast.SequenceExpression)
	if !ok {
		// Not a SequenceExpression => return single item
		return []ast.Expression{expr}
	}

	// We do have a SequenceExpression => flatten each sub-expression
	var result []ast.Expression
	for _, subExpr := range seq.Sequence {
		// gatherSequenceItems recursively, in case there's nesting
		subItems := gatherSequenceItems(subExpr)
		result = append(result, subItems...)
	}
	return result
}

func ExpandVarDeclaration(p *ast.Program) {
	e := &ExpandVarDeclarationVisitor{}
	e.V = e
	p.VisitWith(e)
}
```

**🧪 How to Use**

```go
prog, _ := parser.ParseFile(src)
ExpandVarDeclaration(prog)

out := generator.Generate(prog)
fmt.Println(out)
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://gofast.disasm.dev/examples/expand-variable-declarations.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
