...
1 package statements
2
3 import (
4 "fmt"
5
6 "github.com/pkg/errors"
7
8 "github.com/noirbizarre/gonja/exec"
9 "github.com/noirbizarre/gonja/nodes"
10 "github.com/noirbizarre/gonja/parser"
11 "github.com/noirbizarre/gonja/tokens"
12 )
13
14 type WithStmt struct {
15 Location *tokens.Token
16 Pairs map[string]nodes.Expression
17 Wrapper *nodes.Wrapper
18 }
19
20 func (stmt *WithStmt) Position() *tokens.Token { return stmt.Location }
21 func (stmt *WithStmt) String() string {
22 t := stmt.Position()
23 return fmt.Sprintf("WithStmt(Line=%d Col=%d)", t.Line, t.Col)
24 }
25
26 func (stmt *WithStmt) Execute(r *exec.Renderer, tag *nodes.StatementBlock) error {
27 sub := r.Inherit()
28
29 for key, value := range stmt.Pairs {
30 val := r.Eval(value)
31 if val.IsError() {
32 return errors.Wrapf(val, `unable to evaluate parameter %s`, value)
33 }
34 sub.Ctx.Set(key, val)
35 }
36
37 return sub.ExecuteWrapper(stmt.Wrapper)
38 }
39
40 func withParser(p *parser.Parser, args *parser.Parser) (nodes.Statement, error) {
41 stmt := &WithStmt{
42 Location: p.Current(),
43 Pairs: map[string]nodes.Expression{},
44 }
45
46 wrapper, endargs, err := p.WrapUntil("endwith")
47 if err != nil {
48 return nil, err
49 }
50 stmt.Wrapper = wrapper
51
52 if !endargs.End() {
53 return nil, endargs.Error("Arguments not allowed here.", nil)
54 }
55
56 for !args.End() {
57 key := args.Match(tokens.Name)
58 if key == nil {
59 return nil, args.Error("Expected an identifier", args.Current())
60 }
61 if args.Match(tokens.Assign) == nil {
62 return nil, args.Error("Expected '='.", args.Current())
63 }
64 value, err := args.ParseExpression()
65 if err != nil {
66 return nil, err
67 }
68 stmt.Pairs[key.Val] = value
69
70 if args.Match(tokens.Comma) == nil {
71 break
72 }
73 }
74
75 if !args.End() {
76 return nil, errors.New("")
77 }
78
79 return stmt, nil
80 }
81
82 func init() {
83 All.Register("with", withParser)
84 }
85
View as plain text