math.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import { StoreObject } from '../store/storeObject';
  2. import * as Commands from './../../ast/commands';
  3. import { Types } from './../../typeSystem/types';
  4. import { toReal } from "./../../typeSystem/parsers";
  5. import { Decimal } from 'decimal.js';
  6. import { MultiType } from '../../typeSystem/multiType';
  7. import { CompoundType } from '../../typeSystem/compoundType';
  8. import { Modes } from '../modes';
  9. /**
  10. * sin
  11. * cos
  12. * tan
  13. * sqrt
  14. * pow
  15. * log
  16. * abs
  17. * negate
  18. * invert
  19. * max
  20. * min
  21. */
  22. function convertToRadians (degrees) {
  23. return degrees.times(Decimal.acos(-1)).div(180);
  24. }
  25. export function createSinFun () {
  26. const sinFun = (sto, _) => {
  27. const x = sto.applyStore('x');
  28. const result = Decimal.sin(convertToRadians(x.value));
  29. const temp = new StoreObject(Types.REAL, result);
  30. sto.mode = Modes.RETURN;
  31. return Promise.resolve(sto.updateStore('$', temp));
  32. };
  33. const block = new Commands.CommandBlock([], [new Commands.SysCall(sinFun)]);
  34. const func = new Commands.Function('$sin', Types.REAL,
  35. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  36. block);
  37. return func;
  38. }
  39. export function createCosFun () {
  40. const cosFun = (sto, _) => {
  41. const x = sto.applyStore('x');
  42. const result = Decimal.cos(convertToRadians(x.value));
  43. const temp = new StoreObject(Types.REAL, result);
  44. sto.mode = Modes.RETURN;
  45. return Promise.resolve(sto.updateStore('$', temp));
  46. };
  47. const block = new Commands.CommandBlock([], [new Commands.SysCall(cosFun)]);
  48. const func = new Commands.Function('$cos', Types.REAL,
  49. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  50. block);
  51. return func;
  52. }
  53. export function createTanFun () {
  54. const tanFun = (sto, _) => {
  55. const x = sto.applyStore('x');
  56. const result = Decimal.tan(convertToRadians(x.value));
  57. const temp = new StoreObject(Types.REAL, result);
  58. sto.mode = Modes.RETURN;
  59. return Promise.resolve(sto.updateStore('$', temp));
  60. };
  61. const block = new Commands.CommandBlock([], [new Commands.SysCall(tanFun)]);
  62. const func = new Commands.Function('$tan', Types.REAL,
  63. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  64. block);
  65. return func;
  66. }
  67. export function createSqrtFun () {
  68. const sqrtFun = (sto, _) => {
  69. const x = sto.applyStore('x');
  70. const result = x.value.sqrt();
  71. const temp = new StoreObject(Types.REAL, result);
  72. sto.mode = Modes.RETURN;
  73. return Promise.resolve(sto.updateStore('$', temp));
  74. };
  75. const block = new Commands.CommandBlock([], [new Commands.SysCall(sqrtFun)]);
  76. const func = new Commands.Function('$sqrt', Types.REAL,
  77. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  78. block);
  79. return func;
  80. }
  81. export function createPowFun () {
  82. const powFun = (sto, _) => {
  83. const x = sto.applyStore('x');
  84. const y = sto.applyStore('y');
  85. const result = x.value.pow(y.value);
  86. const temp = new StoreObject(Types.REAL, result);
  87. sto.mode = Modes.RETURN;
  88. return Promise.resolve(sto.updateStore('$', temp));
  89. };
  90. const block = new Commands.CommandBlock([], [new Commands.SysCall(powFun)]);
  91. const func = new Commands.Function('$pow', Types.REAL,
  92. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false),
  93. new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'y', false)],
  94. block);
  95. return func;
  96. }
  97. export function createLogFun () {
  98. const logFun = (sto, _) => {
  99. const x = sto.applyStore('x');
  100. if (x.value.isNegative()) {
  101. return Promise.reject("the value passed to log function cannot be negative");
  102. }
  103. const result = Decimal.log10(x.value);
  104. const temp = new StoreObject(Types.REAL, result);
  105. sto.mode = Modes.RETURN;
  106. return Promise.resolve(sto.updateStore('$', temp));
  107. };
  108. const block = new Commands.CommandBlock([], [new Commands.SysCall(logFun)]);
  109. const func = new Commands.Function('$log', Types.REAL,
  110. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  111. block);
  112. return func;
  113. }
  114. export function createAbsFun () {
  115. const absFun = (sto, _) => {
  116. const x = sto.applyStore('x');
  117. const result = x.value.abs();
  118. const temp = new StoreObject(x.type, result);
  119. sto.mode = Modes.RETURN;
  120. return Promise.resolve(sto.updateStore('$', temp));
  121. };
  122. const block = new Commands.CommandBlock([], [new Commands.SysCall(absFun)]);
  123. const func = new Commands.Function('$abs', new MultiType([Types.INTEGER, Types.REAL]),
  124. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  125. block);
  126. return func;
  127. }
  128. export function createNegateFun () {
  129. const negateFun = (sto, _) => {
  130. const x = sto.applyStore('x');
  131. const result = x.value.negated();
  132. const temp = new StoreObject(x.type, result);
  133. sto.mode = Modes.RETURN;
  134. return Promise.resolve(sto.updateStore('$', temp));
  135. };
  136. const block = new Commands.CommandBlock([], [new Commands.SysCall(negateFun)]);
  137. const func = new Commands.Function('$negate', new MultiType([Types.INTEGER, Types.REAL]),
  138. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  139. block);
  140. return func;
  141. }
  142. export function createInvertFun () {
  143. const invertFun = (sto, _) => {
  144. const x = sto.applyStore('x');
  145. const result = toReal(1).dividedBy(x.value);
  146. const temp = new StoreObject(Types.REAL, result);
  147. sto.mode = Modes.RETURN;
  148. return Promise.resolve(sto.updateStore('$', temp));
  149. };
  150. const block = new Commands.CommandBlock([], [new Commands.SysCall(invertFun)]);
  151. const func = new Commands.Function('$invert', Types.REAL,
  152. [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
  153. block);
  154. return func;
  155. }
  156. export function createMaxFun () {
  157. const maxFun = (sto, _) => {
  158. const x = sto.applyStore('x');
  159. const numbers = x.value.map(stoObj => stoObj.value);
  160. const result = Decimal.max(...numbers);
  161. const temp = new StoreObject(x.type.innerType, result);
  162. sto.mode = Modes.RETURN;
  163. return Promise.resolve(sto.updateStore('$', temp));
  164. };
  165. const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
  166. const block = new Commands.CommandBlock([], [new Commands.SysCall(maxFun)]);
  167. const func = new Commands.Function('$max', new MultiType([Types.INTEGER, Types.REAL]),
  168. [new Commands.FormalParameter(paramType, 'x', false)],
  169. block);
  170. return func;
  171. }
  172. export function createMinFun () {
  173. const minFun = (sto, _) => {
  174. const x = sto.applyStore('x');
  175. const numbers = x.value.map(stoObj => stoObj.value);
  176. const result = Decimal.min(...numbers);
  177. const temp = new StoreObject(x.type.innerType, result);
  178. sto.mode = Modes.RETURN;
  179. return Promise.resolve(sto.updateStore('$', temp));
  180. };
  181. const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
  182. const block = new Commands.CommandBlock([], [new Commands.SysCall(minFun)]);
  183. const func = new Commands.Function('$min', new MultiType([Types.INTEGER, Types.REAL]),
  184. [new Commands.FormalParameter(paramType, 'x', false)],
  185. block);
  186. return func;
  187. }