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

View File

@ -1,6 +1,7 @@
package read package read
import ( import (
"fmt"
"mal-go/hash_map" "mal-go/hash_map"
"mal-go/symbol" "mal-go/symbol"
"mal-go/vector" "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) res, err, pos = readVector(s, pos, ns)
case '(': case '(':
res, err, pos = readList(s, pos, ns) res, err, pos = readList(s, pos, ns)
default:
return nil, "unexpected char: '" + fmt.Sprint(c) + "'", pos
} }
} }
return res, err, 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) { func readMap(s string, pos int, ns string) (any, any, int) {
m := hash_map.New() 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) { func readList(s string, pos int, ns string) (any, any, int) {

View File

@ -1,10 +1,15 @@
package read package read
import ( import (
"github.com/stretchr/testify/assert" "fmt"
"mal-go/hash_map"
"mal-go/list" "mal-go/list"
"mal-go/symbol" "mal-go/symbol"
"mal-go/vector"
"testing" "testing"
"github.com/stretchr/testify/assert"
"pgregory.net/rapid"
) )
func TestReadInt(t *testing.T) { 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, nil, err, "should read without error")
assert.Equal(t, len(input), pos, "should read the whole string") 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 return newVec
} }
func String(this *Vector) string { func (this *Vector) String() string {
if this == nil { if this.IsEmpty() {
return "[]" return "[]"
} }
var sb strings.Builder var sb strings.Builder
@ -41,10 +41,11 @@ func String(this *Vector) string {
sb.WriteRune(' ') sb.WriteRune(' ')
} }
return sb.String()[:sb.Len()-1] + "]" return sb.String()[:sb.Len()-1] + "]"
} }
func (this *Vector) String() string { func (this *Vector) IsEmpty() bool {
return String(this) return len(this._slice) == 0
} }
func ToList(this *Vector) list.IList { func ToList(this *Vector) list.IList {