This commit is contained in:
Michael McLoughlin
2018-11-06 21:10:54 -05:00
parent 099f29d941
commit 5fb985ad23
2 changed files with 138 additions and 0 deletions

53
ast.go Normal file
View File

@@ -0,0 +1,53 @@
package avo
// GoType represents a Golang type.
type GoType interface{}
// Parameter represents a parameter to an assembly function.
type Parameter struct {
Name string
Type GoType
}
// Instruction is a single instruction in a function.
type Instruction struct {
Mnemonic string
Operands []string
}
// File represents an assembly file.
type File struct {
functions []*Function
}
// Function represents an assembly function.
type Function struct {
name string
params []Parameter
inst []Instruction
}
func NewFunction(name string) *Function {
return &Function{
name: name,
}
}
func (f *Function) AddInstruction(i Instruction) {
f.inst = append(f.inst, i)
}
// Name returns the function name.
func (f *Function) Name() string { return f.name }
// FrameBytes returns the size of the stack frame in bytes.
func (f *Function) FrameBytes() int {
// TODO(mbm): implement
return 0
}
// ArgumentBytes returns the size of the arguments in bytes.
func (f *Function) ArgumentBytes() int {
// TODO(mbm): implement
return 0
}

85
printer.go Normal file
View File

@@ -0,0 +1,85 @@
package avo
import (
"fmt"
"io"
"strings"
)
// 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()
for _, fn := range f.functions {
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())
for _, i := range f.inst {
p.printf("\t%s\t%s\n", i.Mnemonic, strings.Join(i.Operands, ", "))
}
}
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
}
}