gotypes,build: add Implement (#58)
By using Implement you can provide a definition of a function, taking the signature from a stub in the package. One major benefit of this approach is it makes it easy to handle external types in the function signature. Updates #55
This commit is contained in:
committed by
GitHub
parent
9c913ee847
commit
eb225e9d2c
33
examples/ext/README.md
Normal file
33
examples/ext/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# ext
|
||||
|
||||
Demonstrates how to use external types in an `avo` function signature.
|
||||
|
||||
In this case, you will need to write the function stub yourself.
|
||||
|
||||
[embedmd]:# (stub.go /package/ $)
|
||||
```go
|
||||
package ext
|
||||
|
||||
import "github.com/mmcloughlin/avo/examples/ext/ext"
|
||||
|
||||
// StructFieldB returns field B.
|
||||
func StructFieldB(e ext.Struct) byte
|
||||
```
|
||||
|
||||
Then in place of the usual `TEXT` declaration we use `Implement` to state that we are beginning the definition of a function already declared in the package stub file.
|
||||
|
||||
[embedmd]:# (asm.go go /.*Package.*/ /RET.*/)
|
||||
```go
|
||||
Package("github.com/mmcloughlin/avo/examples/ext")
|
||||
Implement("StructFieldB")
|
||||
b := Load(Param("e").Field("B"), GP8())
|
||||
Store(b, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
|
||||
Finally, in this case the `go:generate` line is different since we do not need to generate the stub file.
|
||||
|
||||
[embedmd]:# (ext_test.go go /.*go:generate.*/)
|
||||
```go
|
||||
//go:generate go run asm.go -out ext.s
|
||||
```
|
||||
16
examples/ext/asm.go
Normal file
16
examples/ext/asm.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
. "github.com/mmcloughlin/avo/build"
|
||||
)
|
||||
|
||||
func main() {
|
||||
Package("github.com/mmcloughlin/avo/examples/ext")
|
||||
Implement("StructFieldB")
|
||||
b := Load(Param("e").Field("B"), GP8())
|
||||
Store(b, ReturnIndex(0))
|
||||
RET()
|
||||
Generate()
|
||||
}
|
||||
7
examples/ext/ext.s
Normal file
7
examples/ext/ext.s
Normal file
@@ -0,0 +1,7 @@
|
||||
// Code generated by command: go run asm.go -out ext.s. DO NOT EDIT.
|
||||
|
||||
// func StructFieldB(e ext.Struct) byte
|
||||
TEXT ·StructFieldB(SB), $0-25
|
||||
MOVB e_B+6(FP), AL
|
||||
MOVB AL, ret+24(FP)
|
||||
RET
|
||||
9
examples/ext/ext/ext.go
Normal file
9
examples/ext/ext/ext.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Package ext is used as a target package in the external types example.
|
||||
package ext
|
||||
|
||||
// Struct is the target type in the external types example.
|
||||
type Struct struct {
|
||||
A [3]uint16
|
||||
B byte
|
||||
C string
|
||||
}
|
||||
17
examples/ext/ext_test.go
Normal file
17
examples/ext/ext_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package ext
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"testing/quick"
|
||||
|
||||
"github.com/mmcloughlin/avo/examples/ext/ext"
|
||||
)
|
||||
|
||||
//go:generate go run asm.go -out ext.s
|
||||
|
||||
func TestFunc(t *testing.T) {
|
||||
expect := func(e ext.Struct) byte { return e.B }
|
||||
if err := quick.CheckEqual(StructFieldB, expect, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
7
examples/ext/stub.go
Normal file
7
examples/ext/stub.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// Package ext demonstrates how to interact with external types.
|
||||
package ext
|
||||
|
||||
import "github.com/mmcloughlin/avo/examples/ext/ext"
|
||||
|
||||
// StructFieldB returns field B.
|
||||
func StructFieldB(e ext.Struct) byte
|
||||
Reference in New Issue
Block a user