Advertisement
Guest User

Untitled

a guest
May 28th, 2017
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.34 KB | None | 0 0
  1. class Stream {
  2. constructor(tokens) {
  3. this.tokens = tokens
  4. this.pos = 0
  5. }
  6.  
  7. get next() {
  8. return this.tokens[this.pos++] || ''
  9. }
  10.  
  11. cancel() {
  12. this.pos--
  13. }
  14.  
  15. get done() {
  16. return this.pos >= this.tokens.length
  17. }
  18.  
  19. get rest() {
  20. return this.tokens.slice(this.pos)
  21. }
  22.  
  23. transaction(fn) {
  24. const rpos = this.pos
  25. const ret = fn()
  26. if (ret === failure) {
  27. this.pos = rpos
  28. return failure
  29. }
  30. return ret
  31. }
  32. }
  33.  
  34. const failure = Symbol('failure')
  35. const ignore = Symbol('ignore')
  36.  
  37. const eq = str => stream => stream.transaction(() => stream.next == str ? ignore : failure)
  38.  
  39. const re = regex => fn => stream => stream.transaction(() => {
  40. const ret = stream.next.match(regex)
  41. if (!ret) return failure
  42. return fn(ret)
  43. })
  44.  
  45. const assembly = (...parsers) => stream => stream.transaction(() => {
  46. console.log('assembly')
  47. let result = ignore
  48. for (const parser of parsers) {
  49. result = parser(result)(stream)
  50. if (result == failure)
  51. return failure
  52. }
  53. return result
  54. })
  55.  
  56. const chain = (...parsers) => fn => stream => stream.transaction(() => {
  57. const arr = []
  58. for (const parser of parsers) {
  59. const result = parser(stream)
  60. if (result == failure)
  61. return failure
  62. if (result != ignore)
  63. arr.push(result)
  64. }
  65. return fn(...arr)
  66. })
  67.  
  68. const choice = (...parsers) => stream => {
  69. for (const parser of parsers) {
  70. const result = parser(stream)
  71. if (result != failure)
  72. return result
  73. }
  74. return failure
  75. }
  76.  
  77. const repeatRange = parser => (low, high = Number.MAX_SAFE_INTEGER) => stream => stream.transaction(() => {
  78. const arr = []
  79. let i = 0
  80. for (; i < high; i++) {
  81. const result = parser(stream)
  82. if (result == failure)
  83. break
  84. if (result != ignore)
  85. arr.push(result)
  86. }
  87. if (i < low || i > high) return failure
  88. return arr
  89. })
  90.  
  91. const repeat = parser => number => repeatRange(parser)(number, number)
  92.  
  93. const many = parser => repeatRange(parser)(1)
  94.  
  95. const zeroOrMany = parser => repeatRange(parser)(0)
  96.  
  97. const maybe = parser => repeatRange(parser)(0, 1)
  98.  
  99. const must = parser => repeatRange(parser)(1, 1)
  100.  
  101. const packer = parser => fn => stream => {
  102. const ret = parser(stream)
  103. if (ret === failure)
  104. return failure
  105. return fn(ret)
  106. }
  107.  
  108. const $log = (...param) => stream => {
  109. console.log(...param, stream.rest)
  110. return ignore
  111. }
  112.  
  113. const $lazy = fn => a => b => fn(a)(b)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement