@jdeighan/coffee-utils 10.0.9 → 10.0.12

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jdeighan/coffee-utils",
3
3
  "type": "module",
4
- "version": "10.0.9",
4
+ "version": "10.0.12",
5
5
  "description": "A set of utility functions for CoffeeScript",
6
6
  "main": "coffee_utils.js",
7
7
  "exports": {
@@ -22,6 +22,7 @@
22
22
  "./placeholders": "./src/placeholders.js",
23
23
  "./section": "./src/Section.js",
24
24
  "./sectionmap": "./src/SectionMap.js",
25
+ "./fsa": "./src/fsa.js",
25
26
  "./package.json": "./package.json"
26
27
  },
27
28
  "engines": {
@@ -56,6 +57,6 @@
56
57
  "svelte": "^3.49.0"
57
58
  },
58
59
  "devDependencies": {
59
- "@jdeighan/unit-tester": "^2.0.21"
60
+ "@jdeighan/unit-tester": "^2.0.23"
60
61
  }
61
62
  }
@@ -6,10 +6,12 @@ import readline from 'readline'
6
6
  import {assert, error, croak} from '@jdeighan/unit-tester/utils'
7
7
  import {
8
8
  undef, pass, defined, isEmpty, isString, isArray, nonEmpty, rtrim,
9
+ escapeStr,
9
10
  } from '@jdeighan/coffee-utils'
10
11
 
11
12
  # ---------------------------------------------------------------------------
12
13
  # blockToArray - split a block into lines
14
+ # DEPRECATED - use toArray()
13
15
 
14
16
  export blockToArray = (block) ->
15
17
 
@@ -68,7 +70,8 @@ export toArray = (item, option=undef) ->
68
70
  return lNewLines
69
71
 
70
72
  # ---------------------------------------------------------------------------
71
- # arrayToBlock - block will have no trailing whitespace
73
+ # arrayToBlock - block and lines in block will have no trailing whitespace
74
+ # DEPRECATED - use toBlock()
72
75
 
73
76
  export arrayToBlock = (lLines) ->
74
77
 
@@ -90,11 +93,11 @@ export toBlock = (lLines) ->
90
93
  if (lLines == undef)
91
94
  return undef
92
95
  assert isArray(lLines), "lLines is not an array"
93
- lLines = lLines.filter((line) => defined(line));
94
- if lLines.length == 0
95
- return undef
96
- else
97
- return lLines.join('\n')
96
+ lNewLines = []
97
+ for line in lLines
98
+ if defined(line)
99
+ lNewLines.push rtrim(line)
100
+ return lNewLines.join("\n")
98
101
 
99
102
  # ---------------------------------------------------------------------------
100
103
 
@@ -18,11 +18,13 @@ import {
18
18
  isString,
19
19
  isArray,
20
20
  nonEmpty,
21
- rtrim
21
+ rtrim,
22
+ escapeStr
22
23
  } from '@jdeighan/coffee-utils';
23
24
 
24
25
  // ---------------------------------------------------------------------------
25
26
  // blockToArray - split a block into lines
