diff --git a/parse/parse.go b/parse/parse.go new file mode 100644 index 0000000..fdaee4c --- /dev/null +++ b/parse/parse.go @@ -0,0 +1,41 @@ +package parse + +import ( + "bufio" + "io" + "strconv" + + "github.com/mediocregopher/ginger/types" +) + +//func ReadElem(r io.Reader) (types.Elem, error) { +// buf := bufio.NewReader(r) +// var err error +// for { +// } +//} + +// ReadString reads in a string from the given reader. It assumes the first +// double-quote has already been read off. Ginger strings are wrapped with " and +// are allowed to have newlines literal in them. In all other respects they are +// the same as go strings. +func ReadString(r io.Reader) (types.Str, error) { + buf := bufio.NewReader(r) + str := types.Str("\"") + for { + piece, err := buf.ReadBytes('"') + if err != nil { + return "", err + } + str += types.Str(piece) + if piece[len(piece)-2] != '\\' { + break + } + } + + ret, err := strconv.Unquote(string(str)) + if err != nil { + return "", err + } + return types.Str(ret), nil +} diff --git a/parse/parse.test b/parse/parse.test new file mode 100755 index 0000000..21bbafc Binary files /dev/null and b/parse/parse.test differ diff --git a/parse/parse_test.go b/parse/parse_test.go new file mode 100644 index 0000000..2ce7653 --- /dev/null +++ b/parse/parse_test.go @@ -0,0 +1,30 @@ +package parse + +import ( + "bytes" + . "testing" + + "github.com/mediocregopher/ginger/types" +) + +func TestReadString(t *T) { + m := map[string]types.Str{ + `"hey there"`: "hey there", + `"hey\nthere"`: "hey\nthere", + `"hey there ⌘"`: "hey there ⌘", + `"hey\nthere \u2318"`: "hey\nthere ⌘", + } + + for input, output := range m { + buf := bytes.NewBufferString(input) + buf.ReadByte() + + parseOut, err := ReadString(buf) + if err != nil { + t.Fatal(err) + } + if output != parseOut { + t.Fatalf("`%s` != `%s`", output, parseOut) + } + } +}