functionalscript 0.0.467 → 0.0.469

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,21 +1,64 @@
1
- const { todo } = require('../dev/module.f.cjs')
2
1
  const list = require('../types/list/module.f.cjs')
2
+ const { equal, isEmpty, fold, toArray, scan } = list
3
3
  const byteSet = require('../types/byte_set/module.f.cjs')
4
+ const { toRangeMap } = byteSet
5
+ const sortedSet = require('../types/sorted_set/module.f.cjs')
6
+ const { intersect, union } = sortedSet
7
+ const rangeMap = require('../types/range_map/module.f.cjs')
8
+ const { merge } = rangeMap
9
+ const { unsafeCmp } = require('../types/function/compare/module.f.cjs')
10
+ const operator = require("../types/function/operator/module.f.cjs")
11
+ const { strictEqual } = operator
12
+ const { stringify } = require('../json/module.f.cjs')
13
+ const { identity } = require('../types/function/module.f.cjs')
4
14
 
5
15
  /** @typedef {readonly[string, byteSet.ByteSet, string]} Rule */
6
16
 
7
17
  /** @typedef {list.List<Rule>} Grammar */
8
18
 
9
- /** @typedef {readonly string[]} ByteMap */
10
-
11
19
  /**
12
20
  * @typedef {{
13
- * readonly[state in string]: ByteMap
21
+ * readonly[state in string]: rangeMap.RangeMapArray<string>
14
22
  * }} Dfa
15
23
  */
16
24
 
25
+ const stringifyIdentity = stringify(identity)
26
+
27
+ /** @type {rangeMap.Operators<sortedSet.SortedSet<string>>} */
28
+ const mergeOp = { union: union(unsafeCmp), equal: equal(strictEqual) }
29
+
30
+ /** @type {(s: string) => (set: sortedSet.SortedSet<string>) => boolean} */
31
+ const hasState = s => set => !isEmpty(intersect(unsafeCmp)([s])(set))
32
+
33
+ /** @type {(set: sortedSet.SortedSet<string>) => operator.Fold<Rule, rangeMap.RangeMap<sortedSet.SortedSet<string>>>} */
34
+ const foldOp = set => ([ruleIn, bs, ruleOut]) => rm => {
35
+ if (hasState(ruleIn)(set)) { return merge(mergeOp)(rm)(toRangeMap(bs)(ruleOut)) }
36
+ return rm
37
+ }
38
+
39
+ /** @type {operator.Scan<rangeMap.Entry<sortedSet.SortedSet<string>>, rangeMap.Entry<string>>} */
40
+ const stringifyOp = ([sortedSet, max]) => [[stringifyIdentity(sortedSet), max], stringifyOp]
41
+
42
+ const scanStringify = scan(stringifyOp)
43
+
44
+ /** @type {operator.Scan<rangeMap.Entry<sortedSet.SortedSet<string>>, sortedSet.SortedSet<string>>} */
45
+ const fetchOp = ([item, _]) => [item, fetchOp]
46
+
47
+ const scanFetch = scan(fetchOp)
48
+
49
+ /** @type {(grammar: Grammar) => operator.Fold<sortedSet.SortedSet<string>, Dfa>} */
50
+ const addEntry = grammar => set => dfa => {
51
+ const s = stringifyIdentity(set)
52
+ if (s in dfa) { return dfa }
53
+ const setMap = fold(foldOp(set))(undefined)(grammar)
54
+ const stringMap = toArray(scanStringify(setMap))
55
+ const newDfa = { ...dfa, [s]: stringMap }
56
+ const newStates = scanFetch(setMap)
57
+ return fold(addEntry(grammar))(newDfa)(newStates)
58
+ }
59
+
17
60
  /** @type {(grammar: Grammar) => Dfa} */
18
- const dfa = grammar => todo()
61
+ const dfa = grammar => addEntry(grammar)([''])({})
19
62
 
