...

Source file src/github.com/noirbizarre/gonja/parser/logic.go

Documentation: github.com/noirbizarre/gonja/parser

     1  package parser
     2  
     3  import (
     4  	"github.com/noirbizarre/gonja/nodes"
     5  	"github.com/noirbizarre/gonja/tokens"
     6  	log "github.com/sirupsen/logrus"
     7  )
     8  
     9  var compareOps = []tokens.Type{
    10  	tokens.Eq, tokens.Ne,
    11  	tokens.Gt, tokens.Gteq,
    12  	tokens.Lt, tokens.Lteq,
    13  	// "in", "not in") != nil || p.PeekOne(TokenSymbol, "==", "<=", ">=", "!=", "<>", ">", "<"
    14  }
    15  
    16  func BinOp(token *tokens.Token) *nodes.BinOperator {
    17  	return &nodes.BinOperator{token}
    18  }
    19  
    20  // type negation struct {
    21  // 	term     Expression
    22  // 	operator *Token
    23  // }
    24  
    25  // func (expr *negation) String() string {
    26  // 	t := expr.GetPositionToken()
    27  
    28  // 	return fmt.Sprintf("<Negation term=%s Line=%d Col=%d>", expr.term, t.Line, t.Col)
    29  // }
    30  
    31  // func (expr *negation) FilterApplied(name string) bool {
    32  // 	return expr.term.FilterApplied(name)
    33  // }
    34  
    35  // func (expr *negation) GetPositionToken() *Token {
    36  // 	return expr.operator
    37  // }
    38  
    39  // func (expr *negation) Evaluate(ctx *ExecutionContext) (*Value, error) {
    40  // 	result, err := expr.term.Evaluate(ctx)
    41  // 	if err != nil {
    42  // 		return nil, err
    43  // 	}
    44  
    45  // 	return result.Negate(), nil
    46  // }
    47  
    48  func (p *Parser) ParseLogicalExpression() (nodes.Expression, error) {
    49  	log.WithFields(log.Fields{
    50  		"current": p.Current(),
    51  	}).Trace("ParseLogicalExpression")
    52  	return p.parseOr()
    53  }
    54  
    55  func (p *Parser) parseOr() (nodes.Expression, error) {
    56  	log.WithFields(log.Fields{
    57  		"current": p.Current(),
    58  	}).Trace("parseOr")
    59  
    60  	var expr nodes.Expression
    61  
    62  	expr, err := p.parseAnd()
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	for p.PeekName("or") != nil {
    68  		op := BinOp(p.Pop())
    69  		right, err := p.parseAnd()
    70  		if err != nil {
    71  			return nil, err
    72  		}
    73  		expr = &nodes.BinaryExpression{
    74  			Left:     expr,
    75  			Right:    right,
    76  			Operator: op,
    77  		}
    78  	}
    79  
    80  	log.WithFields(log.Fields{
    81  		"expr": expr,
    82  	}).Trace("parseOr return")
    83  	return expr, nil
    84  }
    85  
    86  func (p *Parser) parseAnd() (nodes.Expression, error) {
    87  	log.WithFields(log.Fields{
    88  		"current": p.Current(),
    89  	}).Trace("parseAnd")
    90  
    91  	var expr nodes.Expression
    92  
    93  	expr, err := p.parseNot()
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	for p.PeekName("and") != nil {
    99  		op := BinOp(p.Pop())
   100  		// binExpr :=
   101  
   102  		right, err := p.parseNot()
   103  		if err != nil {
   104  			return nil, err
   105  		}
   106  		// binExpr.right = right
   107  		expr = &nodes.BinaryExpression{
   108  			Left:     expr,
   109  			Right:    right,
   110  			Operator: op,
   111  		}
   112  	}
   113  
   114  	log.WithFields(log.Fields{
   115  		"expr": expr,
   116  	}).Trace("parseAnd return")
   117  	return expr, nil
   118  }
   119  
   120  func (p *Parser) parseNot() (nodes.Expression, error) {
   121  	log.WithFields(log.Fields{
   122  		"current": p.Current(),
   123  	}).Trace("parseNot")
   124  
   125  	op := p.MatchName("not")
   126  	expr, err := p.parseCompare()
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	if op != nil {
   132  		expr = &nodes.Negation{
   133  			Operator: op,
   134  			Term:     expr,
   135  		}
   136  	}
   137  
   138  	log.WithFields(log.Fields{
   139  		"expr": expr,
   140  	}).Trace("parseNot return")
   141  	return expr, nil
   142  }
   143  
   144  func (p *Parser) parseCompare() (nodes.Expression, error) {
   145  	log.WithFields(log.Fields{
   146  		"current": p.Current(),
   147  	}).Trace("parseCompare")
   148  
   149  	var expr nodes.Expression
   150  
   151  	expr, err := p.ParseMath()
   152  	if err != nil {
   153  		return nil, err
   154  	}
   155  
   156  	// for p.PeekOne(TokenKeyword, "in", "not in") != nil || p.PeekOne(TokenSymbol, "==", "<=", ">=", "!=", "<>", ">", "<") != nil {
   157  	for p.Peek(compareOps...) != nil || p.PeekName("in", "not") != nil {
   158  
   159  		op := p.Pop()
   160  		// if op = p.MatchOne(TokenKeyword, "in", "not in"); op == nil {
   161  		// 	if op = p.MatchOne(TokenSymbol, "==", "<=", ">=", "!=", "<>", ">", "<"); op == nil {
   162  		// 		return nil, p.Error("Unexpected operator %s", p.Current())
   163  		// 	}
   164  		// }
   165  
   166  		right, err := p.ParseMath()
   167  		if err != nil {
   168  			return nil, err
   169  		}
   170  
   171  		if right != nil {
   172  			expr = &nodes.BinaryExpression{
   173  				Left:     expr,
   174  				Operator: BinOp(op),
   175  				Right:    right,
   176  			}
   177  		}
   178  	}
   179  
   180  	expr, err = p.ParseTest(expr)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	log.WithFields(log.Fields{
   186  		"expr": expr,
   187  	}).Trace("parseCompare return")
   188  	return expr, nil
   189  }
   190  

View as plain text