math.js 6.6 KB

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