rt_arithmetic.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package interpreter
  11. import (
  12. "math"
  13. "devt.de/krotik/ecal/parser"
  14. )
  15. // Basic Arithmetic Operator Runtimes
  16. // ==================================
  17. type plusOpRuntime struct {
  18. *operatorRuntime
  19. }
  20. /*
  21. plusOpRuntimeInst returns a new runtime component instance.
  22. */
  23. func plusOpRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parser.Runtime {
  24. return &plusOpRuntime{&operatorRuntime{newBaseRuntime(erp, node)}}
  25. }
  26. /*
  27. Eval evaluate this runtime component.
  28. */
  29. func (rt *plusOpRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint64) (interface{}, error) {
  30. var res interface{}
  31. _, err := rt.baseRuntime.Eval(vs, is, tid)
  32. if err == nil {
  33. // Use as prefix
  34. if len(rt.node.Children) == 1 {
  35. return rt.numVal(func(n float64) interface{} {
  36. return n
  37. }, vs, is, tid)
  38. }
  39. // Use as operation
  40. res, err = rt.numOp(func(n1 float64, n2 float64) interface{} {
  41. return n1 + n2
  42. }, vs, is, tid)
  43. }
  44. return res, err
  45. }
  46. type minusOpRuntime struct {
  47. *operatorRuntime
  48. }
  49. /*
  50. minusOpRuntimeInst returns a new runtime component instance.
  51. */
  52. func minusOpRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parser.Runtime {
  53. return &minusOpRuntime{&operatorRuntime{newBaseRuntime(erp, node)}}
  54. }
  55. /*
  56. Eval evaluate this runtime component.
  57. */
  58. func (rt *minusOpRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint64) (interface{}, error) {
  59. var res interface{}
  60. _, err := rt.baseRuntime.Eval(vs, is, tid)
  61. if err == nil {
  62. // Use as prefix
  63. if len(rt.node.Children) == 1 {
  64. return rt.numVal(func(n float64) interface{} {
  65. return -n
  66. }, vs, is, tid)
  67. }
  68. // Use as operation
  69. res, err = rt.numOp(func(n1 float64, n2 float64) interface{} {
  70. return n1 - n2
  71. }, vs, is, tid)
  72. }
  73. return res, err
  74. }
  75. type timesOpRuntime struct {
  76. *operatorRuntime
  77. }
  78. /*
  79. timesOpRuntimeInst returns a new runtime component instance.
  80. */
  81. func timesOpRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parser.Runtime {
  82. return &timesOpRuntime{&operatorRuntime{newBaseRuntime(erp, node)}}
  83. }
  84. /*
  85. Eval evaluate this runtime component.
  86. */
  87. func (rt *timesOpRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint64) (interface{}, error) {
  88. var res interface{}
  89. _, err := rt.baseRuntime.Eval(vs, is, tid)
  90. if err == nil {
  91. res, err = rt.numOp(func(n1 float64, n2 float64) interface{} {
  92. return n1 * n2
  93. }, vs, is, tid)
  94. }
  95. return res, err
  96. }
  97. type divOpRuntime struct {
  98. *operatorRuntime
  99. }
  100. /*
  101. divOpRuntimeInst returns a new runtime component instance.
  102. */
  103. func divOpRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parser.Runtime {
  104. return &divOpRuntime{&operatorRuntime{newBaseRuntime(erp, node)}}
  105. }
  106. /*
  107. Eval evaluate this runtime component.
  108. */
  109. func (rt *divOpRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint64) (interface{}, error) {
  110. var res interface{}
  111. _, err := rt.baseRuntime.Eval(vs, is, tid)
  112. if err == nil {
  113. res, err = rt.numOp(func(n1 float64, n2 float64) interface{} {
  114. return n1 / n2
  115. }, vs, is, tid)
  116. }
  117. return res, err
  118. }
  119. type divintOpRuntime struct {
  120. *operatorRuntime
  121. }
  122. /*
  123. divintOpRuntimeInst returns a new runtime component instance.
  124. */
  125. func divintOpRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parser.Runtime {
  126. return &divintOpRuntime{&operatorRuntime{newBaseRuntime(erp, node)}}
  127. }
  128. /*
  129. Eval evaluate this runtime component.
  130. */
  131. func (rt *divintOpRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint64) (interface{}, error) {
  132. var res interface{}
  133. _, err := rt.baseRuntime.Eval(vs, is, tid)
  134. if err == nil {
  135. res, err = rt.numOp(func(n1 float64, n2 float64) interface{} {
  136. return math.Floor(n1 / n2)
  137. }, vs, is, tid)
  138. }
  139. return res, err
  140. }
  141. type modintOpRuntime struct {
  142. *operatorRuntime
  143. }
  144. /*
  145. divOpRuntimeInst returns a new runtime component instance.
  146. */
  147. func modintOpRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parser.Runtime {
  148. return &modintOpRuntime{&operatorRuntime{newBaseRuntime(erp, node)}}
  149. }
  150. /*
  151. Eval evaluate this runtime component.
  152. */
  153. func (rt *modintOpRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint64) (interface{}, error) {
  154. var res interface{}
  155. _, err := rt.baseRuntime.Eval(vs, is, tid)
  156. if err == nil {
  157. res, err = rt.numOp(func(n1 float64, n2 float64) interface{} {
  158. return float64(int64(n1) % int64(n2))
  159. }, vs, is, tid)
  160. }
  161. return res, err
  162. }