File: acc.go

package info (click to toggle)
addchain 0.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,396 kB
  • sloc: sh: 428; makefile: 8
file content (91 lines) | stat: -rw-r--r-- 2,117 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// 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
}