diff --git a/ex.moon b/ex.moon index 5546e91..5276ea4 100644 --- a/ex.moon +++ b/ex.moon @@ -32,6 +32,5 @@ other_hash: { item_one: "this is item one" -# we should be able to reference variables defined earlier -# (this doesn't work yet) -# item_two: item_one +# we may reference an item that was defined earlier +item_two: item_one diff --git a/node.go b/node.go index d40836b..6af0059 100644 --- a/node.go +++ b/node.go @@ -21,6 +21,7 @@ const ( n_number n_list n_object + n_variable ) var indent = " " @@ -410,3 +411,32 @@ func (o *objectNode) eval(ctx map[string]interface{}) (interface{}, error) { } return out, nil } + +type variableNode string + +func (v *variableNode) Type() nodeType { + return n_variable +} + +func (v *variableNode) parse(p *parser) error { + t := p.next() + if t.t != t_name { + return fmt.Errorf("unexpected %s token when parsing variable", t.t) + } + *v = variableNode(t.s) + return nil +} + +func (v *variableNode) pretty(w io.Writer, prefix string) error { + fmt.Fprintf(w, "%svariable:\n", prefix) + fmt.Fprintf(w, "%s%s\n", prefix+indent, string(*v)) + return nil +} + +func (v *variableNode) eval(ctx map[string]interface{}) (interface{}, error) { + value, ok := ctx[string(*v)] + if !ok { + return nil, fmt.Errorf("undefined variable: %s", *v) + } + return value, nil +} diff --git a/parse.go b/parse.go index 5325a60..e2b6cb5 100644 --- a/parse.go +++ b/parse.go @@ -106,6 +106,12 @@ func (p *parser) parseValue() (node, error) { return nil, err } return n, nil + case t_name: + n := new(variableNode) + if err := n.parse(p); err != nil { + return nil, err + } + return n, nil default: return nil, fmt.Errorf("parse error: unexpected %v token while looking for value", t.t) } diff --git a/tests/parse/05.in b/tests/parse/05.in new file mode 100644 index 0000000..9ceaf27 --- /dev/null +++ b/tests/parse/05.in @@ -0,0 +1,2 @@ +an_item: "this is the value of the item" +a_variable: an_item diff --git a/tests/parse/05.out b/tests/parse/05.out new file mode 100644 index 0000000..46fdeef --- /dev/null +++ b/tests/parse/05.out @@ -0,0 +1,13 @@ +root: + assign: + name: + an_item + value: + string: + this is the value of the item + assign: + name: + a_variable + value: + variable: + an_item