package gen import ( "fmt" "github.com/mmcloughlin/avo/internal/inst" "github.com/mmcloughlin/avo/internal/prnt" "github.com/mmcloughlin/avo/printer" ) type build struct { cfg printer.Config prnt.Generator } // NewBuild builds a printer that will generate instruction functions in the // build package. Each instruction will have one method on the build.Context // type, and a corresponding wrapper operating on the global Context. These // functions are thin wrappers around constructors generated by NewCtors. func NewBuild(cfg printer.Config) Interface { return GoFmt(&build{cfg: cfg}) } func (b *build) Generate(is []inst.Instruction) ([]byte, error) { b.Printf("// %s\n\n", b.cfg.GeneratedWarning()) b.Printf("package build\n\n") b.Printf("import (\n") b.Printf("\t\"%s/operand\"\n", pkg) b.Printf("\t\"%s/x86\"\n", pkg) b.Printf(")\n\n") for _, i := range is { b.instruction(i) } return b.Result() } func (b *build) instruction(i inst.Instruction) { s := params(i) d := doc(i) // Context method. methoddoc := append([]string{}, d...) methoddoc = append(methoddoc, fmt.Sprintf("Construct and append a %s instruction to the active function.", i.Opcode)) b.Comment(methoddoc...) b.Printf("func (c *Context) %s(%s) {\n", i.Opcode, s.ParameterList()) b.Printf("if inst, err := x86.%s(%s); err == nil", i.Opcode, s.Arguments()) b.Printf(" { c.Instruction(inst) }") b.Printf(" else { c.adderror(err) }\n") b.Printf("}\n\n") // Global version. globaldoc := append([]string{}, methoddoc...) globaldoc = append(globaldoc, "Operates on the global context.") b.Comment(globaldoc...) b.Printf("func %s(%s) { ctx.%s(%s) }\n\n", i.Opcode, s.ParameterList(), i.Opcode, s.Arguments()) }