From 88c013b2bc3941a62ab297b3fe33adf07745db4f Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Tue, 31 Mar 2015 13:03:46 -0400 Subject: [PATCH] list nodes parse now --- node.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++ parse.go | 29 +++++++------------------- tests/parse/03.in | 1 + tests/parse/03.out | 10 +++++++++ 4 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 tests/parse/03.in create mode 100644 tests/parse/03.out diff --git a/node.go b/node.go index 7c6122a..70ba88b 100644 --- a/node.go +++ b/node.go @@ -18,6 +18,7 @@ const ( n_assignment n_string n_number + n_list ) var indent = " " @@ -291,5 +292,55 @@ func (n *numberNode) eval(ctx map[string]interface{}) (interface{}, error) { } } +type listNode []node + +func (l *listNode) Type() nodeType { + return n_list +} + +func (l *listNode) parse(p *parser) error { + if p.peek().t == t_list_end { + p.next() + return nil + } + + if n, err := p.parseValue(); err != nil { + return err + } else { + *l = append(*l, n) + } + + switch t := p.peek(); t.t { + case t_list_end: + p.next() + return nil + default: + return l.parse(p) + } +} + +func (l *listNode) pretty(w io.Writer, prefix string) error { + fmt.Fprintf(w, "%slist{\n", prefix) + for _, n := range *l { + if err := n.pretty(w, prefix+indent); err != nil { + return err + } + } + fmt.Fprintf(w, "%s}\n", prefix) + return nil +} + +func (l *listNode) eval(ctx map[string]interface{}) (interface{}, error) { + out := make([]interface{}, 0, len(*l)) + for _, n := range *l { + v, err := n.eval(ctx) + if err != nil { + return nil, err + } + out = append(out, v) + } + return out, nil +} + type list []interface{} type object map[string]interface{} diff --git a/parse.go b/parse.go index 3a1da86..6c87d3a 100644 --- a/parse.go +++ b/parse.go @@ -92,7 +92,13 @@ func (p *parser) parseValue() (node, error) { return nil, err } return n, nil - // case t_list_start: + case t_list_start: + p.next() + n := new(listNode) + if err := n.parse(p); err != nil { + return nil, err + } + return n, nil // return p.parseList(make(list, 0, 4)) // case t_object_start: // return p.parseObject(make(object)) @@ -102,27 +108,6 @@ func (p *parser) parseValue() (node, error) { } } -func (p *parser) parseList(l list) (list, error) { - if p.peek().t == t_list_end { - p.next() - return l, nil - } - - if v, err := p.parseValue(); err != nil { - return nil, err - } else { - l = append(l, v) - } - - switch t := p.peek(); t.t { - case t_list_end: - p.next() - return l, nil - default: - return p.parseList(l) - } -} - func (p *parser) parseObject(obj object) (object, error) { if p.peek().t == t_object_end { p.next() diff --git a/tests/parse/03.in b/tests/parse/03.in new file mode 100644 index 0000000..8d450f7 --- /dev/null +++ b/tests/parse/03.in @@ -0,0 +1 @@ +items: [1 2 3] diff --git a/tests/parse/03.out b/tests/parse/03.out new file mode 100644 index 0000000..4534506 --- /dev/null +++ b/tests/parse/03.out @@ -0,0 +1,10 @@ +root{ + assign{ + name: items + value: list{ + value: 1 + value: 2 + value: 3 + value: } + } +}