Files
avo/printer.go

103 lines
1.8 KiB
Go
Raw Normal View History

2018-11-06 21:10:54 -05:00
package avo
import (
"fmt"
"io"
"strings"
2018-12-02 12:28:33 -08:00
"github.com/mmcloughlin/avo/operand"
2018-11-06 21:10:54 -05:00
)
// dot is the pesky unicode dot used in Go assembly.
const dot = "\u00b7"
type Printer interface {
Print(*File) error
}
type GoPrinter struct {
w io.Writer
by string // generated by
copyright []string
err error
}
func NewGoPrinter(w io.Writer) *GoPrinter {
return &GoPrinter{
w: w,
by: "avo",
}
}
func (p *GoPrinter) SetGeneratedBy(by string) {
p.by = by
}
func (p *GoPrinter) Print(f *File) error {
p.header()
2018-11-30 20:43:31 -08:00
for _, fn := range f.Functions {
2018-11-06 21:10:54 -05:00
p.function(fn)
}
return p.err
}
func (p *GoPrinter) header() {
p.generated()
p.nl()
p.incl("textflag.h")
p.nl()
}
func (p *GoPrinter) generated() {
p.comment(fmt.Sprintf("Code generated by %s. DO NOT EDIT.", p.by))
}
func (p *GoPrinter) incl(path string) {
p.printf("#include \"%s\"\n", path)
}
func (p *GoPrinter) comment(line string) {
p.multicomment([]string{line})
}
func (p *GoPrinter) multicomment(lines []string) {
for _, line := range lines {
p.printf("// %s\n", line)
}
}
func (p *GoPrinter) function(f *Function) {
p.printf("TEXT %s%s(SB),0,$%d-%d\n", dot, f.Name(), f.FrameBytes(), f.ArgumentBytes())
2018-12-02 12:28:33 -08:00
for _, node := range f.Nodes {
2018-11-30 21:37:17 -08:00
switch n := node.(type) {
case Instruction:
p.printf("\t%s\t%s\n", n.Opcode, joinOperands(n.Operands))
case Label:
p.printf("%s:\n", n)
default:
panic("unexpected node type")
}
2018-11-06 21:10:54 -05:00
}
}
func (p *GoPrinter) nl() {
p.printf("\n")
}
func (p *GoPrinter) printf(format string, args ...interface{}) {
if _, err := fmt.Fprintf(p.w, format, args...); err != nil {
p.err = err
}
}
2018-11-20 11:44:44 -06:00
2018-12-02 12:28:33 -08:00
func joinOperands(operands []operand.Op) string {
2018-11-20 11:44:44 -06:00
asm := make([]string, len(operands))
for i, op := range operands {
asm[i] = op.Asm()
}
return strings.Join(asm, ", ")
}