Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/addchain: templated output generation #127

Merged
merged 28 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a96a4bd
wip
mmcloughlin Oct 25, 2021
41735a1
wip
mmcloughlin Oct 25, 2021
b041365
skeleton gen command
mmcloughlin Oct 25, 2021
ae54c04
wip: more templates, extend data prep, golden tests
mmcloughlin Oct 25, 2021
3c8b658
change input to curve25519
mmcloughlin Oct 25, 2021
bb960a6
init doc/gen.md
mmcloughlin Oct 25, 2021
04d889d
docs for template functions
mmcloughlin Oct 26, 2021
0ee0fc2
fixed urls in readme
mmcloughlin Oct 26, 2021
bd1b2f7
include builtin templates in doc
mmcloughlin Oct 26, 2021
a0d78bf
tweak builtin template output
mmcloughlin Oct 26, 2021
60e9d64
include the input chain for builin examples
mmcloughlin Oct 26, 2021
ebdab5d
extend example output generation, start fp25519 example
mmcloughlin Oct 26, 2021
c53073c
template functions in table
mmcloughlin Oct 26, 2021
974a466
generate code that compiles
mmcloughlin Oct 27, 2021
1407b2c
fp25519 passing tests
mmcloughlin Oct 27, 2021
3c6fb88
update include path
mmcloughlin Oct 27, 2021
0bebcbe
spruce up example codegen
mmcloughlin Oct 27, 2021
d79babf
more sprucing up
mmcloughlin Oct 27, 2021
1dbe89d
add fp25519 example to docs
mmcloughlin Oct 27, 2021
b79f348
link to working example
mmcloughlin Oct 27, 2021
e70d9fc
rename PrepareData
mmcloughlin Oct 27, 2021
7ce1552
comments and tweaks
mmcloughlin Oct 27, 2021
67480eb
document the template data structure
mmcloughlin Oct 27, 2021
7eb8a5d
lint
mmcloughlin Oct 27, 2021
887991f
fix formatting
mmcloughlin Oct 27, 2021
627c74e
mention from readme
mmcloughlin Oct 27, 2021
dc382fe
simplify sentence
mmcloughlin Oct 27, 2021
11f054a
update usage
mmcloughlin Oct 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ linters:
- maligned
- nlreturn
- paralleltest
- prealloc
- predeclared
- revive
- testpackage
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ generators.
* Generic optimization methods eliminate redundant operations
* Simple domain-specific language for addition chain computations
* Command-line interface or library
* Code generation and templated output support

## Table of Contents

Expand Down Expand Up @@ -106,8 +107,8 @@ delta from the library result.
| [secp256k1 (Bitcoin) Scalar Inversion](doc/results.md#secp256k1-bitcoin-scalar-inversion) | 293 | 290 | +3 |


See [full results listing](doc/results.md) for more detail and results for
less common exponents.
See [full results listing](doc/results.md) for more detail and
results for less common exponents.

These results demonstrate that `addchain` is competitive with hand-optimized
chains, often with equivalent or better performance. Even when `addchain` is
Expand Down Expand Up @@ -162,6 +163,8 @@ x250 = x240 << 10 + x10
return (x250 << 2 + 1) << 3 + _11
```

Next, you can [generate code from this addition chain](doc/gen.md).

### Library

Install:
Expand Down
9 changes: 9 additions & 0 deletions acc/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import (
"github.com/mmcloughlin/addchain/internal/print"
)

// String prints the AST and returns resulting string.
func String(n interface{}) (string, error) {
b, err := Bytes(n)
if err != nil {
return "", err
}
return string(b), nil
}

// Bytes prints the AST and returns resulting bytes.
func Bytes(n interface{}) ([]byte, error) {
var buf bytes.Buffer
Expand Down
118 changes: 118 additions & 0 deletions cmd/addchain/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package main

import (
"context"
"errors"
"flag"
"fmt"
"io/ioutil"
"strings"

"github.com/google/subcommands"

"github.com/mmcloughlin/addchain/acc/parse"
"github.com/mmcloughlin/addchain/acc/pass"
"github.com/mmcloughlin/addchain/internal/cli"
"github.com/mmcloughlin/addchain/internal/gen"
)

// generate subcommand.
type generate struct {
cli.Command

typ string
tmpl string
output string
}

func (*generate) Name() string { return "gen" }
func (*generate) Synopsis() string { return "generate output from an addition chain program" }
func (*generate) Usage() string {
return `Usage: gen [-type <name>] [-tmpl <file>] [-out <file>] [<filename>]

Generate output from an addition chain program.

`
}

func (cmd *generate) SetFlags(f *flag.FlagSet) {
defaulttype := "listing"
if !gen.IsBuiltinTemplate(defaulttype) {
panic("bad default template")
}
f.StringVar(&cmd.typ, "type", defaulttype, fmt.Sprintf("`name` of a builtin template (%s)", strings.Join(gen.BuiltinTemplateNames(), ",")))
f.StringVar(&cmd.tmpl, "tmpl", "", "template `file` (overrides type)")
f.StringVar(&cmd.output, "out", "", "output `file` (default stdout)")
}

func (cmd *generate) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) (status subcommands.ExitStatus) {
// Read input.
input, r, err := cli.OpenInput(f.Arg(0))
if err != nil {
return cmd.Error(err)
}
defer cmd.CheckClose(&status, r)

// Parse to a syntax tree.
s, err := parse.Reader(input, r)
if err != nil {
return cmd.Error(err)
}

// Prepare template data.
cfg := gen.Config{
Allocator: pass.Allocator{
Input: "x",
Output: "z",
Format: "t%d",
},
}

data, err := gen.PrepareData(cfg, s)
if err != nil {
return cmd.Error(err)
}

// Load template.
tmpl, err := cmd.LoadTemplate()
if err != nil {
return cmd.Error(err)
}

// Open output.
_, w, err := cli.OpenOutput(cmd.output)
if err != nil {
return cmd.Error(err)
}
defer cmd.CheckClose(&status, w)

// Generate.
if err := gen.Generate(w, tmpl, data); err != nil {
return cmd.Error(err)
}

return subcommands.ExitSuccess
}

func (cmd *generate) LoadTemplate() (string, error) {
// Explicit filename has precedence.
if cmd.tmpl != "" {
b, err := ioutil.ReadFile(cmd.tmpl)
if err != nil {
return "", err
}
return string(b), nil
}

// Lookup type name in builtin templates.
if cmd.typ == "" {
return "", errors.New("no builtin template specified")
}

s, err := gen.BuiltinTemplate(cmd.typ)
if err != nil {
return "", err
}

return s, nil
}
1 change: 1 addition & 0 deletions cmd/addchain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func main() {
subcommands.Register(&search{Command: base}, "")
subcommands.Register(&eval{Command: base}, "")
subcommands.Register(&format{Command: base}, "")
subcommands.Register(&generate{Command: base}, "")

if meta.Meta.BuildVersion != "" {
subcommands.Register(&version{version: meta.Meta.BuildVersion, Command: base}, "")
Expand Down
Loading