27
+ // DEPRECATED - use toArray()
26
28
  export var blockToArray = function(block) {
27
29
  var lLines, len;
28
30
  if (isEmpty(block)) {
@@ -89,7 +91,8 @@ export var toArray = function(item, option = undef) {
89
91
  };
90
92
 
91
93
  // ---------------------------------------------------------------------------
92
- // arrayToBlock - block will have no trailing whitespace
94
+ // arrayToBlock - block and lines in block will have no trailing whitespace
95
+ // DEPRECATED - use toBlock()
93
96
  export var arrayToBlock = function(lLines) {
94
97
  if (lLines === undef) {
95
98
  return undef;
@@ -109,18 +112,19 @@ export var arrayToBlock = function(lLines) {
109
112
  // toBlock - block may have trailing whitespace
110
113
  // but undef items are ignored
111
114
  export var toBlock = function(lLines) {
115
+ var i, lNewLines, len1, line;
112
116
  if (lLines === undef) {
113
117
  return undef;
114
118
  }
115
119
  assert(isArray(lLines), "lLines is not an array");
116
- lLines = lLines.filter((line) => {
117
- return defined(line);
118
- });
119
- if (lLines.length === 0) {
120
- return undef;
121
- } else {
122
- return lLines.join('\n');
120
+ lNewLines = [];
121
+ for (i = 0, len1 = lLines.length; i < len1; i++) {
122
+ line = lLines[i];
123
+ if (defined(line)) {
124
+ lNewLines.push(rtrim(line));
125
+ }
123
126
  }
127
+ return lNewLines.join("\n");
124
128
  };
125
129
 
126
130
  // ---------------------------------------------------------------------------
@@ -241,7 +241,10 @@ export pushCond = (lItems, item, doPush=notInArray) ->
241
241
 
242
242
  export words = (str) ->
243
243
 
244
- return str.trim().split(/\s+/)
244
+ str = str.trim()
245
+ if (str == '')
246
+ return []
247
+ return str.split(/\s+/)
245
248
 
246
249
  # ---------------------------------------------------------------------------
247
250
 
@@ -253,7 +253,11 @@ export var pushCond = function(lItems, item, doPush = notInArray) {
253
253
 
254
254
  // ---------------------------------------------------------------------------
255
255
  export var words = function(str) {
256
- return str.trim().split(/\s+/);
256
+ str = str.trim();
257
+ if (str === '') {
258
+ return [];
259
+ }
260
+ return str.split(/\s+/);
257
261
  };
258
262
 
259
263
  // ---------------------------------------------------------------------------
package/src/fsa.coffee ADDED
@@ -0,0 +1,83 @@
1
+ # fsa.coffee
2
+
3
+ import {assert, croak} from '@jdeighan/unit-tester/utils'
4
+ import {
5
+ undef, defined, notdefined, words, isEmpty, nonEmpty,
6
+ isString, OL,
7
+ } from '@jdeighan/coffee-utils'
8
+ import {toArray} from '@jdeighan/coffee-utils/block'
9
+ import {LOG} from '@jdeighan/coffee-utils/log'
10
+ import {debug} from '@jdeighan/coffee-utils/debug'
11
+
12
+ # ---------------------------------------------------------------------------
13
+
14
+ export class FSA
15
+
16
+ constructor: (block) ->
17
+
18
+ debug "enter FSA()"
19
+ assert isString(block), "block not a string"
20
+ @hTransitions = {}
21
+ lLines = toArray(block, 'noEmptyLines')
22
+ debug 'lLines', lLines
23
+ for line,i in lLines
24
+ debug "LINE #{i}", line
25
+ lWords = words(line)
26
+ if (lWords.length == 3)
27
+ [bState, token, eState] = lWords
28
+ output = undef
29
+ else if (lWords.length == 4)
30
+ [bState, token, eState, output] = lWords
31
+ else
32
+ croak "Invalid desc: #{OL(line)}"
33
+ debug "LINE #{i}: #{OL(bState)} #{OL(token)} #{OL(eState)} #{OL(output)}"
34
+ assert nonEmpty(eState), "Invalid FSA description #{i}"
35
+
36
+ # --- tokens may be quoted (but may not contain whitespace),
37
+ # but the quotes are stripped
38
+ if (i == 0)
39
+ assert (bState == 'start'), "Invalid FSA description #{i}"
40
+ token = @fixToken(token)
41
+ debug 'token', token
42
+ if isEmpty(output)
43
+ output = undef
44
+ hTrans = @hTransitions[bState]
45
+ if notdefined(hTrans)
46
+ hTrans = @hTransitions[bState] = {}
47
+ assert notdefined(hTrans[token]), "Duplicate transition"
48
+ hTrans[token] = [eState, output]
49
+ debug 'hTransitions', @hTransitions
50
+ @curState = 'start'
51
+ debug "return from FSA()"
52
+
53
+ # ..........................................................
54
+
55
+ fixToken: (token) ->
56
+
57
+ if lMatches = token.match(/^\'(.*)\'$/)
58
+ return lMatches[1]
59
+ else if lMatches = token.match(/^\"(.*)\"$/)
60
+ return lMatches[1]
61
+ else
62
+ return token
63
+
64
+ # ..........................................................
65
+
66
+ got: (token) ->
67
+ # --- returns pair [newState, output]
68
+
69
+ hTrans = @hTransitions[@curState]
70
+ if notdefined(hTrans)
71
+ return [undef, undef]
72
+ result = hTrans[token]
73
+ if notdefined(result)
74
+ return [undef, undef]
75
+ [newState, output] = result
76
+ assert nonEmpty(newState), "Failed: #{@curState} -> #{token}"
77
+ @curState = newState
78
+ return result
79
+
80
+ # ..........................................................
81
+
82
+ state: () ->
83
+ return @curState
package/src/fsa.js ADDED
@@ -0,0 +1,111 @@
1
+ // Generated by CoffeeScript 2.7.0
2
+ // fsa.coffee
3
+ import {
4
+ assert,
5
+ croak
6
+ } from '@jdeighan/unit-tester/utils';
7
+
8
+ import {
9
+ undef,
10
+ defined,
11
+ notdefined,
12
+ words,
13
+ isEmpty,
14
+ nonEmpty,
15
+ isString,
16
+ OL
17
+ } from '@jdeighan/coffee-utils';
18
+
19
+ import {
20
+ toArray
21
+ } from '@jdeighan/coffee-utils/block';
22
+
23
+ import {
24
+ LOG
25
+ } from '@jdeighan/coffee-utils/log';
26
+
27
+ import {
28
+ debug
29
+ } from '@jdeighan/coffee-utils/debug';
30
+
31
+ // ---------------------------------------------------------------------------
32
+ export var FSA = class FSA {
33
+ constructor(block) {
34
+ var bState, eState, hTrans, i, j, lLines, lWords, len, line, output, token;
35
+ debug("enter FSA()");
36
+ assert(isString(block), "block not a string");
37
+ this.hTransitions = {};
38
+ lLines = toArray(block, 'noEmptyLines');
39
+ debug('lLines', lLines);
40
+ for (i = j = 0, len = lLines.length; j < len; i = ++j) {
41
+ line = lLines[i];
42
+ debug(`LINE ${i}`, line);
43
+ lWords = words(line);
44
+ if (lWords.length === 3) {
45
+ [bState, token, eState] = lWords;
46
+ output = undef;
47
+ } else if (lWords.length === 4) {
48
+ [bState, token, eState, output] = lWords;
49
+ } else {
50
+ croak(`Invalid desc: ${OL(line)}`);
51
+ }
52
+ debug(`LINE ${i}: ${OL(bState)} ${OL(token)} ${OL(eState)} ${OL(output)}`);
53
+ assert(nonEmpty(eState), `Invalid FSA description ${i}`);
54
+ // --- tokens may be quoted (but may not contain whitespace),
55
+ // but the quotes are stripped
56
+ if (i === 0) {
57
+ assert(bState === 'start', `Invalid FSA description ${i}`);
58
+ }
59
+ token = this.fixToken(token);
60
+ debug('token', token);
61
+ if (isEmpty(output)) {
62
+ output = undef;
63
+ }
64
+ hTrans = this.hTransitions[bState];
65
+ if (notdefined(hTrans)) {
66
+ hTrans = this.hTransitions[bState] = {};
67
+ }
68
+ assert(notdefined(hTrans[token]), "Duplicate transition");
69
+ hTrans[token] = [eState, output];
70
+ }
71
+ debug('hTransitions', this.hTransitions);
72
+ this.curState = 'start';
73
+ debug("return from FSA()");
74
+ }
75
+
76
+ // ..........................................................
77
+ fixToken(token) {
78
+ var lMatches;
79
+ if (lMatches = token.match(/^\'(.*)\'$/)) {
80
+ return lMatches[1];
81
+ } else if (lMatches = token.match(/^\"(.*)\"$/)) {
82
+ return lMatches[1];
83
+ } else {
84
+ return token;
85
+ }
86
+ }
87
+
88
+ // ..........................................................
89
+ got(token) {
90
+ var hTrans, newState, output, result;
91
+ // --- returns pair [newState, output]
92
+ hTrans = this.hTransitions[this.curState];
93
+ if (notdefined(hTrans)) {
94
+ return [undef, undef];
95
+ }
96
+ result = hTrans[token];
97
+ if (notdefined(result)) {
98
+ return [undef, undef];
99
+ }
100
+ [newState, output] = result;
101
+ assert(nonEmpty(newState), `Failed: ${this.curState} -> ${token}`);
102
+ this.curState = newState;
103
+ return result;
104
+ }
105
+
106
+ // ..........................................................
107
+ state() {
108
+ return this.curState;
109
+ }
110
+
111
+ };
@@ -173,7 +173,10 @@ export logItem = (label, item, pre='', itemPre=undef) ->
173
173
  LOG "pre = #{OL(pre)}"
174
174
  LOG "itemPre = #{OL(itemPre)}"
175
175
 
176
- labelStr = if label then "#{label} = " else ""
176
+ if label
177
+ labelStr = "#{label} = "
178
+ else
179
+ labelStr = ""
177
180
 
178
181
  if (item == undef)
179
182
  putstr "#{pre}#{labelStr}undef"
package/src/log_utils.js CHANGED
@@ -198,7 +198,11 @@ export var logItem = function(label, item, pre = '', itemPre = undef) {
198
198
  LOG(`pre = ${OL(pre)}`);
199
199
  LOG(`itemPre = ${OL(itemPre)}`);
200
200
  }
201
- labelStr = label ? `${label} = ` : "";
201
+ if (label) {
202
+ labelStr = `${label} = `;
203
+ } else {
204
+ labelStr = "";
205
+ }
202
206
  if (item === undef) {
203
207
  putstr(`${pre}${labelStr}undef`);
204
208
  } else if (item === null) {