92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
// Package acc implements the "addition chain calculator" language: a
|
|
// domain-specific language (DSL) for addition chain computation.
|
|
package acc
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/mmcloughlin/addchain/acc/ir"
|
|
"github.com/mmcloughlin/addchain/acc/parse"
|
|
"github.com/mmcloughlin/addchain/acc/pass"
|
|
"github.com/mmcloughlin/addchain/acc/printer"
|
|
"github.com/mmcloughlin/addchain/internal/errutil"
|
|
)
|
|
|
|
// LoadFile is a convenience for loading an addition chain script from a file.
|
|
func LoadFile(filename string) (p *ir.Program, err error) {
|
|
f, err := os.Open(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer errutil.CheckClose(&err, f)
|
|
return LoadReader(filename, f)
|
|
}
|
|
|
|
// LoadString is a convenience for loading and evaluating an addition chain
|
|
// script from a string.
|
|
func LoadString(src string) (*ir.Program, error) {
|
|
return LoadReader("string", strings.NewReader(src))
|
|
}
|
|
|
|
// LoadReader is a convenience for loading and evaluating an addition chain
|
|
// script.
|
|
func LoadReader(filename string, r io.Reader) (*ir.Program, error) {
|
|
// Parse to AST.
|
|
s, err := parse.Reader(filename, r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Translate to IR.
|
|
p, err := Translate(s)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Evaluate the program.
|
|
if err := pass.Eval(p); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return p, nil
|
|
}
|
|
|
|
// Write is a convenience for writing a program as an addition chain script.
|
|
func Write(w io.Writer, p *ir.Program) error {
|
|
// Build AST.
|
|
s, err := Build(p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Print.
|
|
if err := printer.Fprint(w, s); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Save is a convenience for writing a program to a file.
|
|
func Save(filename string, p *ir.Program) (err error) {
|
|
f, err := os.Create(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer errutil.CheckClose(&err, f)
|
|
return Write(f, p)
|
|
}
|
|
|
|
// String is a convenience for obtaining a program as an addition chain script
|
|
// in string form.
|
|
func String(p *ir.Program) (string, error) {
|
|
var buf bytes.Buffer
|
|
if err := Write(&buf, p); err != nil {
|
|
return "", err
|
|
}
|
|
return buf.String(), nil
|
|
}
|