@jdeighan/coffee-utils 10.0.10 → 10.0.13

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.10",
4
+ "version": "10.0.13",
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,6 +6,7 @@ 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
  # ---------------------------------------------------------------------------
@@ -18,7 +18,8 @@ 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
  // ---------------------------------------------------------------------------
@@ -61,6 +61,12 @@ export charCount = (str, ch) ->
61
61
 
62
62
  # ---------------------------------------------------------------------------
63
63
 
64
+ export oneof = (word, lWords...) ->
65
+
66
+ return (lWords.indexOf(word) >= 0)
67
+
68
+ # ---------------------------------------------------------------------------
69
+
64
70
  export isConstructor = (f) ->
65
71
 
66
72
  try
@@ -241,7 +247,10 @@ export pushCond = (lItems, item, doPush=notInArray) ->
241
247
 
242
248
  export words = (str) ->
243
249
 
244
- return str.trim().split(/\s+/)
250
+ str = str.trim()
251
+ if (str == '')
252
+ return []
253
+ return str.split(/\s+/)
245
254
 
246
255
  # ---------------------------------------------------------------------------
247
256
 
@@ -65,6 +65,11 @@ export var charCount = function(str, ch) {
65
65
  return count;
66
66
  };
67
67
 
68
+ // ---------------------------------------------------------------------------
69
+ export var oneof = function(word, ...lWords) {
70
+ return lWords.indexOf(word) >= 0;
71
+ };
72
+
68
73
  // ---------------------------------------------------------------------------
69
74
  export var isConstructor = function(f) {
70
75
  var err;
@@ -253,7 +258,11 @@ export var pushCond = function(lItems, item, doPush = notInArray) {
253
258
 
254
259
  // ---------------------------------------------------------------------------
255
260
  export var words = function(str) {
256
- return str.trim().split(/\s+/);
261
+ str = str.trim();
262
+ if (str === '') {
263
+ return [];
264
+ }
265
+ return str.split(/\s+/);
257
266
  };
258
267
 
259
268
  // ---------------------------------------------------------------------------
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) {