109 lines
2.0 KiB
Go

package zig
import (
"fmt"
"io"
)
type formatter struct {
w io.Writer
}
func (f *formatter) WriteString(s string) (n int, err error) {
return f.w.Write([]byte(s))
}
func (f *formatter) Writef(format string, a ...any) (err error) {
_, err = f.w.Write(fmt.Appendf(nil, format, a...))
return err
}
func Write(w io.Writer, root *Root) error {
f := &formatter{
w: w,
}
if root.ContainerDocComment != "" {
err := f.Writef("//! %s\n\n", root.ContainerDocComment)
if err != nil {
return err
}
}
for _, member := range root.ContainerMembers {
for _, decl := range member.Decls {
if err := writeDecl(f, decl); err != nil {
return err
}
}
}
return nil
}
func writeDecl(f *formatter, decl Decl) (err error) {
switch typ := decl.(type) {
case *FnDecl:
if err = f.Writef("fn %s(", typ.Name); err != nil {
return err
}
if err = writeParams(f, typ.Params); err != nil {
return err
}
if err = f.Writef(") %s", typ.ReturnType); err != nil {
return err
}
if err = writeBlock(f, typ.Body); err != nil {
return err
}
}
return nil
}
func writeParams(f *formatter, params []*ParamDecl) (err error) {
for _, param := range params {
if param.Name != "" {
if err = f.Writef("%s: ", param.Name); err != nil {
return err
}
}
if err = f.Writef("%s", param.Type); err != nil {
return err
}
}
return nil
}
func writeBlock(f *formatter, block *Block) (err error) {
if block == nil {
if _, err = f.WriteString(";"); err != nil {
return err
}
return nil
}
if err = f.Writef(" {\n"); err != nil {
return err
}
for _, stmt := range block.Stmts {
if err = writeStmt(f, stmt); err != nil {
return err
}
// Should this be the job of the formatter?
if _, err = f.WriteString("\n"); err != nil {
return err
}
}
if err = f.Writef("}\n"); err != nil {
return err
}
return nil
}
func writeStmt(f *formatter, stmt Stmt) (err error) {
switch stmt.(type) {
case *ReturnStmt:
if _, err = f.WriteString("return;"); err != nil {
return err
}
}
return nil
}