parser_expression.go 11 KB

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