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
|
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 {
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user