129 lines
2.5 KiB
Go

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
}