mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-21 06:24:32 -04:00
Play depends on bridge and compile on compiler package. Before, the compiler depended on bridge, but we could not use the compiler to build the library, as the bridge depends on the library. Also, play can now start having slightly more options e.g. wav out etc.
85 lines
2.8 KiB
Go
85 lines
2.8 KiB
Go
package compiler
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"path"
|
|
"path/filepath"
|
|
"runtime"
|
|
"text/template"
|
|
|
|
"github.com/Masterminds/sprig"
|
|
"github.com/vsariola/sointu"
|
|
)
|
|
|
|
type Compiler struct {
|
|
Template *template.Template
|
|
OS string
|
|
Arch string
|
|
}
|
|
|
|
// New returns a new compiler using the default .asm templates
|
|
func New(os string, arch string) (*Compiler, error) {
|
|
_, myname, _, _ := runtime.Caller(0)
|
|
templateDir := filepath.Join(path.Dir(myname), "..", "templates")
|
|
compiler, err := NewFromTemplates(os, arch, templateDir)
|
|
return compiler, err
|
|
}
|
|
|
|
func NewFromTemplates(os string, arch string, templateDirectory string) (*Compiler, error) {
|
|
globPtrn := filepath.Join(templateDirectory, "*.*")
|
|
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`, templateDirectory, err)
|
|
}
|
|
return &Compiler{Template: tmpl, OS: os, Arch: arch}, nil
|
|
}
|
|
|
|
func (com *Compiler) Library() (map[string]string, error) {
|
|
if com.Arch != "386" && com.Arch != "amd64" {
|
|
return nil, fmt.Errorf(`compiling as a library is supported only on 386 and amd64 architectures (targeted architecture was %v)`, com.Arch)
|
|
}
|
|
templates := []string{"library.asm", "library.h"}
|
|
features := AllFeatures{}
|
|
retmap := map[string]string{}
|
|
for _, templateName := range templates {
|
|
macros := NewMacros(*com, features)
|
|
macros.Library = true
|
|
populatedTemplate, extension, err := com.compile(templateName, macros)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not execute template "%v": %v`, templateName, err)
|
|
}
|
|
retmap[extension] = populatedTemplate
|
|
}
|
|
return retmap, nil
|
|
}
|
|
|
|
func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) {
|
|
if com.Arch != "386" && com.Arch != "amd64" {
|
|
return nil, fmt.Errorf(`compiling a song player is supported only on 386 and amd64 architectures (targeted architecture was %v)`, com.Arch)
|
|
}
|
|
templates := []string{"player.asm", "player.h"}
|
|
features := NecessaryFeaturesFor(song.Patch)
|
|
retmap := map[string]string{}
|
|
encodedPatch, err := Encode(&song.Patch, features)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not encode patch: %v`, err)
|
|
}
|
|
for _, templateName := range templates {
|
|
macros := NewPlayerMacros(*com, features, song, encodedPatch)
|
|
populatedTemplate, extension, err := com.compile(templateName, macros)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(`could not execute template "%v": %v`, templateName, err)
|
|
}
|
|
retmap[extension] = populatedTemplate
|
|
}
|
|
return retmap, nil
|
|
}
|
|
|
|
func (com *Compiler) compile(templateName string, data interface{}) (string, string, error) {
|
|
result := bytes.NewBufferString("")
|
|
err := com.Template.ExecuteTemplate(result, templateName, data)
|
|
extension := filepath.Ext(templateName)
|
|
return result.String(), extension, err
|
|
}
|