add TDD for read symbols
This commit is contained in:
+54
-2
@@ -1,5 +1,57 @@
|
||||
package read
|
||||
|
||||
func ReadString(s string) any {
|
||||
return s
|
||||
import (
|
||||
"mal-go/list"
|
||||
"mal-go/symbol"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ReadString(s string) (any, any) {
|
||||
res, err, _ := readInternal(s, 0, nil, "user")
|
||||
return res, err
|
||||
}
|
||||
|
||||
func isSymbolChar(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '-' || c == '/' || c == '\''
|
||||
}
|
||||
|
||||
func readInternal(s string, pos int, ctx *list.List, ns string) (any, any, int) {
|
||||
if pos >= len(s) {
|
||||
return ctx, nil, pos
|
||||
}
|
||||
c := s[pos]
|
||||
|
||||
var res, err any
|
||||
|
||||
if isSymbolChar(c) {
|
||||
res, err, pos2 := readSymbol(s, pos, ns)
|
||||
return res, err, pos2
|
||||
}
|
||||
// switch c {
|
||||
// case '{':
|
||||
// res, err, _ = readInternal(s, pos+1, list.Conj(ctx, hash_map.New()), ns)
|
||||
// case '[':
|
||||
// case '(':
|
||||
// }
|
||||
return res, err, 0
|
||||
}
|
||||
|
||||
func readSymbol(s string, pos int, ns string) (any, any, int) {
|
||||
startingPos := pos
|
||||
c := s[pos]
|
||||
for isSymbolChar(c) {
|
||||
pos += 1
|
||||
if pos >= len(s) {
|
||||
break
|
||||
}
|
||||
c = s[pos]
|
||||
}
|
||||
sym := s[startingPos:pos]
|
||||
symNs := ns
|
||||
if strings.Contains(sym, "/") {
|
||||
splitIdx := strings.Index(s, "/")
|
||||
symNs = s[startingPos:splitIdx]
|
||||
sym = s[splitIdx+1 : pos]
|
||||
}
|
||||
return symbol.Intern(symNs, sym), nil, pos
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package read
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"mal-go/symbol"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReadSymbol(t *testing.T) {
|
||||
input := "foo"
|
||||
sym, err, end_pos := readSymbol(input, 0, "user")
|
||||
assert.Equal(t, sym, symbol.Intern("user", "foo"), "should read user/foo symbol")
|
||||
assert.Equal(t, err, nil, "should read without error")
|
||||
assert.Equal(t, end_pos, len(input), "should read the whole string")
|
||||
}
|
||||
|
||||
func TestReadSymbolWithNamespace(t *testing.T) {
|
||||
input := "foo/bar"
|
||||
sym, err, end_pos := readSymbol(input, 0, "user")
|
||||
assert.Equal(t, sym, symbol.Intern("foo", "bar"), "should read user/foo symbol")
|
||||
assert.Equal(t, err, nil, "should read without error")
|
||||
assert.Equal(t, end_pos, len(input), "should read the whole string")
|
||||
}
|
||||
Reference in New Issue
Block a user