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 }