add bare word/number parsing

This commit is contained in:
Brian Picciano 2014-10-14 20:13:10 -04:00
parent 55ecdc9f2a
commit b8c09a905b
4 changed files with 85 additions and 0 deletions

View File

@ -39,3 +39,56 @@ func ReadString(r io.Reader) (types.Str, error) {
} }
return types.Str(ret), nil 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
}

Binary file not shown.

View File

@ -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)
}
}
}

View File

@ -6,6 +6,10 @@ package types
type Elem interface { type Elem interface {
} }
// Number can either be either an Int or a Float
type Number interface {
}
type Str string type Str string
type Int int type Int int