math.js 7.1 KB

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