Compare commits

...

5 Commits

Author SHA1 Message Date
ca2485b725 sprinkle in some PBT
All checks were successful
Go / test (push) Successful in 3s
2025-11-05 06:43:24 -10:00
f816fdc912 implement read empty map 2025-11-05 06:43:14 -10:00
4ed27b8c0e add IsEmpty 2025-11-05 06:43:02 -10:00
656bd7dc27 add error for unknown chars 2025-11-05 06:28:56 -10:00
e906b007de add IsEmpty 2025-11-05 06:28:42 -10:00
4 changed files with 55 additions and 11 deletions

View File

@ -49,8 +49,13 @@ func (this *HashMap) Conj(key any, val any) *HashMap {
return Conj(this, key, val)
}
func String(this *HashMap) string {
if this == nil {
func (this *HashMap) IsEmpty() bool {
return len(this._map) == 0
}
func (this *HashMap) String() string {
if this.IsEmpty() {
return "{}"
}
var sb strings.Builder
@ -63,8 +68,5 @@ func String(this *HashMap) string {
sb.WriteRune(' ')
}
return sb.String()[:sb.Len()-2] + "}"
}
func (this *HashMap) String() string {
return String(this)
}

View File

@ -1,6 +1,7 @@
package read
import (
"fmt"
"mal-go/hash_map"
"mal-go/symbol"
"mal-go/vector"
@ -47,6 +48,8 @@ func readForm(s string, pos int, ns string) (any, any, int) {
res, err, pos = readVector(s, pos, ns)
case '(':
res, err, pos = readList(s, pos, ns)
default:
return nil, "unexpected char: '" + fmt.Sprint(c) + "'", pos
}
}
return res, err, pos
@ -54,7 +57,10 @@ func readForm(s string, pos int, ns string) (any, any, int) {
func readMap(s string, pos int, ns string) (any, any, int) {
m := hash_map.New()
return m, "unimplemented", pos
if s[pos+1] == '}' {
return m, nil, pos + 2
}
return nil, "unimplemented", pos
}
func readList(s string, pos int, ns string) (any, any, int) {

View File

@ -1,10 +1,15 @@
package read
import (
"github.com/stretchr/testify/assert"
"fmt"
"mal-go/hash_map"
"mal-go/list"
"mal-go/symbol"
"mal-go/vector"
"testing"
"github.com/stretchr/testify/assert"
"pgregory.net/rapid"
)
func TestReadInt(t *testing.T) {
@ -47,3 +52,33 @@ func TestReadList(t *testing.T) {
assert.Equal(t, nil, err, "should read without error")
assert.Equal(t, len(input), pos, "should read the whole string")
}
func StringifiedFormGen() *rapid.Generator[string] {
return rapid.OneOf(rapid.Custom(func(t *rapid.T) string {
myList := list.Empty()
i := 200
t.Repeat(map[string]func(*rapid.T){
"conj": func(t *rapid.T) {
if i < 50 {
myList = myList.Conj(StringifiedFormGen().Draw(t, "el"))
}
},
})
return myList.String()
}),
rapid.Just(list.Empty().String()),
rapid.Just(hash_map.New().String()),
rapid.Just(vector.New().String()),
rapid.Custom(func(t *rapid.T) string {
return fmt.Sprint(rapid.Int().Draw(t, "i"))
}),
)
}
func TestRead(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
input := StringifiedFormGen().Draw(t, "input")
_, err, _ := readForm(input, 0, "user")
assert.Nil(t, err, err)
})
}

View File

@ -30,8 +30,8 @@ func (this *Vector) Conj(data any) *Vector {
return newVec
}
func String(this *Vector) string {
if this == nil {
func (this *Vector) String() string {
if this.IsEmpty() {
return "[]"
}
var sb strings.Builder
@ -41,10 +41,11 @@ func String(this *Vector) string {
sb.WriteRune(' ')
}
return sb.String()[:sb.Len()-1] + "]"
}
func (this *Vector) String() string {
return String(this)
func (this *Vector) IsEmpty() bool {
return len(this._slice) == 0
}
func ToList(this *Vector) list.IList {