object nodes parse now

master
Jordan Orelli 10 years ago
parent 2dc6b618f0
commit 5313fe431c

@ -5,6 +5,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"sort"
"strconv" "strconv"
"strings" "strings"
) )
@ -19,6 +20,7 @@ const (
n_string n_string
n_number n_number
n_list n_list
n_object
) )
var indent = " " var indent = " "
@ -341,5 +343,66 @@ func (l *listNode) eval(ctx map[string]interface{}) (interface{}, error) {
return out, nil return out, nil
} }
type list []interface{} type objectNode map[string]node
type object map[string]interface{}
func (o *objectNode) Type() nodeType {
return n_object
}
func (o *objectNode) parse(p *parser) error {
if p.peek().t == t_object_end {
p.next()
return nil
}
if err := p.ensureNext(t_name, "looking for object field name in parseObject"); err != nil {
return err
}
field_name := p.next().s
if err := p.ensureNext(t_object_separator, "looking for object separator in parseObject"); err != nil {
return err
}
p.next()
if n, err := p.parseValue(); err != nil {
return err
} else {
(*o)[field_name] = n
}
switch t := p.peek(); t.t {
case t_object_end:
p.next()
return nil
default:
return o.parse(p)
}
}
func (o *objectNode) pretty(w io.Writer, prefix string) error {
fmt.Fprintf(w, "%sobject:\n", prefix)
keys := make([]string, 0, len(*o))
for key := range *o {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
fmt.Fprintf(w, "%s%s:\n", prefix+indent, key)
err := (*o)[key].pretty(w, prefix+indent+indent)
if err != nil {
return err
}
}
return nil
}
func (o *objectNode) eval(ctx map[string]interface{}) (interface{}, error) {
out := make(map[string]interface{}, len(*o))
for name, node := range *o {
v, err := node.eval(ctx)
if err != nil {
return nil, err
}
out[name] = v
}
return out, nil
}

@ -99,40 +99,15 @@ func (p *parser) parseValue() (node, error) {
return nil, err return nil, err
} }
return n, nil return n, nil
// return p.parseList(make(list, 0, 4)) case t_object_start:
// case t_object_start:
// return p.parseObject(make(object))
default:
return nil, fmt.Errorf("parse error: unexpected %v token while looking for value", t.t)
}
}
}
func (p *parser) parseObject(obj object) (object, error) {
if p.peek().t == t_object_end {
p.next() p.next()
return obj, nil n := &objectNode{}
} if err := n.parse(p); err != nil {
if err := p.ensureNext(t_name, "looking for object field name in parseObject"); err != nil {
return nil, err
}
field_name := p.next().s
if err := p.ensureNext(t_object_separator, "looking for object separator in parseObject"); err != nil {
return nil, err
}
p.next()
if v, err := p.parseValue(); err != nil {
return nil, err return nil, err
} else {
obj[field_name] = v
} }
return n, nil
switch t := p.peek(); t.t {
case t_object_end:
p.next()
return obj, nil
default: default:
return p.parseObject(obj) return nil, fmt.Errorf("parse error: unexpected %v token while looking for value", t.t)
}
} }
} }

@ -0,0 +1,10 @@
an_object: {
item_one: 1
item_two: "two"
item_three: [1 2 3]
item_four: {
item_one: "one"
item_two: 2
item_three: ["one" "two" "three"]
}
}

@ -0,0 +1,36 @@
root:
assign:
name:
an_object
value:
object:
item_four:
object:
item_one:
string:
one
item_three:
list:
string:
one
string:
two
string:
three
item_two:
number:
2
item_one:
number:
1
item_three:
list:
number:
1
number:
2
number:
3
item_two:
string:
two
Loading…
Cancel
Save