...

Source file src/github.com/noirbizarre/gonja/builtins/statements/set.go

Documentation: github.com/noirbizarre/gonja/builtins/statements

     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  	// Evaluate expression
    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  	// Parse variable name
    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  	// Variable expression
    80  	expr, err := args.ParseExpression()
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	stmt.Expression = expr
    85  
    86  	// Remaining arguments
    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