20
63
  module.exports = {
21
64
  /** @readonly */
package/fsm/test.f.cjs CHANGED
@@ -1,5 +1,79 @@
1
1
  const _ = require('./module.f.cjs')
2
+ const byteSet = require('../types/byte_set/module.f.cjs')
3
+ const { sort, fromEntries } = require('../types/object/module.f.cjs')
4
+ const json = require('../json/module.f.cjs')
5
+ const { identity } = require('../types/function/module.f.cjs')
6
+
7
+ /** @type {(c: string) => number} */
8
+ const toCharCode = c => c.charCodeAt(0)
2
9
 
3
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('.'))
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
+ ]
33
+
34
+ const dfa = _.dfa(grammar)
35
+ const entries = Object.entries(dfa)
36
+ const sortedEntries = sort(entries)
37
+ const obj = fromEntries(sortedEntries)
38
+ const result = json.stringify(identity)(obj)
39
+
40
+ const expectedObj = {
41
+ '[""]': [
42
+ [ '[]', 35 ],
43
+ [ '["id"]', 36 ],
44
+ [ '[]', 47 ],
45
+ [ '["floatBegin","int"]', 57 ],
46
+ [ '[]', 64 ],
47
+ [ '["id"]', 90 ],
48
+ [ '[]', 94 ],
49
+ [ '["id"]', 95 ],
50
+ [ '[]', 96 ],
51
+ [ '["id"]', 122 ]
52
+ ],
53
+ '["float"]': [ [ '[]', 47 ], [ '["float"]', 57 ] ],
54
+ '["floatBegin","int"]': [
55
+ [ '[]', 45 ],
56
+ [ '["floatDot"]', 46 ],
57
+ [ '[]', 47 ],
58
+ [ '["floatBegin","int"]', 57 ]
59
+ ],
60
+ '["floatDot"]': [ [ '[]', 47 ], [ '["float"]', 57 ] ],
61
+ '["id"]': [
62
+ [ '[]', 35 ],
63
+ [ '["id"]', 36 ],
64
+ [ '[]', 47 ],
65
+ [ '["id"]', 57 ],
66
+ [ '[]', 64 ],
67
+ [ '["id"]', 90 ],
68
+ [ '[]', 94 ],
69
+ [ '["id"]', 95 ],
70
+ [ '[]', 96 ],
71
+ [ '["id"]', 122 ]
72
+ ],
73
+ '[]': []
74
+ };
75
+ const expectedResult = json.stringify(identity)(expectedObj)
4
76
 
