...
1 package statements
2
3 import (
4 "fmt"
5
6 "github.com/noirbizarre/gonja/exec"
7 "github.com/noirbizarre/gonja/nodes"
8 "github.com/noirbizarre/gonja/parser"
9 "github.com/noirbizarre/gonja/tokens"
10 "github.com/pkg/errors"
11 )
12
13 type SetStmt struct {
14 Location *tokens.Token
15 Target nodes.Expression
16 Expression nodes.Expression
17 }
18
19 func (stmt *SetStmt) Position() *tokens.Token { return stmt.Location }
20 func (stmt *SetStmt) String() string {
21 t := stmt.Position()
22 return fmt.Sprintf("SetStmt(Line=%d Col=%d)", t.Line, t.Col)
23 }
24
25 func (stmt *SetStmt) Execute(r *exec.Renderer, tag *nodes.StatementBlock) error {
26
27 value := r.Eval(stmt.Expression)
28 if value.IsError() {
29 return value
30 }
31
32 switch n := stmt.Target.(type) {
33 case *nodes.Name:
34 r.Ctx.Set(n.Name.Val, value.Interface())
35 case *nodes.Getattr:
36 target := r.Eval(n.Node)
37 if target.IsError() {
38 return errors.Wrapf(target, `Unable to evaluate target %s`, n)
39 }
40 if err := target.Set(n.Attr, value.Interface()); err != nil {
41 return errors.Wrapf(err, `Unable to set value on "%s"`, n.Attr)
42 }
43 case *nodes.Getitem:
44 target := r.Eval(n.Node)
45 if target.IsError() {
46 return errors.Wrapf(target, `Unable to evaluate target %s`, n)
47 }
48 if err := target.Set(n.Arg, value.Interface()); err != nil {
49 return errors.Wrapf(err, `Unable to set value on "%s"`, n.Arg)
50 }
51 default:
52 return errors.Errorf(`Illegal set target node %s`, n)
53 }
54
55 return nil
56 }
57
58 func setParser(p *parser.Parser, args *parser.Parser) (nodes.Statement, error) {
59 stmt := &SetStmt{
60 Location: p.Current(),
61 }
62
63
64 ident, err := args.ParseVariable()
65 if err != nil {
66 return nil, errors.Wrap(err, `Unable to parse identifier`)
67 }
68 switch n := ident.(type) {
69 case *nodes.Name, *nodes.Call, *nodes.Getitem, *nodes.Getattr:
70 stmt.Target = n
71 default:
72 return nil, errors.Errorf(`Unexpected set target %s`, n)
73 }
74
75 if args.Match(tokens.Assign) == nil {
76 return nil, args.Error("Expected '='.", args.Current())
77 }
78
79
80 expr, err := args.ParseExpression()
81 if err != nil {
82 return nil, err
83 }
84 stmt.Expression = expr
85
86
87 if !args.End() {
88 return nil, args.Error("Malformed 'set'-tag args.", args.Current())
89 }
90
91 return stmt, nil
92 }
93
94 func init() {
95 All.Register("set", setParser)
96 }
97
View as plain text