mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
package compiler
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"path"
|
|
"path/filepath"
|
|
"runtime"
|
|
"text/template"
|
|
|
|
"github.com/Masterminds/sprig"
|
|
"github.com/vsariola/sointu"
|
|
)
|
|
|
|
//go:generate go run generate.go
|
|
|
|
type Compiler struct {
|
|
Template *template.Template
|
|
Amd64 bool
|
|
OS string
|
|
DisableSections bool
|
|
}
|
|
|
|
// New returns a new compiler using the default .asm templates
|
|
func New() (*Compiler, error) {
|
|
_, myname, _, _ := runtime.Caller(0)
|
|
templateDir := filepath.Join(path.Dir(myname), "..", "templates")
|
|
compiler, err := NewFromTemplates(templateDir)
|
|
return compiler, err
|
|
}
|
|
|
|
func NewFromTemplates(directory string) (*Compiler, error) {
|
|
globPtrn := filepath.Join(directory, "*.*")
|
|
tmpl, err := template.New("base").Funcs(sprig.TxtFuncMap()).ParseGlob(globPtrn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not create template based on directory "%v": %v`, directory, err)
|
|
}
|
|
return &Compiler{Template: tmpl, Amd64: runtime.GOARCH == "amd64", OS: runtime.GOOS}, nil
|
|
}
|
|
|
|
func (com *Compiler) compile(templateName string, data interface{}) (string, error) {
|
|
result := bytes.NewBufferString("")
|
|
err := com.Template.ExecuteTemplate(result, templateName, data)
|
|
return result.String(), err
|
|
}
|
|
|
|
func (com *Compiler) Library() (map[string]string, error) {
|
|
features := AllFeatures{}
|
|
m := NewMacros(*com, features)
|
|
m.Library = true
|
|
asmCode, err := com.compile("library.asm", m)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not execute template "library.asm": %v`, err)
|
|
}
|
|
|
|
m = NewMacros(*com, features)
|
|
m.Library = true
|
|
header, err := com.compile("library.h", &m)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not execute template "library.h": %v`, err)
|
|
}
|
|
return map[string]string{"asm": asmCode, "h": header}, nil
|
|
}
|
|
|
|
func (com *Compiler) Player(song *sointu.Song, maxSamples int) (map[string]string, error) {
|
|
features := NecessaryFeaturesFor(song.Patch)
|
|
encodedPatch, err := Encode(&song.Patch, features)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not encode patch: %v`, err)
|
|
}
|
|
asmCode, err := com.compile("player.asm", NewPlayerMacros(*com, features, song, encodedPatch, maxSamples))
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not execute template "player.asm": %v`, err)
|
|
}
|
|
|
|
header, err := com.compile("player.h", NewPlayerMacros(*com, features, song, encodedPatch, maxSamples))
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not execute template "player.h": %v`, err)
|
|
}
|
|
return map[string]string{"asm": asmCode, "h": header}, nil
|
|
}
|