functionalscript 0.0.473 → 0.0.475

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fsm/module.f.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  const list = require('../types/list/module.f.cjs')
2
- const { equal, isEmpty, fold, toArray, scan } = list
2
+ const { equal, isEmpty, fold, toArray, scan, foldScan } = list
3
3
  const byteSet = require('../types/byte_set/module.f.cjs')
4
- const { toRangeMap } = byteSet
4
+ const { toRangeMap, union: byteSetUnion, one, empty } = byteSet
5
5
  const sortedSet = require('../types/sorted_set/module.f.cjs')
6
- const { intersect, union } = sortedSet
6
+ const { intersect, union: sortedSetUnion } = sortedSet
7
7
  const rangeMap = require('../types/range_map/module.f.cjs')
8
8
  const { merge } = rangeMap
9
9
  const { unsafeCmp } = require('../types/function/compare/module.f.cjs')
@@ -11,6 +11,7 @@ const operator = require("../types/function/operator/module.f.cjs")
11
11
  const { strictEqual } = operator
12
12
  const { stringify } = require('../json/module.f.cjs')
13
13
  const { identity } = require('../types/function/module.f.cjs')
14
+ const { stringToList } = require('../text/utf16/module.f.cjs')
14
15
 
15
16
  /** @typedef {readonly[string, byteSet.ByteSet, string]} Rule */
16
17
 
@@ -24,8 +25,23 @@ const { identity } = require('../types/function/module.f.cjs')
24
25
 
25
26
  const stringifyIdentity = stringify(identity)
26
27
 
28
+ /** @type {(s: string) => byteSet.ByteSet} */
29
+ const toRange = s => {
30
+ const [b, e] = toArray(stringToList(s))
31
+ return byteSet.range([b, e])
32
+ }
33
+
34
+ /** @type {operator.Fold<number, byteSet.ByteSet>} */
35
+ const toUnionOp = i => bs => byteSetUnion(bs)(one(i))
36
+
37
+ /** @type {(s: string) => byteSet.ByteSet} */
38
+ const toUnion = s => {
39
+ const codePoints = stringToList(s)
40
+ return fold(toUnionOp)(empty)(codePoints)
41
+ }
42
+
27
43
  /** @type {rangeMap.Operators<sortedSet.SortedSet<string>>} */
28
- const mergeOp = { union: union(unsafeCmp), equal: equal(strictEqual) }
44
+ const mergeOp = { union: sortedSetUnion(unsafeCmp), equal: equal(strictEqual) }
29
45
 
30
46
  /** @type {(s: string) => (set: sortedSet.SortedSet<string>) => boolean} */
31
47
  const hasState = s => set => !isEmpty(intersect(unsafeCmp)([s])(set))
@@ -57,10 +73,34 @@ const addEntry = grammar => set => dfa => {
57
73
  return fold(addEntry(grammar))(newDfa)(newStates)
58
74
  }
59
75
 
76
+ /** @type {string[]} */
77
+ const emptyState = []
78
+
79
+ const emptyStateStringify = stringifyIdentity(emptyState)
80
+
81
+ const initialState = ['']
82
+
83
+ const initialStateStringify = stringifyIdentity(initialState)
84
+
60
85
  /** @type {(grammar: Grammar) => Dfa} */
61
- const dfa = grammar => addEntry(grammar)([''])({})
86
+ const dfa = grammar => addEntry(grammar)(initialState)({})
87
+
88
+ /** @type {(dfa: Dfa) => operator.Fold<number, string>} */
89
+ const runOp = dfa => input => s => {
90
+ const state = rangeMap.get(input)(dfa[s])
91
+ return state === undefined ? emptyStateStringify : state
92
+ }
93
+
94
+ /** @type {(dfa: Dfa) => (input: list.List<number>) => list.List<string>} */
95
+ const run = dfa => input => foldScan(runOp(dfa))(initialStateStringify)(input)
62
96
 
63
97
  module.exports = {
64
98
  /** @readonly */
65
99
  dfa,
100
+ /** @readonly */
101
+ run,
102
+ /** @readonly */
103
+ toRange,
104
+ /** @readonly */
105
+ toUnion
66
106
  }
package/fsm/test.f.cjs CHANGED
@@ -3,39 +3,43 @@ const byteSet = require('../types/byte_set/module.f.cjs')
3
3
  const { sort, fromEntries } = require('../types/object/module.f.cjs')
