package zig import ( "fmt" "io" ) type formatter struct { io.Writer } func (f *formatter) WriteString(s string) (n int, err error) { return f.Write([]byte(s)) } func (f *formatter) Writef(format string, a ...any) (err error) { _, err = fmt.Fprintf(f, format, a...) return err } func Write(w io.Writer, root *Root) error { f := &formatter{Writer: w} if root.ContainerDocComment != "" { if err := f.Writef("//! %s\n\n", root.ContainerDocComment); err != nil { return err } } for _, member := range root.ContainerMembers { // Only handle Decl for now (fields not needed for hello world) if member.Decl != nil { if err := writeDecl(f, member.Decl); err != nil { return err } } } return nil } func writeDecl(f *formatter, decl Decl) error { switch fn := decl.(type) { case *FnDecl: if err := f.Writef("fn %s(", fn.Name); err != nil { return err } if err := writeParams(f, fn.Params); err != nil { return err } if _, err := f.WriteString(") "); err != nil { return err } if err := writeTypeExpr(f, fn.ReturnType); err != nil { return err } if err := writeBlock(f, fn.Body); err != nil { return err } } return nil } func writeParams(f *formatter, params []*ParamDecl) error { for i, param := range params { if i > 0 { if _, err := f.WriteString(", "); err != nil { return err } } if param.Name != "" { if _, err := f.WriteString(param.Name); err != nil { return err } if _, err := f.WriteString(": "); err != nil { return err } } if err := writeTypeExpr(f, param.Type); err != nil { return err } } return nil } func writeTypeExpr(f *formatter, typ TypeExpr) error { switch t := typ.(type) { case *Identifier: _, err := f.WriteString(t.Name) return err case nil: return nil default: // fallback: print as string _, err := f.WriteString(fmt.Sprintf("%v", t)) return err } } func writeBlock(f *formatter, block *Block) error { if block == nil { _, err := f.WriteString(";") return err } if _, err := f.WriteString(" {\n"); err != nil { return err } for _, stmt := range block.Stmts { if err := writeStmt(f, stmt); err != nil { return err } if _, err := f.WriteString("\n"); err != nil { return err } } if _, err := f.WriteString("}\n"); err != nil { return err } return nil } func writeStmt(f *formatter, stmt Stmt) error { switch stmt.(type) { case *ReturnStmt: if _, err := f.WriteString("return;"); err != nil { return err } } return nil }