operators.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. function lazy_bool (arg, desc, name) {
  2. ensure(is(arg, Types.Bool), 'arg_require_bool', name)
  3. return arg
  4. }
  5. function apply_operator (name, a, b) {
  6. assert(is(name, Types.String))
  7. if (is(a, Types.Struct)) {
  8. let s = get_common_schema(a, b)
  9. return call(s.get_operator(name), [a, b])
  10. } else {
  11. assert(is(a, Types.Instance))
  12. let f = get_common_operator(a, b, name)
  13. return call(f, [a, b])
  14. }
  15. }
  16. function apply_unary (name, a) {
  17. assert(is(name, Types.String))
  18. if (is(a, Types.Struct)) {
  19. return call(a.schema.get_operator(name), [a])
  20. } else {
  21. assert(is(a, Types.Instance))
  22. return call(a.class_.get_operator(name), [a])
  23. }
  24. }
  25. let operators = {
  26. 'is': f (
  27. 'operator.is',
  28. 'function operator.is (x: Any, T: Type) -> Bool',
  29. (x, A) => {
  30. // if T is a custom type, its checker must be f: [Any] --> Bool
  31. // this constraint should be enforced by custom type creator
  32. return call(A[Checker], [x])
  33. }
  34. ),
  35. 'as': f (
  36. 'operator.as',
  37. `function operator.as (x: Operand<'as'>, T: Type) -> Object`,
  38. (x, T) => {
  39. let y = null
  40. if (is(x, Types.Struct)) {
  41. y = call(x.schema.get_operator('as'), [x, T])
  42. } else {
  43. assert(is(x, Types.Instance))
  44. y = call(x.class_.get_operator('as'), [x, T])
  45. }
  46. ensure(is(y, T), 'invalid_cast')
  47. return y
  48. }
  49. ),
  50. 'str': f (
  51. 'operator.str',
  52. `function operator.str (o: Operand<'str'>) -> String`,
  53. o => apply_unary('str', o),
  54. 'function operator.str (p: Bool) -> String',
  55. p => p? 'true': 'false',
  56. 'function operator.str (x: Number) -> String',
  57. x => Number.prototype.toString.call(x),
  58. 'function operator.str (s: String) -> String',
  59. s => s
  60. ),
  61. 'len': f (
  62. 'operator.len',
  63. `function operator.len (o: Operand<'len'>) -> Size`,
  64. o => apply_unary('len', o),
  65. 'function operator.len (l: List) -> Size',
  66. l => l.length
  67. ),
  68. 'copy': f (
  69. 'copy',
  70. `function copy (o: Operand<'copy'>) -> Object`,
  71. o => {
  72. assert(is(o, Types.Instance))
  73. let copied = apply_unary('copy', o)
  74. ensure(is(copied, Types.Instance), 'invalid_copy')
  75. ensure(copied.class_ === o.class_, 'invalid_copy')
  76. ensure(copied !== o, 'did_not_copy')
  77. return copied
  78. },
  79. 'function copy (s: Struct) -> Struct',
  80. s => new_struct(s.schema, copy(s.data)),
  81. 'function copy (l: List) -> List',
  82. l => copy(l),
  83. 'function copy (h: Hash) -> Hash',
  84. h => copy(h)
  85. ),
  86. 'prms': f (
  87. 'operator.prms',
  88. `function operator.prms (o: Operand<'prms'>) -> Promise`,
  89. o => apply_unary('prms', o),
  90. 'function operator.prms (p: Promise) -> Promise',
  91. p => p
  92. ),
  93. 'iter': f (
  94. 'operator.iter',
  95. `function operator.iter (o: Operand<'iter'>) -> Iterator`,
  96. o => apply_unary('iter', o),
  97. 'function operator.iter (e: Enum) -> Iterator',
  98. e => e.iterate_items(),
  99. 'function operator.iter (i: ES_Iterable) -> Iterator',
  100. i => i[Symbol.iterator]()
  101. ),
  102. 'obsv': f (
  103. 'operator.obsv',
  104. `function operator.obsv (o: Operand<'obsv'>) -> Observer`,
  105. o => apply_unary('obsv', o),
  106. 'function operator.obsv (o: Observer) -> Observer',
  107. o => o
  108. ),
  109. 'async_iter': f (
  110. 'operator.async_iter',
  111. `function operator.async_iter (o: Operand<'async_iter'>) -> AsyncIterator`,
  112. o => apply_unary('async_iter', o),
  113. 'function operator.async_iter (ai: ES_AsyncIterable) -> AsyncIterator',
  114. ai => ai[Symbol.asyncIterator]()
  115. ),
  116. 'enum': f (
  117. 'operator.enum',
  118. `function operator.enum (o: Operand<'enum'>) -> EntryList`,
  119. o => apply_unary('enum', o),
  120. 'function operator.enum (e: Enum) -> EntryList',
  121. e => {
  122. let keys = e.keys()
  123. return new_struct(Types.EntryList, {
  124. keys, values: keys.map(k => e.get(k))
  125. })
  126. },
  127. 'function operator.enum (h: Hash) -> EntryList',
  128. h => {
  129. let keys = Object.keys(h)
  130. return new Struct(Types.EntryList, {
  131. keys, values: keys.map(k => h[k])
  132. })
  133. }
  134. ),
  135. 'negate': f (
  136. 'operator.negate',
  137. `function operator.negate (o: Operand<'negate'>) -> Object`,
  138. o => apply_unary('negate', o),
  139. 'function operator.negate (x: Number) -> Number',
  140. x => 0 - x
  141. ),
  142. /* Pull, Push, Derive, Otherwise */
  143. '<<': f (
  144. 'operator.pull',
  145. `function operator.pull (a: Operand<'<<'>, b: Operand<'<<'>) -> Any`,
  146. (a, b) => apply_operator('<<', a, b),
  147. 'function operator.pull (f: Callable, x: Any) -> Any',
  148. (f, x) => call(f, [x]),
  149. 'function operator.pull (l: Hash, r: Hash) -> Hash',
  150. (l, r) => Object.assign(l, r),
  151. 'function operator.pull (s: String, x: Any) -> String',
  152. (s, x) => call(string_format, [s, x])
  153. ),
  154. '>>': f (
  155. 'operator.push',
  156. `function operator.push (a: Operand<'>>'>, b: Operand<'>>'>) -> Any`,
  157. (a, b) => apply_operator('>>', a, b)
  158. ),
  159. '=>': f (
  160. 'operator.derive',
  161. 'function operator.derive (p: Bool, ok: Callable) -> Any',
  162. (p, ok) => p? ok(): Nil
  163. ),
  164. 'or': f (
  165. 'operator.otherwise',
  166. 'function operator.otherwise (x: Any, fallback: Callable) -> Any',
  167. (x, fallback) => (x !== Nil)? x: fallback()
  168. ),
  169. /* Comparsion */
  170. '<': f (
  171. 'operator.less_than',
  172. `function operator.less_than (a: Operand<'<'>, b: Operand<'<'>) -> Bool`,
  173. (a, b) => apply_operator('<', a, b),
  174. 'function operator.less_than (a: String, b: String) -> Bool',
  175. (a, b) => a < b,
  176. 'function operator.less_than (x: Number, y: Number) -> Bool',
  177. (x, y) => x < y
  178. ),
  179. '>': f (
  180. 'operator.greater_than',
  181. 'function operator.greater_than (l: Any, r: Any) -> Bool',
  182. (l, r) => operators['<'](r, l)
  183. ),
  184. '<=': f (
  185. 'operator.less_than_or_equal',
  186. 'function operator.less_than_or_equal (l: Any, r: Any) -> Bool',
  187. (l, r) => !operators['<'](r, l)
  188. ),
  189. '>=': f (
  190. 'operator.greater_than_or_equal',
  191. 'function operator.greater_than_or_equal (l: Any, r: Any) -> Bool',
  192. (l, r) => !operators['<'](l, r)
  193. ),
  194. '==': f (
  195. 'operator.equal',
  196. `function operator.equal (a: Operand<'=='>, b: Operand<'=='>) -> Bool`,
  197. (a, b) => apply_operator('==', a, b),
  198. 'function operator.equal (p: Bool, q: Bool) -> Bool',
  199. (p, q) => (p === q),
  200. 'function operator.equal (a: String, b: String) -> Bool',
  201. (a, b) => (a === b),
  202. 'function operator.equal (x: Number, y: Number) -> Bool',
  203. (x, y) => (x === y)
  204. ),
  205. '!=': f (
  206. 'operator.not_equal',
  207. 'function operator.not_equal (l: Any, r: Any) -> Bool',
  208. (l, r) => !operators['=='](l, r)
  209. ),
  210. '~~': f (
  211. 'operator.same',
  212. 'function operator.same (l: Any, r: Any) -> Bool',
  213. (l, r) => (Number.isNaN(l) && Number.isNaN(r)) || (l === r)
  214. ),
  215. '!~': f (
  216. 'operator.not_same',
  217. 'function operator.not_same (l: Any, r: Any) -> Bool',
  218. (l, r) => !operators['~~'](l, r)
  219. ),
  220. '<=>': f (
  221. 'operator.type_equal',
  222. 'function operator.type_equal (L: Type, R: Type) -> Bool',
  223. (L, R) => type_equivalent(L, R)
  224. ),
  225. '<!=>': f (
  226. 'operator.type_not_equal',
  227. 'function operator.type_not_equal (L: Type, R: Type) -> Bool',
  228. (L, R) => !operators['<=>'](L, R)
  229. ),
  230. /* Logic */
  231. '&&': f (
  232. 'operator.and',
  233. 'function operator.and (p: Bool, q: Callable) -> Bool',
  234. (p, q) => !p? false: lazy_bool(q(), 'operator.and', 'q')
  235. ),
  236. '||': f (
  237. 'operator.or',
  238. 'function operator.or (p: Bool, q: Callable) -> Bool',
  239. (p, q) => p? true: lazy_bool(q(), 'operator.or', 'q')
  240. ),
  241. '!': f (
  242. 'operator.not',
  243. 'function operator.not (p: Bool) -> Bool',
  244. p => !p
  245. ),
  246. '&': f (
  247. 'operator.intersect',
  248. 'function operator.intersect (A: Type, B: Type) -> Type',
  249. (A, B) => Ins(A, B)
  250. ),
  251. '|': f (
  252. 'operator.union',
  253. 'function operator.union (A: Type, B: Type) -> Type',
  254. (A, B) => Uni(A, B)
  255. ),
  256. '~': f (
  257. 'operator.complement',
  258. 'function operator.complement (A: Type) -> Type',
  259. A => Not(A)
  260. ),
  261. '\\': f (
  262. 'operator.difference',
  263. 'function operator.difference (A: Type, B: Type) -> Type',
  264. (A, B) => Ins(A, Not(B))
  265. ),
  266. 'not': f (
  267. 'operator.keyword_not',
  268. 'function operator.keyword_not (p: Bool) -> Bool',
  269. p => !p,
  270. 'function operator.keyword_not (T: Type) -> Type',
  271. T => Not(T)
  272. ),
  273. /* Arithmetic */
  274. '+': f (
  275. 'operator.plus',
  276. `function operator.plus (a: Operand<'+'>, b: Operand<'+'>) -> Object`,
  277. (a, b) => apply_operator('+', a, b),
  278. 'function operator.plus (a: List, b: List) -> List',
  279. (a, b) => [...a, ...b],
  280. 'function operator.plus (a: String, b: String) -> String',
  281. (a, b) => a + b,
  282. 'function operator.plus (x: Number, y: Number) -> GeneralNumber',
  283. (x, y) => x + y
  284. ),
  285. '-': f (
  286. 'operator.minus',
  287. `function operator.minus (a: Operand<'-'>, b: Operand<'-'>) -> Object`,
  288. (a, b) => apply_operator('-', a, b),
  289. 'function operator.minus (x: Number, y: Number) -> GeneralNumber',
  290. (x, y) => x - y
  291. ),
  292. '*': f (
  293. 'operator.times',
  294. `function operator.times (a: Operand<'*'>, b: Operand<'*'>) -> Object`,
  295. (a, b) => apply_operator('*', a, b),
  296. 'function operator.times (x: Number, y: Number) -> GeneralNumber',
  297. (x, y) => x * y
  298. ),
  299. '/': f (
  300. 'operator.divide',
  301. `function operator.divide (a: Operand<'/'>, b: Operand<'/'>) -> Object`,
  302. (a, b) => apply_operator('/', a, b),
  303. 'function operator.divide (x: Number, y: Number) -> GeneralNumber',
  304. (x, y) => x / y
  305. ),
  306. '%': f (
  307. 'operator.modulo',
  308. `function operator.modulo (a: Operand<'%'>, b: Operand<'%'>) -> Object`,
  309. (a, b) => apply_operator('%', a, b),
  310. 'function operator.modulo (x: Number, y: Number) -> GeneralNumber',
  311. (x, y) => x % y
  312. ),
  313. '^': f (
  314. 'operator.power',
  315. `function operator.power (a: Operand<'^'>, b: Operand<'^'>) -> Object`,
  316. (a, b) => apply_operator('^', a, b),
  317. 'function operator.power (x: Number, y: Number) -> GeneralNumber',
  318. (x, y) => Math.pow(x, y)
  319. )
  320. }
  321. Object.freeze(operators)
  322. let operator_is = operators['is']
  323. function str (value) {
  324. return call(operators['str'], [value])
  325. }
  326. function prms (value) {
  327. return call(operators['prms'], [value])
  328. }
  329. function iter (value) {
  330. return call(operators['iter'], [value])
  331. }
  332. function obsv (value) {
  333. return call(operators['obsv'], [value])
  334. }
  335. function async_iter (value) {
  336. return call(operators['async_iter'], [value])
  337. }
  338. function enum_ (value) {
  339. return call(operators['enum'], [value])
  340. }
  341. function get_operator (name) {
  342. assert(has(name, operators))
  343. return operators[name]
  344. }