github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/flosch/pongo2.v3/parser_expression.go (about) 1 package pongo2 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 ) 8 9 type Expression struct { 10 // TODO: Add location token? 11 expr1 IEvaluator 12 expr2 IEvaluator 13 op_token *Token 14 } 15 16 type relationalExpression struct { 17 // TODO: Add location token? 18 expr1 IEvaluator 19 expr2 IEvaluator 20 op_token *Token 21 } 22 23 type simpleExpression struct { 24 negate bool 25 negative_sign bool 26 term1 IEvaluator 27 term2 IEvaluator 28 op_token *Token 29 } 30 31 type term struct { 32 // TODO: Add location token? 33 factor1 IEvaluator 34 factor2 IEvaluator 35 op_token *Token 36 } 37 38 type power struct { 39 // TODO: Add location token? 40 power1 IEvaluator 41 power2 IEvaluator 42 } 43 44 func (expr *Expression) FilterApplied(name string) bool { 45 return expr.expr1.FilterApplied(name) && (expr.expr2 == nil || 46 (expr.expr2 != nil && expr.expr2.FilterApplied(name))) 47 } 48 49 func (expr *relationalExpression) FilterApplied(name string) bool { 50 return expr.expr1.FilterApplied(name) && (expr.expr2 == nil || 51 (expr.expr2 != nil && expr.expr2.FilterApplied(name))) 52 } 53 54 func (expr *simpleExpression) FilterApplied(name string) bool { 55 return expr.term1.FilterApplied(name) && (expr.term2 == nil || 56 (expr.term2 != nil && expr.term2.FilterApplied(name))) 57 } 58 59 func (t *term) FilterApplied(name string) bool { 60 return t.factor1.FilterApplied(name) && (t.factor2 == nil || 61 (t.factor2 != nil && t.factor2.FilterApplied(name))) 62 } 63 64 func (p *power) FilterApplied(name string) bool { 65 return p.power1.FilterApplied(name) && (p.power2 == nil || 66 (p.power2 != nil && p.power2.FilterApplied(name))) 67 } 68 69 func (expr *Expression) GetPositionToken() *Token { 70 return expr.expr1.GetPositionToken() 71 } 72 73 func (expr *relationalExpression) GetPositionToken() *Token { 74 return expr.expr1.GetPositionToken() 75 } 76 77 func (expr *simpleExpression) GetPositionToken() *Token { 78 return expr.term1.GetPositionToken() 79 } 80 81 func (expr *term) GetPositionToken() *Token { 82 return expr.factor1.GetPositionToken() 83 } 84 85 func (expr *power) GetPositionToken() *Token { 86 return expr.power1.GetPositionToken() 87 } 88 89 func (expr *Expression) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error { 90 value, err := expr.Evaluate(ctx) 91 if err != nil { 92 return err 93 } 94 buffer.WriteString(value.String()) 95 return nil 96 } 97 98 func (expr *relationalExpression) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error { 99 value, err := expr.Evaluate(ctx) 100 if err != nil { 101 return err 102 } 103 buffer.WriteString(value.String()) 104 return nil 105 } 106 107 func (expr *simpleExpression) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error { 108 value, err := expr.Evaluate(ctx) 109 if err != nil { 110 return err 111 } 112 buffer.WriteString(value.String()) 113 return nil 114 } 115 116 func (expr *term) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error { 117 value, err := expr.Evaluate(ctx) 118 if err != nil { 119 return err 120 } 121 buffer.WriteString(value.String()) 122 return nil 123 } 124 125 func (expr *power) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error { 126 value, err := expr.Evaluate(ctx) 127 if err != nil { 128 return err 129 } 130 buffer.WriteString(value.String()) 131 return nil 132 } 133 134 func (expr *Expression) Evaluate(ctx *ExecutionContext) (*Value, *Error) { 135 v1, err := expr.expr1.Evaluate(ctx) 136 if err != nil { 137 return nil, err 138 } 139 if expr.expr2 != nil { 140 v2, err := expr.expr2.Evaluate(ctx) 141 if err != nil { 142 return nil, err 143 } 144 switch expr.op_token.Val { 145 case "and", "&&": 146 return AsValue(v1.IsTrue() && v2.IsTrue()), nil 147 case "or", "||": 148 return AsValue(v1.IsTrue() || v2.IsTrue()), nil 149 default: 150 panic(fmt.Sprintf("unimplemented: %s", expr.op_token.Val)) 151 } 152 } else { 153 return v1, nil 154 } 155 } 156 157 func (expr *relationalExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) { 158 v1, err := expr.expr1.Evaluate(ctx) 159 if err != nil { 160 return nil, err 161 } 162 if expr.expr2 != nil { 163 v2, err := expr.expr2.Evaluate(ctx) 164 if err != nil { 165 return nil, err 166 } 167 switch expr.op_token.Val { 168 case "<=": 169 if v1.IsFloat() || v2.IsFloat() { 170 return AsValue(v1.Float() <= v2.Float()), nil 171 } else { 172 return AsValue(v1.Integer() <= v2.Integer()), nil 173 } 174 case ">=": 175 if v1.IsFloat() || v2.IsFloat() { 176 return AsValue(v1.Float() >= v2.Float()), nil 177 } else { 178 return AsValue(v1.Integer() >= v2.Integer()), nil 179 } 180 case "==": 181 return AsValue(v1.EqualValueTo(v2)), nil 182 case ">": 183 if v1.IsFloat() || v2.IsFloat() { 184 return AsValue(v1.Float() > v2.Float()), nil 185 } else { 186 return AsValue(v1.Integer() > v2.Integer()), nil 187 } 188 case "<": 189 if v1.IsFloat() || v2.IsFloat() { 190 return AsValue(v1.Float() < v2.Float()), nil 191 } else { 192 return AsValue(v1.Integer() < v2.Integer()), nil 193 } 194 case "!=", "<>": 195 return AsValue(!v1.EqualValueTo(v2)), nil 196 case "in": 197 return AsValue(v2.Contains(v1)), nil 198 default: 199 panic(fmt.Sprintf("unimplemented: %s", expr.op_token.Val)) 200 } 201 } else { 202 return v1, nil 203 } 204 } 205 206 func (expr *simpleExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) { 207 t1, err := expr.term1.Evaluate(ctx) 208 if err != nil { 209 return nil, err 210 } 211 result := t1 212 213 if expr.negate { 214 result = result.Negate() 215 } 216 217 if expr.negative_sign { 218 if result.IsNumber() { 219 switch { 220 case result.IsFloat(): 221 result = AsValue(-1 * result.Float()) 222 case result.IsInteger(): 223 result = AsValue(-1 * result.Integer()) 224 default: 225 panic("not possible") 226 } 227 } else { 228 return nil, ctx.Error("Negative sign on a non-number expression", expr.GetPositionToken()) 229 } 230 } 231 232 if expr.term2 != nil { 233 t2, err := expr.term2.Evaluate(ctx) 234 if err != nil { 235 return nil, err 236 } 237 switch expr.op_token.Val { 238 case "+": 239 if result.IsFloat() || t2.IsFloat() { 240 // Result will be a float 241 return AsValue(result.Float() + t2.Float()), nil 242 } else { 243 // Result will be an integer 244 return AsValue(result.Integer() + t2.Integer()), nil 245 } 246 case "-": 247 if result.IsFloat() || t2.IsFloat() { 248 // Result will be a float 249 return AsValue(result.Float() - t2.Float()), nil 250 } else { 251 // Result will be an integer 252 return AsValue(result.Integer() - t2.Integer()), nil 253 } 254 default: 255 panic("unimplemented") 256 } 257 } 258 259 return result, nil 260 } 261 262 func (t *term) Evaluate(ctx *ExecutionContext) (*Value, *Error) { 263 f1, err := t.factor1.Evaluate(ctx) 264 if err != nil { 265 return nil, err 266 } 267 if t.factor2 != nil { 268 f2, err := t.factor2.Evaluate(ctx) 269 if err != nil { 270 return nil, err 271 } 272 switch t.op_token.Val { 273 case "*": 274 if f1.IsFloat() || f2.IsFloat() { 275 // Result will be float 276 return AsValue(f1.Float() * f2.Float()), nil 277 } 278 // Result will be int 279 return AsValue(f1.Integer() * f2.Integer()), nil 280 case "/": 281 if f1.IsFloat() || f2.IsFloat() { 282 // Result will be float 283 return AsValue(f1.Float() / f2.Float()), nil 284 } 285 // Result will be int 286 return AsValue(f1.Integer() / f2.Integer()), nil 287 case "%": 288 // Result will be int 289 return AsValue(f1.Integer() % f2.Integer()), nil 290 default: 291 panic("unimplemented") 292 } 293 } else { 294 return f1, nil 295 } 296 } 297 298 func (pw *power) Evaluate(ctx *ExecutionContext) (*Value, *Error) { 299 p1, err := pw.power1.Evaluate(ctx) 300 if err != nil { 301 return nil, err 302 } 303 if pw.power2 != nil { 304 p2, err := pw.power2.Evaluate(ctx) 305 if err != nil { 306 return nil, err 307 } 308 return AsValue(math.Pow(p1.Float(), p2.Float())), nil 309 } else { 310 return p1, nil 311 } 312 } 313 314 func (p *Parser) parseFactor() (IEvaluator, *Error) { 315 if p.Match(TokenSymbol, "(") != nil { 316 expr, err := p.ParseExpression() 317 if err != nil { 318 return nil, err 319 } 320 if p.Match(TokenSymbol, ")") == nil { 321 return nil, p.Error("Closing bracket expected after expression", nil) 322 } 323 return expr, nil 324 } 325 326 return p.parseVariableOrLiteralWithFilter() 327 } 328 329 func (p *Parser) parsePower() (IEvaluator, *Error) { 330 pw := new(power) 331 332 power1, err := p.parseFactor() 333 if err != nil { 334 return nil, err 335 } 336 pw.power1 = power1 337 338 if p.Match(TokenSymbol, "^") != nil { 339 power2, err := p.parsePower() 340 if err != nil { 341 return nil, err 342 } 343 pw.power2 = power2 344 } 345 346 if pw.power2 == nil { 347 // Shortcut for faster evaluation 348 return pw.power1, nil 349 } 350 351 return pw, nil 352 } 353 354 func (p *Parser) parseTerm() (IEvaluator, *Error) { 355 return_term := new(term) 356 357 factor1, err := p.parsePower() 358 if err != nil { 359 return nil, err 360 } 361 return_term.factor1 = factor1 362 363 for p.PeekOne(TokenSymbol, "*", "/", "%") != nil { 364 if return_term.op_token != nil { 365 // Create new sub-term 366 return_term = &term{ 367 factor1: return_term, 368 } 369 } 370 371 op := p.Current() 372 p.Consume() 373 374 factor2, err := p.parsePower() 375 if err != nil { 376 return nil, err 377 } 378 379 return_term.op_token = op 380 return_term.factor2 = factor2 381 } 382 383 if return_term.op_token == nil { 384 // Shortcut for faster evaluation 385 return return_term.factor1, nil 386 } 387 388 return return_term, nil 389 } 390 391 func (p *Parser) parseSimpleExpression() (IEvaluator, *Error) { 392 expr := new(simpleExpression) 393 394 if sign := p.MatchOne(TokenSymbol, "+", "-"); sign != nil { 395 if sign.Val == "-" { 396 expr.negative_sign = true 397 } 398 } 399 400 if p.Match(TokenSymbol, "!") != nil || p.Match(TokenKeyword, "not") != nil { 401 expr.negate = true 402 } 403 404 term1, err := p.parseTerm() 405 if err != nil { 406 return nil, err 407 } 408 expr.term1 = term1 409 410 for p.PeekOne(TokenSymbol, "+", "-") != nil { 411 if expr.op_token != nil { 412 // New sub expr 413 expr = &simpleExpression{ 414 term1: expr, 415 } 416 } 417 418 op := p.Current() 419 p.Consume() 420 421 term2, err := p.parseTerm() 422 if err != nil { 423 return nil, err 424 } 425 426 expr.term2 = term2 427 expr.op_token = op 428 } 429 430 if expr.negate == false && expr.negative_sign == false && expr.term2 == nil { 431 // Shortcut for faster evaluation 432 return expr.term1, nil 433 } 434 435 return expr, nil 436 } 437 438 func (p *Parser) parseRelationalExpression() (IEvaluator, *Error) { 439 expr1, err := p.parseSimpleExpression() 440 if err != nil { 441 return nil, err 442 } 443 444 expr := &relationalExpression{ 445 expr1: expr1, 446 } 447 448 if t := p.MatchOne(TokenSymbol, "==", "<=", ">=", "!=", "<>", ">", "<"); t != nil { 449 expr2, err := p.parseRelationalExpression() 450 if err != nil { 451 return nil, err 452 } 453 expr.op_token = t 454 expr.expr2 = expr2 455 } else if t := p.MatchOne(TokenKeyword, "in"); t != nil { 456 expr2, err := p.parseSimpleExpression() 457 if err != nil { 458 return nil, err 459 } 460 expr.op_token = t 461 expr.expr2 = expr2 462 } 463 464 if expr.expr2 == nil { 465 // Shortcut for faster evaluation 466 return expr.expr1, nil 467 } 468 469 return expr, nil 470 } 471 472 func (p *Parser) ParseExpression() (IEvaluator, *Error) { 473 rexpr1, err := p.parseRelationalExpression() 474 if err != nil { 475 return nil, err 476 } 477 478 exp := &Expression{ 479 expr1: rexpr1, 480 } 481 482 if p.PeekOne(TokenSymbol, "&&", "||") != nil || p.PeekOne(TokenKeyword, "and", "or") != nil { 483 op := p.Current() 484 p.Consume() 485 expr2, err := p.ParseExpression() 486 if err != nil { 487 return nil, err 488 } 489 exp.expr2 = expr2 490 exp.op_token = op 491 } 492 493 if exp.expr2 == nil { 494 // Shortcut for faster evaluation 495 return exp.expr1, nil 496 } 497 498 return exp, nil 499 }