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

feat(examples): add moul/xmath #3403

Merged
merged 11 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
go.sum linguist-generated text
gnovm/stdlibs/generated.go linguist-generated
gnovm/tests/stdlibs/generated.go linguist-generated
*.gen.gno linguist-generated
*.gen_test.gno linguist-generated
*.gen.go linguist-generated
*.gen_test.go linguist-generated
8 changes: 8 additions & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,20 @@ jobs:
- run: make lint -C ./examples
# TODO: consider running lint on every other directories, maybe in "warning" mode?
# TODO: track coverage

fmt:
name: Run gno fmt on examples
uses: ./.github/workflows/gnofmt_template.yml
with:
path: "examples/..."

generate:
name: Check generated files are up to date
uses: ./.github/workflows/build_template.yml
with:
modulepath: "examples"
go-version: "1.22.x"

mod-tidy:
strategy:
fail-fast: false
Expand Down
3 changes: 3 additions & 0 deletions examples/gno.land/p/moul/xmath/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package xmath

//go:generate go run generator.go
183 changes: 183 additions & 0 deletions examples/gno.land/p/moul/xmath/generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//go:build ignore

package main

import (
"bytes"
"fmt"
"go/format"
"log"
"os"
"strings"
"text/template"
)

type Type struct {
Name string
ZeroValue string
Signed bool
Float bool
}

var types = []Type{
{"Int8", "0", true, false},
{"Int16", "0", true, false},
{"Int32", "0", true, false},
{"Int64", "0", true, false},
{"Int", "0", true, false},
{"Uint8", "0", false, false},
{"Uint16", "0", false, false},
{"Uint32", "0", false, false},
{"Uint64", "0", false, false},
{"Uint", "0", false, false},
{"Float32", "0.0", true, true},
{"Float64", "0.0", true, true},
}

const sourceTpl = `package xmath

{{ range .Types }}
// {{.Name}} helpers
func Max{{.Name}}(a, b {{.Name | lower}}) {{.Name | lower}} {
if a > b {
return a
}
return b
}

func Min{{.Name}}(a, b {{.Name | lower}}) {{.Name | lower}} {
if a < b {
return a
}
return b
}

func Clamp{{.Name}}(value, min, max {{.Name | lower}}) {{.Name | lower}} {
if value < min {
return min
}
if value > max {
return max
}
return value
}
{{if .Signed}}
func Abs{{.Name}}(x {{.Name | lower}}) {{.Name | lower}} {
if x < 0 {
return -x
}
return x
}

func Sign{{.Name}}(x {{.Name | lower}}) {{.Name | lower}} {
if x < 0 {
return -1
}
if x > 0 {
return 1
}
return 0
}
{{end}}
{{end}}
`

const testTpl = `package xmath

import "testing"

{{range .Types}}
func Test{{.Name}}Helpers(t *testing.T) {
// Test Max{{.Name}}
if Max{{.Name}}(1, 2) != 2 {
t.Error("Max{{.Name}}(1, 2) should be 2")
}
{{if .Signed}}if Max{{.Name}}(-1, -2) != -1 {
t.Error("Max{{.Name}}(-1, -2) should be -1")
}{{end}}

// Test Min{{.Name}}
if Min{{.Name}}(1, 2) != 1 {
t.Error("Min{{.Name}}(1, 2) should be 1")
}
{{if .Signed}}if Min{{.Name}}(-1, -2) != -2 {
t.Error("Min{{.Name}}(-1, -2) should be -2")
}{{end}}

// Test Clamp{{.Name}}
if Clamp{{.Name}}(5, 1, 3) != 3 {
t.Error("Clamp{{.Name}}(5, 1, 3) should be 3")
}
if Clamp{{.Name}}(0, 1, 3) != 1 {
t.Error("Clamp{{.Name}}(0, 1, 3) should be 1")
}
if Clamp{{.Name}}(2, 1, 3) != 2 {
t.Error("Clamp{{.Name}}(2, 1, 3) should be 2")
}
{{if .Signed}}
// Test Abs{{.Name}}
if Abs{{.Name}}(-5) != 5 {
t.Error("Abs{{.Name}}(-5) should be 5")
}
if Abs{{.Name}}(5) != 5 {
t.Error("Abs{{.Name}}(5) should be 5")
}

// Test Sign{{.Name}}
if Sign{{.Name}}(-5) != -1 {
t.Error("Sign{{.Name}}(-5) should be -1")
}
if Sign{{.Name}}(5) != 1 {
t.Error("Sign{{.Name}}(5) should be 1")
}
if Sign{{.Name}}({{.ZeroValue}}) != 0 {
t.Error("Sign{{.Name}}({{.ZeroValue}}) should be 0")
}
{{end}}
}
{{end}}
`

func main() {
funcMap := template.FuncMap{
"lower": strings.ToLower,
}

// Generate source file
sourceTmpl := template.Must(template.New("source").Funcs(funcMap).Parse(sourceTpl))
var sourceOut bytes.Buffer
if err := sourceTmpl.Execute(&sourceOut, struct{ Types []Type }{types}); err != nil {
log.Fatal(err)
}

// Format the generated code
formattedSource, err := format.Source(sourceOut.Bytes())
if err != nil {
log.Fatal(err)
}

// Write source file
if err := os.WriteFile("xmath.gen.gno", formattedSource, 0644); err != nil {
log.Fatal(err)
}

// Generate test file
testTmpl := template.Must(template.New("test").Parse(testTpl))
var testOut bytes.Buffer
if err := testTmpl.Execute(&testOut, struct{ Types []Type }{types}); err != nil {
log.Fatal(err)
}

// Format the generated test code
formattedTest, err := format.Source(testOut.Bytes())
if err != nil {
log.Fatal(err)
}

// Write test file
if err := os.WriteFile("xmath.gen_test.gno", formattedTest, 0644); err != nil {
log.Fatal(err)
}

fmt.Println("Generated xmath.gen.gno and xmath.gen_test.gno")
}
1 change: 1 addition & 0 deletions examples/gno.land/p/moul/xmath/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/p/moul/xmath
Loading
Loading