math.js 7.0 KB

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