4
4
  const json = require('../json/module.f.cjs')
5
5
  const { identity } = require('../types/function/module.f.cjs')
6
+ const { toArray } = require('../types/list/module.f.cjs')
7
+ const { stringToList } = require('../text/utf16/module.f.cjs')
6
8
 
7
- /** @type {(c: string) => number} */
8
- const toCharCode = c => c.charCodeAt(0)
9
+ const stringifyIdentity = json.stringify(identity)
9
10
 
10
- module.exports = {
11
- dfa: () => {
12
- const lowercaseAlpha = byteSet.range([toCharCode('a'), toCharCode('z')])
13
- const uppercaseAlpha = byteSet.range([toCharCode('A'), toCharCode('Z')])
14
- const alpha = byteSet.union(lowercaseAlpha)(uppercaseAlpha)
15
- const idSymbol = byteSet.union(byteSet.one(toCharCode('_')))(byteSet.one(toCharCode('$')))
16
- const idBegin = byteSet.union(alpha)(idSymbol)
17
- const digit = byteSet.range([toCharCode('0'), toCharCode('9')])
18
- const idNext = byteSet.union(idBegin)(digit)
19
- const dot = byteSet.one(toCharCode('.'))
11
+ const buildDfa = () => {
12
+ const lowercaseAlpha = _.toRange('az')
13
+ const uppercaseAlpha = _.toRange('AZ')
14
+ const alpha = byteSet.union(lowercaseAlpha)(uppercaseAlpha)
15
+ const idSymbol = _.toUnion('_$')
16
+ const idBegin = byteSet.union(alpha)(idSymbol)
17
+ const digit = _.toRange('09')
18
+ const idNext = byteSet.union(idBegin)(digit)
19
+ const dot = _.toUnion('.')
20
20
 
21
- /** @type {_.Grammar} */
22
- const grammar = [
23
- ['', digit, 'int'],
24
- ['int', digit, 'int'],
25
- ['', digit, 'floatBegin'],
26
- ['floatBegin', digit, 'floatBegin'],
27
- ['floatBegin', dot, 'floatDot'],
28
- ['floatDot', digit, 'float'],
29
- ['float', digit, 'float'],
30
- ['', idBegin, 'id'],
31
- ['id', idNext, 'id']
32
- ]
21
+ /** @type {_.Grammar} */
22
+ const grammar = [
23
+ ['', digit, 'int'],
24
+ ['int', digit, 'int'],
25
+ ['', digit, 'floatBegin'],
26
+ ['floatBegin', digit, 'floatBegin'],
27
+ ['floatBegin', dot, 'floatDot'],
28
+ ['floatDot', digit, 'float'],
29
+ ['float', digit, 'float'],
30
+ ['', idBegin, 'id'],
31
+ ['id', idNext, 'id']
32
+ ]
33
+ return _.dfa(grammar)
34
+ }
33
35
 
34
- const dfa = _.dfa(grammar)
36
+ module.exports = {
37
+ dfa: () => {
38
+ const dfa = buildDfa()
35
39
  const entries = Object.entries(dfa)
36
40
  const sortedEntries = sort(entries)
37
41
  const obj = fromEntries(sortedEntries)
38
- const result = json.stringify(identity)(obj)
42
+ const result = stringifyIdentity(obj)
39
43
 
40
44
  const expectedObj = {
41
45
  '[""]': [
@@ -72,8 +76,59 @@ module.exports = {
72
76
  ],
73
77
  '[]': []
74
78
  };
75
- const expectedResult = json.stringify(identity)(expectedObj)
79
+ const expectedResult = stringifyIdentity(expectedObj)
76
80
 
77
81
  if (result !== expectedResult) {throw result }
78
- }
82
+ },
83
+ run: [
84
+ () => {
85
+ const dfa = buildDfa()
86
+ const input = stringToList('a1')
87
+ const result = stringifyIdentity(toArray(_.run(dfa)(input)))
88
+
89
+ const expectedOutput = [
90
+ '["id"]',
91
+ '["id"]'
92
+ ]
93
+ const expectedResult = stringifyIdentity(expectedOutput)
94
+ if (result !== expectedResult) { throw result }
95
+ },
96
+ () => {
97
+ const dfa = buildDfa()
98
+ const input = stringToList('0.1')
99
+ const result = stringifyIdentity(toArray(_.run(dfa)(input)))
100
+
101
+ const expectedOutput = [
102
+ '["floatBegin","int"]',
103
+ '["floatDot"]',
104
+ '["float"]'
105
+ ]
106
+ const expectedResult = stringifyIdentity(expectedOutput)
107
+ if (result !== expectedResult) { throw result }
108
+ },
109
+ () => {
110
+ const dfa = buildDfa()
111
+ const input = stringToList('//')
112
+ const result = stringifyIdentity(toArray(_.run(dfa)(input)))
113
+
114
+ const expectedOutput = [
115
+ '[]',
116
+ '[]'
117
+ ]
118
+ const expectedResult = stringifyIdentity(expectedOutput)
119
+ if (result !== expectedResult) { throw result }
120
+ },
121
+ () => {
122
+ const dfa = buildDfa()
123
+ const input = stringToList('::')
124
+ const result = stringifyIdentity(toArray(_.run(dfa)(input)))
125
+
126
+ const expectedOutput = [
127
+ '[]',
128
+ '[]'
129
+ ]
130
+ const expectedResult = stringifyIdentity(expectedOutput)
131
+ if (result !== expectedResult) { throw result }
132
+ }
133
+ ]
79
134
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.473",
3
+ "version": "0.0.475",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {
@@ -60,7 +60,32 @@ const tailReduce = equal => state => tail => {
60
60
  /** @type {<T>(op: Operators<T>) => RangeMerge<T>} */
61
61
  const merge = ({union, equal}) => genericMerge({reduceOp: reduceOp(union)(equal), tailReduce: tailReduce(equal)})(undefined)
62
62
 
63
+ /** @type {<T>(value: number) => (rm: RangeMapArray<T>) => T|undefined} */
64
+ const get = value => rm => {
65
+ let b = 0
66
+ let e = rm.length - 1
67
+ while (true) {
68
+ if (b >= rm.length) return undefined
69
+ if (e - b < 0) return rm[b][0]
70
+ const mid = b + (e - b >> 1)
71
+ const sign = cmp(value)(rm[mid][1])
72
+ switch(sign) {
73
+ case -1: {
74
+ e = mid - 1
75
+ break
76
+ }
77
+ case 0: { return rm[mid][0] }
78
+ case 1: {
79
+ b = mid + 1
80
+ break
81
+ }
82
+ }
83
+ }
84
+ }
85
+
63
86
  module.exports = {
64
87
  /** @readonly */
65
- merge
88
+ merge,
89
+ /** @readonly */
90
+ get
66
91
  }
@@ -77,5 +77,55 @@ module.exports = {
77
77
  const result = stringify(list.toArray(merged))
78
78
  if (result !== '[[["a"],1],[["a","b"],2],[["a"],5]]') { throw result }
79
79
  }
80
+ ],
81
+ get: [
82
+ () => {
83
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
84
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
85
+ const result = stringify(_.get(5)(rm))
86
+ if (result !== '["a"]') { throw result }
87
+ },
88
+ () => {
89
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
90
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
91
+ const result = stringify(_.get(10)(rm))
92
+ if (result !== '["a"]') { throw result }
93
+ },
94
+ () => {
95
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
96
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
97
+ const result = stringify(_.get(15)(rm))
98
+ if (result !== '["b"]') { throw result }
99
+ },
100
+ () => {
101
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
102
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
103
+ const result = stringify(_.get(20)(rm))
104
+ if (result !== '["b"]') { throw result }
105
+ },
106
+ () => {
107
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
108
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
109
+ const result = stringify(_.get(25)(rm))
110
+ if (result !== '["c"]') { throw result }
111
+ },
112
+ () => {
113
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
114
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
115
+ const result = stringify(_.get(30)(rm))
116
+ if (result !== '["c"]') { throw result }
117
+ },
118
+ () => {
119
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
120
+ const rm = [[['a'], 10], [['b'], 20], [['c'], 30]]
121
+ const result = _.get(35)(rm)
122
+ if (result !== undefined) { throw result }
123
+ },
124
+ () => {
125
+ /** @type {_.RangeMapArray<sortedSet.SortedSet<string>>} */
126
+ const rm = []
127
+ const result = _.get(10)(rm)
128
+ if (result !== undefined) { throw result }
129
+ }
80
130
  ]
81
131
  }