add bare word/number parsing
This commit is contained in:
parent
55ecdc9f2a
commit
b8c09a905b
@ -39,3 +39,56 @@ func ReadString(r io.Reader) (types.Str, error) {
|
||||
}
|
||||
return types.Str(ret), nil
|
||||
}
|
||||
|
||||
|
||||
// Returns (isNumber, isFloat). Can never return (false, true)
|
||||
func whatNumber(el string) (bool, bool) {
|
||||
var isFloat bool
|
||||
first := el[0]
|
||||
|
||||
var start int
|
||||
if first == '-' {
|
||||
if len(el) == 1 {
|
||||
return false, false
|
||||
}
|
||||
start = 1
|
||||
}
|
||||
|
||||
el = el[start:]
|
||||
for i := range el {
|
||||
if el[i] == '.' {
|
||||
isFloat = true
|
||||
} else if el[i] < '0' || el[i] > '9' {
|
||||
return false, false
|
||||
}
|
||||
}
|
||||
|
||||
return true, isFloat
|
||||
}
|
||||
|
||||
// Given a string with no spaces and with a length >= 1, parses it into either a
|
||||
// number or string.
|
||||
func ParseBareElement(el string) (types.Elem, error) {
|
||||
isNumber, isFloat := whatNumber(el)
|
||||
if isNumber {
|
||||
if isFloat {
|
||||
f, err := strconv.ParseFloat(el, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return types.Float(f), nil
|
||||
} else {
|
||||
i, err := strconv.ParseInt(el, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return types.Int(i), nil
|
||||
}
|
||||
}
|
||||
|
||||
if el[0] == ':' {
|
||||
return types.Str(el), nil
|
||||
}
|
||||
|
||||
return types.Str(":"+el), nil
|
||||
}
|
||||
|
BIN
parse/parse.test
BIN
parse/parse.test
Binary file not shown.
@ -28,3 +28,31 @@ func TestReadString(t *T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseBareElement(t *T) {
|
||||
m := map[string]types.Elem{
|
||||
`1`: types.Int(1),
|
||||
`12`: types.Int(12),
|
||||
`-1`: types.Int(-1),
|
||||
`-12`: types.Int(-12),
|
||||
|
||||
`1.0`: types.Float(1.0),
|
||||
`12.5`: types.Float(12.5),
|
||||
`-12.5`: types.Float(-12.5),
|
||||
|
||||
`-`: types.Str(":-"),
|
||||
|
||||
`bare`: types.Str(":bare"),
|
||||
`:not-bare`: types.Str(":not-bare"),
|
||||
}
|
||||
|
||||
for input, output := range m {
|
||||
el, err := ParseBareElement(input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if output != el {
|
||||
t.Fatalf("`%s` != `%s`", output, el)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ package types
|
||||
type Elem interface {
|
||||
}
|
||||
|
||||
// Number can either be either an Int or a Float
|
||||
type Number interface {
|
||||
}
|
||||
|
||||
type Str string
|
||||
|
||||
type Int int
|
||||
|
Loading…
Reference in New Issue
Block a user