@jdeighan/coffee-utils 7.0.60 → 7.0.63

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": "7.0.60",
4
+ "version": "7.0.63",
5
5
  "description": "A set of utility functions for CoffeeScript",
6
6
  "main": "coffee_utils.js",
7
7
  "exports": {
package/src/arrow.coffee CHANGED
@@ -1,6 +1,6 @@
1
1
  # arrow.coffee
2
2
 
3
- import {undef, OL, setCharsAt} from '@jdeighan/coffee-utils'
3
+ import {undef, assert, OL, setCharsAt} from '@jdeighan/coffee-utils'
4
4
 
5
5
  # --- We use spaces here because Windows Terminal handles TAB chars badly
6
6
 
@@ -16,50 +16,41 @@ export clearIndent = space + space + space + space
16
16
 
17
17
  # ---------------------------------------------------------------------------
18
18
 
19
- export getPrefix = (level, option='none') ->
19
+ export prefix = (level, option='none') ->
20
20
 
21
- if level==0
22
- if (option == 'object')
23
- return clearIndent
24
- else
25
- return ''
26
21
  switch option
27
22
  when 'withArrow'
28
- result = oneIndent.repeat(level-1) + arrow
29
- when 'object'
30
- result = oneIndent.repeat(level) + clearIndent
31
- when 'none'
32
- result = oneIndent.repeat(level)
23
+ if (level == 0)
24
+ return arrow
25
+ else
26
+ return oneIndent.repeat(level-1) + arrow
27
+ when 'noLastVbar'
28
+ assert (level >= 1), "prefix(), noLastVbar but level=#{OL(level)}"
29
+ return oneIndent.repeat(level-1) + clearIndent
30
+ when 'noLast2Vbars'
31
+ assert (level >= 2), "prefix(), noLast2Vbars but level=#{OL(level)}"
32
+ return oneIndent.repeat(level-2) + clearIndent + clearIndent
33
33
  else
34
- throw new Error("getPrefix(): Bad option: '#{option}'")
35
- if result.length % 4 != 0
36
- throw new Error("getPrefix(): Bad prefix '#{result}'")
37
- return result
34
+ return oneIndent.repeat(level)
38
35
 
39
36
  # ---------------------------------------------------------------------------
40
37
 
41
38
  export addArrow = (prefix) ->
42
39
 
43
- # console.log "in addArrow(#{OL(prefix)})"
44
40
  pos = prefix.lastIndexOf(vbar)
45
- # console.log "pos = #{pos}"
46
41
  if (pos == -1)
47
42
  result = prefix
48
43
  else
49
44
  result = setCharsAt(prefix, pos, arrow)
50
- # console.log "result = #{OL(result)}"
51
45
  return result
52
46
 
53
47
  # ---------------------------------------------------------------------------
54
48
 
55
49
  export removeLastVbar = (prefix) ->
56
50
 
57
- # console.log "in removeLastVbar(#{OL(prefix)})"
58
51
  pos = prefix.lastIndexOf(vbar)
59
- # console.log "pos = #{pos}"
60
52
  if (pos == -1)
61
53
  result = prefix
62
54
  else
63
55
  result = setCharsAt(prefix, pos, ' ')
64
- # console.log "result = #{OL(result)}"
65
56
  return result
package/src/arrow.js CHANGED
@@ -2,6 +2,7 @@
2
2
  // arrow.coffee
3
3
  import {
4
4
  undef,
5
+ assert,
5
6
  OL,
6
7
  setCharsAt
7
8
  } from '@jdeighan/coffee-utils';
@@ -24,60 +25,46 @@ export var arrow = corner + hbar + arrowhead + space;
24
25
  export var clearIndent = space + space + space + space;
25
26
 
26
27
  // ---------------------------------------------------------------------------
27
- export var getPrefix = function(level, option = 'none') {
28
- var result;
29
- if (level === 0) {
30
- if (option === 'object') {
31
- return clearIndent;
32
- } else {
33
- return '';
34
- }
35
- }
28
+ export var prefix = function(level, option = 'none') {
36
29
  switch (option) {
37
30
  case 'withArrow':
38
- result = oneIndent.repeat(level - 1) + arrow;
39
- break;
40
- case 'object':
41
- result = oneIndent.repeat(level) + clearIndent;
42
- break;
43
- case 'none':
44
- result = oneIndent.repeat(level);
31
+ if (level === 0) {
32
+ return arrow;
33
+ } else {
34
+ return oneIndent.repeat(level - 1) + arrow;
35
+ }
45
36
  break;
37
+ case 'noLastVbar':
38
+ assert(level >= 1, `prefix(), noLastVbar but level=${OL(level)}`);
39
+ return oneIndent.repeat(level - 1) + clearIndent;
40
+ case 'noLast2Vbars':
41
+ assert(level >= 2, `prefix(), noLast2Vbars but level=${OL(level)}`);
42
+ return oneIndent.repeat(level - 2) + clearIndent + clearIndent;
46
43
  default:
47
- throw new Error(`getPrefix(): Bad option: '${option}'`);
44
+ return oneIndent.repeat(level);
48
45
  }
49
- if (result.length % 4 !== 0) {
50
- throw new Error(`getPrefix(): Bad prefix '${result}'`);
51
- }
52
- return result;
53
46
  };
54
47
 
55
48
  // ---------------------------------------------------------------------------
56
49
  export var addArrow = function(prefix) {
57
50
  var pos, result;
58
- // console.log "in addArrow(#{OL(prefix)})"
59
51
  pos = prefix.lastIndexOf(vbar);
60
- // console.log "pos = #{pos}"
61
52
  if (pos === -1) {
62
53
  result = prefix;
63
54
  } else {
64
55
  result = setCharsAt(prefix, pos, arrow);
65
56
  }
66
- // console.log "result = #{OL(result)}"
67
57
  return result;
68
58
  };
69
59
 
70
60
  // ---------------------------------------------------------------------------
71
61
  export var removeLastVbar = function(prefix) {
72
62
  var pos, result;
73
- // console.log "in removeLastVbar(#{OL(prefix)})"
74
63
  pos = prefix.lastIndexOf(vbar);
75
- // console.log "pos = #{pos}"
76
64
  if (pos === -1) {
77
65
  result = prefix;
78
66
  } else {
79
67
  result = setCharsAt(prefix, pos, ' ');
80
68
  }
81
- // console.log "result = #{OL(result)}"
82
69
  return result;
83
70
  };
@@ -1,10 +1,10 @@
1
1
  # call_stack.coffee
2
2
 
3
3
  import {
4
- undef, defined, croak, assert, OL, isBoolean, escapeStr, deepCopy,
4
+ undef, defined, croak, assert, OL, escapeStr, deepCopy,
5
+ isArray, isBoolean,
5
6
  } from '@jdeighan/coffee-utils'
6
- import {log, LOG} from '@jdeighan/coffee-utils/log'
7
- import {getPrefix} from '@jdeighan/coffee-utils/arrow'
7
+ import {LOG} from '@jdeighan/coffee-utils/log'
8
8
 
9
9
  doDebugStack = false
10
10
 
@@ -22,7 +22,6 @@ export class CallStack
22
22
  constructor: () ->
23
23
 
24
24
  @lStack = []
25
- @level = 0
26
25
 
27
26
  # ........................................................................
28
27
 
@@ -31,14 +30,16 @@ export class CallStack
31
30
  if doDebugStack
32
31
  LOG "RESET STACK"
33
32
  @lStack = []
34
- @level = 0
35
33
  return
36
34
 
37
35
  # ........................................................................
38
36
 
39
- enter: (funcName, lArgs=[]) ->
37
+ enter: (funcName, lArgs=[], isLogged) ->
40
38
  # --- funcName might be <object>.<method>
41
39
 
40
+ assert isArray(lArgs), "missing lArgs"
41
+ assert isBoolean(isLogged), "missing isLogged"
42
+
42
43
  if doDebugStack
43
44
  LOG "[--> ENTER #{funcName}]"
44
45
 
@@ -52,26 +53,31 @@ export class CallStack
52
53
  assert defined(lMatches), "Bad funcName: #{OL(funcName)}"
53
54
  [_, ident1, ident2] = lMatches
54
55
  if ident2
55
- @lStack.push({
56
+ hStackItem = {
56
57
  fullName: funcName # "#{ident1}.#{ident2}"
57
58
  funcName: ident2
58
- isLogged: false
59
+ isLogged
59
60
  lArgs: deepCopy(lArgs)
60
- })
61
+ }
61
62
  else
62
- @lStack.push({
63
+ hStackItem = {
63
64
  fullName: funcName
64
65
  funcName: ident1
65
- isLogged: false
66
+ isLogged
66
67
  lArgs: deepCopy(lArgs)
67
- })
68
- return
68
+ }
69
+ @lStack.push hStackItem
70
+ return hStackItem
69
71
 
70
72
  # ........................................................................
71
73
 
72
74
  getLevel: () ->
73
75
 
74
- return @level
76
+ level = 0
77
+ for item in @lStack
78
+ if item.isLogged
79
+ level += 1
80
+ return level
75
81
 
76
82
  # ........................................................................
77
83
 
@@ -82,32 +88,6 @@ export class CallStack
82
88
  else
83
89
  return @lStack[@lStack.length - 1].isLogged
84
90
 
85
- # ........................................................................
86
-
87
- isLoggingPrev: () ->
88
-
89
- if (@lStack.length < 2)
90
- return false
91
- else
92
- return @lStack[@lStack.length - 2].isLogged
93
-
94
- # ........................................................................
95
-
96
- logCurFunc: (funcName) ->
97
-
98
- # --- funcName must be the current function
99
- # and the isLogged flag must currently be false
100
-
101
- cur = @lStack[@lStack.length - 1]
102
- assert (cur.isLogged == false), "isLogged is already true"
103
- if (funcName != cur.fullName)
104
- LOG "cur func #{cur.fullName} is not #{funcName}"
105
- LOG @dump()
106
- croak "BAD"
107
- cur.isLogged = true
108
- @level += 1
109
- return
110
-
111
91
  # ........................................................................
112
92
  # --- if stack is empty, log the error, but continue
113
93
 
@@ -121,19 +101,10 @@ export class CallStack
121
101
  return
122
102
 
123
103
  {fullName, isLogged} = @lStack.pop()
124
- if isLogged && (@level > 0)
125
- @level -= 1
126
-
127
- # --- This should do nothing
128
- while (fullName != fName) && (@lStack.length > 0)
129
- LOG "[MISSING RETURN FROM #{fullName} (return from #{fName})]"
130
- {fullName, isLogged} = @lStack.pop()
131
- if isLogged && (@level > 0)
132
- @level -= 1
133
-
134
- if fullName != fName
135
- @dump()
136
- LOG "BAD BAD BAD BAD returnFrom('#{fName}')"
104
+ if (fullName != fName)
105
+ LOG "ERROR: returnFrom('#{fName}') but TOS is #{fullName}"
106
+ return
107
+
137
108
  return
138
109
 
139
110
  # ........................................................................
@@ -158,9 +129,9 @@ export class CallStack
158
129
 
159
130
  # ........................................................................
160
131
 
161
- dump: () ->
132
+ dump: (label="CALL STACK") ->
162
133
 
163
- lLines = ["CALL STACK:"]
134
+ lLines = [label]
164
135
  if @lStack.length == 0
165
136
  lLines.push " <EMPTY>"
166
137
  else
@@ -172,8 +143,8 @@ export class CallStack
172
143
 
173
144
  callStr: (i, item) ->
174
145
 
175
- sym = if item.isLogged then '*' else ''
176
- str = "#{i}#{sym}: #{item.fullName}"
146
+ sym = if item.isLogged then '*' else '-'
147
+ str = "#{i}: #{sym}#{item.fullName}"
177
148
  for arg in item.lArgs
178
149
  str += " #{OL(arg)}"
179
150
  return str
package/src/call_stack.js CHANGED
@@ -8,20 +8,16 @@ import {
8
8
  croak,
9
9
  assert,
10
10
  OL,
11
- isBoolean,
12
11
  escapeStr,
13
- deepCopy
12
+ deepCopy,
13
+ isArray,
14
+ isBoolean
14
15
  } from '@jdeighan/coffee-utils';
15
16
 
16
17
  import {
17
- log,
18
18
  LOG
19
19
  } from '@jdeighan/coffee-utils/log';
20
20
 
21
- import {
22
- getPrefix
23
- } from '@jdeighan/coffee-utils/arrow';
24
-
25
21
  doDebugStack = false;
26
22
 
27
23
  // ---------------------------------------------------------------------------
@@ -33,7 +29,6 @@ export var debugStack = function(flag = true) {
33
29
  export var CallStack = class CallStack {
34
30
  constructor() {
35
31
  this.lStack = [];
36
- this.level = 0;
37
32
  }
38
33
 
39
34
  // ........................................................................
@@ -42,13 +37,14 @@ export var CallStack = class CallStack {
42
37
  LOG("RESET STACK");
43
38
  }
44
39
  this.lStack = [];
45
- this.level = 0;
46
40
  }
47
41
 
48
42
  // ........................................................................
49
- enter(funcName, lArgs = []) {
50
- var _, ident1, ident2, lMatches;
43
+ enter(funcName, lArgs = [], isLogged) {
44
+ var _, hStackItem, ident1, ident2, lMatches;
51
45
  // --- funcName might be <object>.<method>
46
+ assert(isArray(lArgs), "missing lArgs");
47
+ assert(isBoolean(isLogged), "missing isLogged");
52
48
  if (doDebugStack) {
53
49
  LOG(`[--> ENTER ${funcName}]`);
54
50
  }
@@ -56,25 +52,36 @@ export var CallStack = class CallStack {
56
52
  assert(defined(lMatches), `Bad funcName: ${OL(funcName)}`);
57
53
  [_, ident1, ident2] = lMatches;
58
54
  if (ident2) {
59
- this.lStack.push({
55
+ hStackItem = {
60
56
  fullName: funcName, // "#{ident1}.#{ident2}"
61
57
  funcName: ident2,
62
- isLogged: false,
58
+ isLogged,
63
59
  lArgs: deepCopy(lArgs)
64
- });
60
+ };
65
61
  } else {
66
- this.lStack.push({
62
+ hStackItem = {
67
63
  fullName: funcName,
68
64
  funcName: ident1,
69
- isLogged: false,
65
+ isLogged,
70
66
  lArgs: deepCopy(lArgs)
71
- });
67
+ };
72
68
  }
69
+ this.lStack.push(hStackItem);
70
+ return hStackItem;
73
71
  }
74
72
 
75
73
  // ........................................................................
76
74
  getLevel() {
77
- return this.level;
75
+ var item, j, len, level, ref;
76
+ level = 0;
77
+ ref = this.lStack;
78
+ for (j = 0, len = ref.length; j < len; j++) {
79
+ item = ref[j];
80
+ if (item.isLogged) {
81
+ level += 1;
82
+ }
83
+ }
84
+ return level;
78
85
  }
79
86
 
80
87
  // ........................................................................
@@ -86,31 +93,6 @@ export var CallStack = class CallStack {
86
93
  }
87
94
  }
88
95
 
89
- // ........................................................................
90
- isLoggingPrev() {
91
- if (this.lStack.length < 2) {
92
- return false;
93
- } else {
94
- return this.lStack[this.lStack.length - 2].isLogged;
95
- }
96
- }
97
-
98
- // ........................................................................
99
- logCurFunc(funcName) {
100
- var cur;
101
- // --- funcName must be the current function
102
- // and the isLogged flag must currently be false
103
- cur = this.lStack[this.lStack.length - 1];
104
- assert(cur.isLogged === false, "isLogged is already true");
105
- if (funcName !== cur.fullName) {
106
- LOG(`cur func ${cur.fullName} is not ${funcName}`);
107
- LOG(this.dump());
108
- croak("BAD");
109
- }
110
- cur.isLogged = true;
111
- this.level += 1;
112
- }
113
-
114
96
  // ........................................................................
115
97
  // --- if stack is empty, log the error, but continue
116
98
  returnFrom(fName) {
@@ -123,20 +105,9 @@ export var CallStack = class CallStack {
123
105
  return;
124
106
  }
125
107
  ({fullName, isLogged} = this.lStack.pop());
126
- if (isLogged && (this.level > 0)) {
127
- this.level -= 1;
128
- }
129
- // --- This should do nothing
130
- while ((fullName !== fName) && (this.lStack.length > 0)) {
131
- LOG(`[MISSING RETURN FROM ${fullName} (return from ${fName})]`);
132
- ({fullName, isLogged} = this.lStack.pop());
133
- if (isLogged && (this.level > 0)) {
134
- this.level -= 1;
135
- }
136
- }
137
108
  if (fullName !== fName) {
138
- this.dump();
139
- LOG(`BAD BAD BAD BAD returnFrom('${fName}')`);
109
+ LOG(`ERROR: returnFrom('${fName}') but TOS is ${fullName}`);
110
+ return;
140
111
  }
141
112
  }
142
113
 
@@ -165,9 +136,9 @@ export var CallStack = class CallStack {
165
136
  }
166
137
 
167
138
  // ........................................................................
168
- dump() {
139
+ dump(label = "CALL STACK") {
169
140
  var i, item, j, lLines, len, ref;
170
- lLines = ["CALL STACK:"];
141
+ lLines = [label];
171
142
  if (this.lStack.length === 0) {
172
143
  lLines.push(" <EMPTY>");
173
144
  } else {
@@ -183,8 +154,8 @@ export var CallStack = class CallStack {
183
154
  // ........................................................................
184
155
  callStr(i, item) {
185
156
  var arg, j, len, ref, str, sym;
186
- sym = item.isLogged ? '*' : '';
187
- str = `${i}${sym}: ${item.fullName}`;
157
+ sym = item.isLogged ? '*' : '-';
158
+ str = `${i}: ${sym}${item.fullName}`;
188
159
  ref = item.lArgs;
189
160
  for (j = 0, len = ref.length; j < len; j++) {
190
161
  arg = ref[j];
@@ -21,6 +21,13 @@ export isComment = (line) ->
21
21
 
22
22
  # ---------------------------------------------------------------------------
23
23
 
24
+ export eval_expr = (str) ->
25
+
26
+ str = str.replace(/\bundef\b/g, 'undefined')
27
+ return Function('"use strict";return (' + str + ')')();
28
+
29
+ # ---------------------------------------------------------------------------
30
+
24
31
  export haltOnError = () ->
25
32
 
26
33
  doHaltOnError = true
@@ -73,17 +80,11 @@ getCallers = (stackTrace, lExclude=[]) ->
73
80
  export assert = (cond, msg) ->
74
81
 
75
82
  if ! cond
76
- # try
77
- # throw new Error()
78
- # catch e
79
- # stackTrace = e.stack
80
83
  stackTrace = new Error().stack
81
84
  lCallers = getCallers(stackTrace, ['assert'])
82
85
 
83
- # console.log 'STACK'
84
- # console.log stackTrace
85
86
  console.log '--------------------'
86
- console.log 'CALL STACK:'
87
+ console.log 'JavaScript CALL STACK:'
87
88
  for caller in lCallers
88
89
  console.log " #{caller}"
89
90
  console.log '--------------------'
@@ -118,6 +119,16 @@ export getClassName = (obj) ->
118
119
 
119
120
  # ---------------------------------------------------------------------------
120
121
 
122
+ export patchStr = (bigstr, pos, str) ->
123
+
124
+ endpos = pos + str.length
125
+ if (endpos < bigstr.length)
126
+ return bigstr.substring(0, pos) + str + bigstr.substring(endpos)
127
+ else
128
+ return bigstr.substring(0, pos) + str
129
+
130
+ # ---------------------------------------------------------------------------
131
+
121
132
  export isString = (x) ->
122
133
 
123
134
  return typeof x == 'string' || x instanceof String
@@ -23,6 +23,12 @@ export var isComment = function(line) {
23
23
  return defined(lMatches);
24
24
  };
25
25
 
26
+ // ---------------------------------------------------------------------------
27
+ export var eval_expr = function(str) {
28
+ str = str.replace(/\bundef\b/g, 'undefined');
29
+ return Function('"use strict";return (' + str + ')')();
30
+ };
31
+
26
32
  // ---------------------------------------------------------------------------
27
33
  export var haltOnError = function() {
28
34
  return doHaltOnError = true;
@@ -68,16 +74,10 @@ getCallers = function(stackTrace, lExclude = []) {
68
74
  export var assert = function(cond, msg) {
69
75
  var caller, i, lCallers, len, stackTrace;
70
76
  if (!cond) {
71
- // try
72
- // throw new Error()
73
- // catch e
74
- // stackTrace = e.stack
75
77
  stackTrace = new Error().stack;
76
78
  lCallers = getCallers(stackTrace, ['assert']);
77
- // console.log 'STACK'
78
- // console.log stackTrace
79
79
  console.log('--------------------');
80
- console.log('CALL STACK:');
80
+ console.log('JavaScript CALL STACK:');
81
81
  for (i = 0, len = lCallers.length; i < len; i++) {
82
82
  caller = lCallers[i];
83
83
  console.log(` ${caller}`);
@@ -112,6 +112,17 @@ export var getClassName = function(obj) {
112
112
  return obj.constructor.name;
113
113
  };
114
114
 
115
+ // ---------------------------------------------------------------------------
116
+ export var patchStr = function(bigstr, pos, str) {
117
+ var endpos;
118
+ endpos = pos + str.length;
119
+ if (endpos < bigstr.length) {
120
+ return bigstr.substring(0, pos) + str + bigstr.substring(endpos);
121
+ } else {
122
+ return bigstr.substring(0, pos) + str;
123
+ }
124
+ };
125
+
115
126
  // ---------------------------------------------------------------------------
116
127
  export var isString = function(x) {
117
128
  return typeof x === 'string' || x instanceof String;