Skip to content

Commit

Permalink
Fixes (part 3) (#152)
Browse files Browse the repository at this point in the history
Following on from #148 and #149, this PR contains various minor fixes:
* slices can now be used with generics
* struct tags are now supported
* lint warnings have been fixed
  • Loading branch information
chriso authored Jun 28, 2024
2 parents f730716 + c9119d6 commit 0a62925
Show file tree
Hide file tree
Showing 6 changed files with 358 additions and 27 deletions.
12 changes: 12 additions & 0 deletions compiler/coroutine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,18 @@ func TestCoroutineYield(t *testing.T) {
coro: func() { GenericStructClosure(3) },
yields: []int{3, 5, 7},
},

{
name: "JSON roundtrip",
coro: func() { JSONRoundTrip(3) },
yields: []int{3, 3},
},

{
name: "generics with slices",
coro: func() { GenericSlice(3) },
yields: []int{0, 1, 2, 0, 1, 2},
},
}

// This emulates the installation of function type information by the
Expand Down
7 changes: 7 additions & 0 deletions compiler/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,10 @@ func (g *genericInstance) gcshapePath() string {
func writeGoShape(b *strings.Builder, tt types.Type) {
b.WriteString("go.shape.")

writeGoShapeType(b, tt)
}

func writeGoShapeType(b *strings.Builder, tt types.Type) {
switch t := tt.Underlying().(type) {
case *types.Basic:
b.WriteString(t.Name())
Expand Down Expand Up @@ -588,6 +592,9 @@ func writeGoShape(b *strings.Builder, tt types.Type) {
b.WriteString(f.Type().String())
}
b.WriteString(" }")
case *types.Slice:
b.WriteString("[]")
writeGoShapeType(b, t.Elem())
default:
panic(fmt.Sprintf("not implemented: %#v (%T)", tt, t))
}
Expand Down
53 changes: 53 additions & 0 deletions compiler/testdata/coroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package testdata

import (
"encoding/json"
"fmt"
"math"
"reflect"
"time"
Expand Down Expand Up @@ -777,3 +779,54 @@ type GenericAdder[A adder] struct{ adder A }
func (b *GenericAdder[A]) Add(n int) int {
return b.adder.Add(n)
}

func JSONRoundTrip(n int) {
b, err := json.Marshal(struct {
N int `json:"n"`
}{n})
if err != nil {
panic(err)
}
if string(b) != fmt.Sprintf(`{"n":%d}`, n) {
panic(fmt.Errorf("unexpected JSON: %v", b))
}

coroutine.Yield[int, any](n)

var result struct {
N int `json:"n"`
}
if err := json.Unmarshal(b, &result); err != nil {
panic(err)
}
coroutine.Yield[int, any](result.N)
}

type Cloner[S ~[]E, E any] struct {
Slice S
}

func (c *Cloner[S, E]) Clone() S {
s2 := make(S, len(c.Slice))
copy(s2, c.Slice)
return s2
}

func GenericSlice(n int) {
ints := make([]int, n)
for i := range ints {
ints[i] = i
}
for _, x := range ints {
coroutine.Yield[int, any](x)
}

cloner := &Cloner[[]int, int]{Slice: ints}
ints2 := cloner.Clone()

clear(ints)

for _, x := range ints2 {
coroutine.Yield[int, any](x)
}
}
Loading

0 comments on commit 0a62925

Please sign in to comment.