mal-go/read/read.go
2025-11-04 05:50:37 -10:00

58 lines
1.1 KiB
Go

package read
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
}