diff --git a/parse/parse.go b/parse/parse.go index fdaee4c..7bde510 100644 --- a/parse/parse.go +++ b/parse/parse.go @@ -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 +} diff --git a/parse/parse.test b/parse/parse.test index 21bbafc..d59e3a5 100755 Binary files a/parse/parse.test and b/parse/parse.test differ diff --git a/parse/parse_test.go b/parse/parse_test.go index 2ce7653..1eef42d 100644 --- a/parse/parse_test.go +++ b/parse/parse_test.go @@ -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) + } + } +} diff --git a/types/types.go b/types/types.go index c3df1b7..d552fc9 100644 --- a/types/types.go +++ b/types/types.go @@ -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