1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
package gen
import (
"fmt"
"github.com/mmcloughlin/avo/internal/api"
"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%q\n", api.ImportPath(api.IRPackage))
b.Printf("\t%q\n", api.ImportPath(api.OperandPackage))
b.Printf("\t%q\n", api.ImportPath("x86"))
b.Printf(")\n\n")
// Helper to reduce source code size a little.
b.Printf("func (c *Context) addinstruction(i *ir.Instruction, err error) {\n")
b.Printf("if err == nil { c.Instruction(i) }")
b.Printf(" else { c.adderror(err) }\n")
b.Printf("}\n\n")
// Generate build functions.
fns := api.InstructionsFunctions(is)
for _, fn := range fns {
b.function(fn)
}
return b.Result()
}
func (b *build) function(fn *api.Function) {
s := fn.Signature()
d := fn.Doc()
// Context method.
methoddoc := append([]string{}, d...)
methoddoc = append(methoddoc, fmt.Sprintf("Construct and append a %s instruction to the active function.", fn.Opcode()))
b.Comment(methoddoc...)
b.Printf("func (c *Context) %s(%s) {\n", fn.Name(), s.ParameterList())
b.Printf("c.addinstruction(x86.%s(%s))", fn.Name(), s.Arguments())
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", fn.Name(), s.ParameterList(), fn.Name(), s.Arguments())
}
|