add label type
This commit is contained in:
22
ast.go
22
ast.go
@@ -17,12 +17,22 @@ type Operand interface {
|
|||||||
Asm
|
Asm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Node interface {
|
||||||
|
node()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Label string
|
||||||
|
|
||||||
|
func (l Label) node() {}
|
||||||
|
|
||||||
// Instruction is a single instruction in a function.
|
// Instruction is a single instruction in a function.
|
||||||
type Instruction struct {
|
type Instruction struct {
|
||||||
Opcode string
|
Opcode string
|
||||||
Operands []Operand
|
Operands []Operand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i Instruction) node() {}
|
||||||
|
|
||||||
// File represents an assembly file.
|
// File represents an assembly file.
|
||||||
type File struct {
|
type File struct {
|
||||||
Functions []*Function
|
Functions []*Function
|
||||||
@@ -36,7 +46,7 @@ func NewFile() *File {
|
|||||||
type Function struct {
|
type Function struct {
|
||||||
name string
|
name string
|
||||||
params []Parameter
|
params []Parameter
|
||||||
inst []Instruction
|
nodes []Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFunction(name string) *Function {
|
func NewFunction(name string) *Function {
|
||||||
@@ -46,7 +56,15 @@ func NewFunction(name string) *Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Function) AddInstruction(i Instruction) {
|
func (f *Function) AddInstruction(i Instruction) {
|
||||||
f.inst = append(f.inst, i)
|
f.AddNode(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Function) AddLabel(l Label) {
|
||||||
|
f.AddNode(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Function) AddNode(n Node) {
|
||||||
|
f.nodes = append(f.nodes, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the function name.
|
// Name returns the function name.
|
||||||
|
|||||||
@@ -26,11 +26,19 @@ func (c *Context) Function(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Instruction(i avo.Instruction) {
|
func (c *Context) Instruction(i avo.Instruction) {
|
||||||
|
c.node(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Label(l avo.Label) {
|
||||||
|
c.node(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) node(n avo.Node) {
|
||||||
if c.function == nil {
|
if c.function == nil {
|
||||||
c.AddErrorMessage("no active function")
|
c.AddErrorMessage("no active function")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.function.AddInstruction(i)
|
c.function.AddNode(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate avogen -output zinstructions.go build
|
//go:generate avogen -output zinstructions.go build
|
||||||
@@ -47,7 +55,7 @@ func (c *Context) Result() (*avo.File, []error) {
|
|||||||
return c.file, c.errs
|
return c.file, c.errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Generate(wout, werr io.Writer) {
|
func (c *Context) Main(wout, werr io.Writer) int {
|
||||||
diag := log.New(werr, "", 0)
|
diag := log.New(werr, "", 0)
|
||||||
|
|
||||||
f, errs := c.Result()
|
f, errs := c.Result()
|
||||||
@@ -55,11 +63,14 @@ func (c *Context) Generate(wout, werr io.Writer) {
|
|||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
diag.Println(err)
|
diag.Println(err)
|
||||||
}
|
}
|
||||||
return
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
p := avo.NewGoPrinter(wout)
|
p := avo.NewGoPrinter(wout)
|
||||||
if err := p.Print(f); err != nil {
|
if err := p.Print(f); err != nil {
|
||||||
diag.Fatal(err)
|
diag.Println(err)
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/mmcloughlin/avo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ctx provides a global build context.
|
// ctx provides a global build context.
|
||||||
var ctx = NewContext()
|
var ctx = NewContext()
|
||||||
|
|
||||||
func TEXT(name string) { ctx.Function(name) }
|
func TEXT(name string) { ctx.Function(name) }
|
||||||
|
func LABEL(name string) { ctx.Label(avo.Label(name)) }
|
||||||
|
|
||||||
var (
|
var (
|
||||||
output = flag.String("output", "", "output filename (default stdout)")
|
output = flag.String("output", "", "output filename (default stdout)")
|
||||||
@@ -31,5 +34,5 @@ func EOF() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Generate(w, os.Stderr)
|
os.Exit(ctx.Main(w, os.Stderr))
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
11
printer.go
11
printer.go
@@ -69,8 +69,15 @@ func (p *GoPrinter) multicomment(lines []string) {
|
|||||||
func (p *GoPrinter) function(f *Function) {
|
func (p *GoPrinter) function(f *Function) {
|
||||||
p.printf("TEXT %s%s(SB),0,$%d-%d\n", dot, f.Name(), f.FrameBytes(), f.ArgumentBytes())
|
p.printf("TEXT %s%s(SB),0,$%d-%d\n", dot, f.Name(), f.FrameBytes(), f.ArgumentBytes())
|
||||||
|
|
||||||
for _, i := range f.inst {
|
for _, node := range f.nodes {
|
||||||
p.printf("\t%s\t%s\n", i.Opcode, joinOperands(i.Operands))
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user