@@ -91,6 +91,9 @@ func (g *Generator) Generate(ns *lang.Namespace) error {
9191
9292 // add lang import
9393 g .addImport ("github.com/glojurelang/glojure/pkg/lang" )
94+ g .addImport ("fmt" ) // for error formatting
95+ g .writef ("// reference fmt to avoid unused import error\n " )
96+ g .writef ("_ = fmt.Printf\n " )
9497
9598 g .writef (" ns := lang.FindOrCreateNamespace(lang.NewSymbol(%#v))\n " , ns .Name ().String ())
9699 g .writef (" _ = ns\n " )
@@ -157,9 +160,14 @@ func (g *Generator) Generate(ns *lang.Namespace) error {
157160
158161 for _ , lifted := range sortedLifted {
159162 // Generate the value - this will write any needed initialization
163+ g .writef ("var %s any\n " , lifted .varName )
164+ g .pushVarScope ()
165+ g .writef ("{\n " )
160166 valueCode := g .generateValue (lifted .value )
161167 // Declare the lifted variable with the final value
162- g .writef (" var %s = %s\n " , lifted .varName , valueCode )
168+ g .writef ("%s = %s\n " , lifted .varName , valueCode )
169+ g .writef ("}\n " )
170+ g .popVarScope ()
163171 }
164172
165173 // Write the lifted values code to init
@@ -180,7 +188,7 @@ func (g *Generator) Generate(ns *lang.Namespace) error {
180188 if err != nil {
181189 // If formatting fails, write the unformatted code with the error
182190 g .originalWriter .Write (sourceBytes )
183- return fmt .Errorf ("formatting failed: %w\n \n Generated code: \n %s " , err , string ( sourceBytes ) )
191+ return fmt .Errorf ("formatting failed: %w\n " , err )
184192 }
185193
186194 // Write formatted code to the original writer
@@ -541,12 +549,14 @@ func (g *Generator) generateSetValue(s lang.IPersistentSet) string {
541549 if idx > 0 {
542550 buf .WriteString (", " )
543551 }
552+ idx ++
544553 element := seq .First ()
545554 elementVar := g .generateValue (element )
546555 buf .WriteString (elementVar )
547556 }
548557
549558 buf .WriteString (")" )
559+
550560 return buf .String ()
551561}
552562
@@ -593,7 +603,6 @@ func (g *Generator) generateFn(fn *runtime.Fn) string {
593603
594604 g .writef ("%s = lang.NewFnFunc(func(args ...any) any {\n " , fnVar )
595605
596- g .addImport ("fmt" ) // Import fmt for error formatting
597606 // Check arity
598607 g .writef (" if len(args) != %d {\n " , methodNode .FixedArity )
599608 g .writef (" panic(lang.NewIllegalArgumentError(\" wrong number of arguments (\" + fmt.Sprint(len(args)) + \" )\" ))\n " )
@@ -667,6 +676,7 @@ func (g *Generator) generateFnMethod(methodNode *ast.FnMethodNode, argsVar strin
667676 if i < methodNode .FixedArity {
668677 // Regular parameter
669678 g .writef ("%s := %s[%d]\n " , paramVar , argsVar , i )
679+ g .writeAssign ("_" , paramVar ) // Prevent unused variable warning
670680 paramVars [i ] = paramVar
671681 } else {
672682 // Variadic parameter - collect rest args
@@ -869,8 +879,15 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
869879 letNode := node .Sub .(* ast.LetNode )
870880
871881 // Push a new variable scope for the let bindings
882+ resultId := g .allocateTempVar ()
883+ g .writef ("var %s any\n " , resultId )
884+
885+ g .writef ("{ // let\n " )
872886 g .pushVarScope ()
873- defer g .popVarScope ()
887+ defer func () {
888+ g .popVarScope ()
889+ g .writef ("} // end let\n " )
890+ }()
874891
875892 // Collect binding variable names for recur context if this is a loop
876893 var bindingVars []string
@@ -885,10 +902,11 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
885902 init := bindingNode .Init
886903
887904 // Allocate a Go variable for the Clojure name
888- varName := g . allocateLocal ( name )
905+ g . writef ( "// let binding \" %s \" \n " , name )
889906
890907 // Generate initialization code
891908 initCode := g .generateASTNode (init )
909+ varName := g .allocateLocal (name )
892910 g .writef ("var %s any = %s\n " , varName , initCode )
893911 g .writeAssign ("_" , varName ) // Prevent unused variable warning
894912
@@ -898,13 +916,11 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
898916 }
899917 }
900918
901- resultId := g .allocateTempVar ()
902919 if isLoop {
903920 // Push recur context for this loop
904921 g .pushRecurContext (letNode .LoopID , bindingVars , false )
905922 defer g .popRecurContext ()
906923
907- g .writef ("var %s any\n " , resultId )
908924 g .writef ("for {\n " )
909925 }
910926
@@ -914,10 +930,10 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
914930 g .writeAssign (resultId , result )
915931 g .writef (" break\n " ) // Break out of the loop after the body
916932 g .writef ("}\n " )
917- return resultId
918933 } else {
919- return result
934+ g . writeAssign ( resultId , result )
920935 }
936+ return resultId
921937}
922938
923939func (g * Generator ) generateRecur (node * ast.Node ) string {
@@ -1135,10 +1151,37 @@ func (g *Generator) generateSet(node *ast.Node) string {
11351151 return setId
11361152}
11371153
1154+ var (
1155+ // TODO: fix all these invalid imports
1156+ expectedInvalidImports = map [string ]bool {
1157+ "ExceptionInfo" : true ,
1158+ "LinkedBlockingQueue" : true ,
1159+ "glojure.lang.LineNumberingPushbackReader" : true ,
1160+ "glojure.lang" : true ,
1161+ "java.io.InputStreamReader" : true ,
1162+ "java.io.StringReader" : true ,
1163+ "java.util.concurrent.CountDownLatch" : true ,
1164+ "java.util.concurrent" : true ,
1165+ }
1166+ )
1167+
11381168func (g * Generator ) generateMaybeClass (node * ast.Node ) string {
11391169 sym := node .Sub .(* ast.MaybeClassNode ).Class .(* lang.Symbol )
11401170 pkg := sym .FullName ()
11411171
1172+ v , ok := pkgmap .Get (sym .FullName ())
1173+ // special-case for reflect.Types
1174+ //
1175+ // NB: we're allowing references to exports of packages that aren't in the package map
1176+ // This implies a difference in behavior, where the interpreter would fail while
1177+ // the compiled code would succeed, because the import will cause the go toolchain
1178+ // to pull in the package.
1179+ if ok {
1180+ if t , ok := v .(reflect.Type ); ok {
1181+ return g .getTypeString (t )
1182+ }
1183+ }
1184+
11421185 // find last dot in the package name
11431186 dotIndex := strings .LastIndex (pkg , "." )
11441187 if dotIndex == - 1 {
@@ -1152,6 +1195,12 @@ func (g *Generator) generateMaybeClass(node *ast.Node) string {
11521195 exportedName := pkg [dotIndex + 1 :]
11531196
11541197 packageName := pkgmap .UnmungePkg (mungedPkgName )
1198+
1199+ if _ , ok := expectedInvalidImports [packageName ]; ok {
1200+ // TODO: fix all these invalid imports
1201+ fmt .Println ("Warning: skipping invalid import:" , packageName )
1202+ return "nil"
1203+ }
11551204 alias := g .addImportWithAlias (packageName )
11561205
11571206 return alias + "." + exportedName
@@ -1269,6 +1318,10 @@ func (g *Generator) addImport(pkg string) {
12691318}
12701319
12711320func (g * Generator ) addImportWithAlias (pkg string ) string {
1321+ if pkg == "glojure.lang.LineNumberingPushbackReader" {
1322+ panic ("glojure.lang.LineNumberingPushbackReader is not a valid Go package" )
1323+ }
1324+
12721325 // Check if the package is already imported
12731326 if alias , ok := g .imports [pkg ]; ok {
12741327 return alias // Return existing alias
0 commit comments