@@ -984,8 +984,7 @@ func (g *Generator) generateASTNode(node *ast.Node) (res string) {
984984 case ast .OpDef :
985985 return g .generateDef (node )
986986 case ast .OpLetFn :
987- fmt .Println ("LetFn not yet implemented; returning nil" )
988- return "nil"
987+ return g .generateLetFn (node )
989988 case ast .OpGo :
990989 return g .generateGo (node )
991990 case ast .OpSetBang :
@@ -1294,6 +1293,42 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
12941293 return resultId
12951294}
12961295
1296+ func (g * Generator ) generateLetFn (node * ast.Node ) string {
1297+ letFnNode := node .Sub .(* ast.LetFnNode )
1298+
1299+ resultId := g .allocateTempVar ()
1300+ g .writef ("var %s any\n " , resultId )
1301+
1302+ // Push a new variable scope for the letfn bindings
1303+ g .writef ("{ // letfn\n " )
1304+ g .pushVarScope ()
1305+ defer func () {
1306+ g .popVarScope ()
1307+ g .writef ("} // end letfn\n " )
1308+ }()
1309+
1310+ // Emit bindings directly to g.w
1311+ for _ , binding := range letFnNode .Bindings {
1312+ bindingNode := binding .Sub .(* ast.BindingNode )
1313+ name := bindingNode .Name
1314+ fn := bindingNode .Init
1315+
1316+ // Allocate a Go variable for the Clojure name
1317+ g .writef ("// letfn binding \" %s\" \n " , name )
1318+ varName := g .allocateLocal (name .Name ())
1319+ // declare the variable now to allow for recursion
1320+ g .writef ("var %s lang.FnFunc\n " , varName )
1321+ fnVar := g .generateASTNode (fn )
1322+ g .writeAssign (varName , fnVar )
1323+ g .writeAssign ("_" , varName ) // Prevent unused variable warning
1324+ }
1325+
1326+ // Return the body expression (r-value)
1327+ result := g .generateASTNode (letFnNode .Body )
1328+ g .writeAssign (resultId , result )
1329+ return resultId
1330+ }
1331+
12971332func (g * Generator ) generateRecur (node * ast.Node ) string {
12981333 recurNode := node .Sub .(* ast.RecurNode )
12991334
0 commit comments