package main import ( "fmt" "regexp" "strconv" ) func isName(s string) bool { reg := regexp.MustCompile(`^"[A-Za-z]\w*$`) return reg.MatchString(s) } func toName(s string) string { if !isName(s) { panic(fmt.Errorf("name: %s (%s)", errInvalidName, s)) } return s[1:] } func isNumber(s string) bool { if s != "" && s[0] == '"' { s = s[1:] } _, err := strconv.ParseFloat(s, 64) return err == nil } func toNumber(s string) float64 { if s != "" && s[0] == '"' { s = s[1:] } val, err := strconv.ParseFloat(s, 64) if err != nil { panic(fmt.Errorf("number: %s (%s)", errInvalidNumber, s)) } return val } func isWord(s string) bool { return s != "" && s[0] == '"' } func isList(s string) bool { return s != "" && s[0] == '[' } func isBool(s string) bool { if s != "" && s[0] == '"' { s = s[1:] } _, err := strconv.ParseBool(s) return err == nil } func toBool(s string) bool { if s != "" && s[0] == '"' { s = s[1:] } val, err := strconv.ParseBool(s) if err != nil { panic(fmt.Errorf("bool: %s (%s)", errInvalidBool, s)) } return val } func isEmpty(s string) bool { return s == `"` || s == "[ ]" } func isValue(s string) bool { return isNumber(s) || isWord(s) || isList(s) || isBool(s) } func opIsName(val1 value) value { return value{val: strconv.FormatBool(isName(val1.val))} } func opIsNumber(val1 value) value { return value{val: strconv.FormatBool(isNumber(val1.val))} } func opIsWord(val1 value) value { return value{val: strconv.FormatBool(isWord(val1.val))} } func opIsList(val1 value) value { return value{val: strconv.FormatBool(isList(val1.val))} } func opIsBool(val1 value) value { return value{val: strconv.FormatBool(isBool(val1.val))} } func opIsEmpty(val1 value) value { return value{val: strconv.FormatBool(isEmpty(val1.val))} }