77
+ if (result !== expectedResult) {throw result }
78
+ }
5
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.467",
3
+ "version": "0.0.469",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {
@@ -72,6 +72,8 @@ module.exports = {
72
72
  /** @readonly */
73
73
  unset,
74
74
  /** @readonly */
75
+ one,
76
+ /** @readonly */
75
77
  union,
76
78
  /** @readonly */
77
79
  setRange,
@@ -1,6 +1,7 @@
1
1
  const sortedList = require("../sorted_list/module.f.cjs")
2
2
  const { genericMerge } = sortedList
3
3
  const list = require("../list/module.f.cjs")
4
+ const { next } = list
4
5
  const option = require("../option/module.f.cjs")
5
6
  const { cmp } = require('../number/module.f.cjs')
6
7
  const operator = require("../function/operator/module.f.cjs")
@@ -15,6 +16,11 @@ const operator = require("../function/operator/module.f.cjs")
15
16
  * @typedef {sortedList.SortedList<Entry<T>>} RangeMap
16
17
  */
17
18
 
19
+ /**
20
+ * @template T
21
+ * @typedef {readonly Entry<T>[]} RangeMapArray
22
+ */
23
+
18
24
  /**
19
25
  * @template T
20
26
  * @typedef {{
@@ -45,7 +51,7 @@ const reduceOp = union => equal => state => ([aItem, aMax]) => ([bItem, bMax])
45
51
  /** @type {<T>(equal: operator.Equal<T>) => sortedList.TailReduce<Entry<T>, RangeState<T>>} */
46
52
  const tailReduce = equal => state => tail => {
47
53
  if (state === undefined) { return tail }
48
- const tailResult = list.next(tail)
54
+ const tailResult = next(tail)
49
55
  if (tailResult === undefined) { return [state] }
50
56
  if (equal(state[0])(tailResult.first[0])) { return tailResult }
51
57
  return { first: state, tail: tailResult }
@@ -3,12 +3,18 @@ const list = require('../list/module.f.cjs')
3
3
  const option = require('../option/module.f.cjs')
4
4
  const { next } = list
5
5
  const { identity } = require('../function/module.f.cjs')
6
+ const range = require('../range/module.f.cjs')
6
7
 
7
8
  /**
8
9
  * @template T
9
10
  * @typedef {list.List<T>} SortedList
10
11
  */
11
12
 
13
+ /**
14
+ * @template T
15
+ * @typedef {readonly T[]} SortedArray
16
+ */
17
+
12
18
  /**
13
19
  * @template T
14
20
  * @typedef {(a: T) => (b: T) => compare.Sign} Cmp
@@ -78,9 +84,33 @@ const cmpReduce = cmp => () => a => b => {
78
84
  /** @type {() => <T>(tail: list.List<T>) => list.List<T>} */
79
85
  const mergeTail = () => identity
80
86
 
87
+ /** @type {<T>(cmp: Cmp<T>) => (value: T) => (array: SortedArray<T>) => T|undefined} */
88
+ const find = cmp => value => array => {
89
+ let b = 0
90
+ let e = array.length - 1
91
+ while (true) {
92
+ if (e - b < 0) return undefined
93
+ const mid = b + (e - b >> 1)
94
+ const sign = cmp(value)(array[mid])
95
+ switch(sign) {
96
+ case -1: {
97
+ e = mid - 1
98
+ break
99
+ }
100
+ case 0: { return value }
101
+ case 1: {
102
+ b = mid + 1
103
+ break
104
+ }
105
+ }
106
+ }
107
+ }
108
+
81
109
  module.exports = {
82
110
  /** @readonly */
83
111
  merge,
84
112
  /** @readonly */
85
- genericMerge
113
+ genericMerge,
114
+ /** @readonly */
115
+ find
86
116
  }
@@ -29,5 +29,23 @@ module.exports = {
29
29
  const len = length(result)
30
30
  if (len != n) { throw result }
31
31
  }
32
+ ],
33
+ find: [
34
+ () => {
35
+ const result = _.find(unsafeCmp)(0)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
36
+ if (result !== 0) { throw result }
37
+ },
38
+ () => {
39
+ const result = _.find(unsafeCmp)(3)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
40
+ if (result !== undefined) { throw result }
41
+ },
42
+ () => {
43
+ const result = _.find(unsafeCmp)(77)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
44
+ if (result !== undefined) { throw result }
45
+ },
46
+ () => {
47
+ const result = _.find(unsafeCmp)(80)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
48
+ if (result !== 80) { throw result }
49
+ }
32
50
  ]
33
51
  }
@@ -1,9 +1,7 @@
1
1
  const compare = require("../function/compare/module.f.cjs")
2
2
  const { toArray } = require("../list/module.f.cjs")
3
3
  const sortedList = require("../sorted_list/module.f.cjs")
4
- const { merge, genericMerge } = sortedList
5
- const list = require("../list/module.f.cjs")
6
- const option = require("../option/module.f.cjs")
4
+ const { merge, genericMerge, find } = sortedList
7
5
 
8
6
  /**
9
7
  * @template T
@@ -34,9 +32,14 @@ const intersectReduce = cmp => state => a => b => {
34
32
 
35
33
  const intersectTail = () => () => undefined
36
34
 
35
+ /** @type {<T>(cmp: Cmp<T>) => (value: T) => (set: SortedSet<T>) => boolean} */
36
+ const has = cmp => value => set => find(cmp)(value)(set) === value
37
+
37
38
  module.exports = {
38
39
  /** @readonly */
39
40
  union,
40
41
  /** @readonly */
41
- intersect
42
+ intersect,
43
+ /** @readonly */
44
+ has
42
45
  }
@@ -40,5 +40,23 @@ module.exports = {
40
40
  const result = stringify(toArray(_.intersect(unsafeCmp)([1, 2, 3])([])))
41
41
  if (result !== '[]') { throw result }
42
42
  }
43
+ ],
44
+ has: [
45
+ () => {
46
+ const result = _.has(unsafeCmp)(0)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
47
+ if (!result) { throw result }
48
+ },
49
+ () => {
50
+ const result = _.has(unsafeCmp)(3)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
51
+ if (result) { throw result }
52
+ },
53
+ () => {
54
+ const result = _.has(unsafeCmp)(77)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
55
+ if (result) { throw result }
56
+ },
57
+ () => {
58
+ const result = _.has(unsafeCmp)(80)([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
59
+ if (!result) { throw result }
60
+ }
43
61
  ]
44
62
  }