circuitscript 0.1.13 → 0.1.15

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.
@@ -48,7 +48,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
48
48
  }
49
49
  const result = this.runExpressions(this.getExecutor(), ctx.expression());
50
50
  this.setResult(ctx, result);
51
- this.getExecutor().closeAllBlocks();
51
+ this.getExecutor().closeOpenPathBlocks();
52
52
  this.log('===', 'end', '===');
53
53
  };
54
54
  this.visitAssignment_expr = (ctx) => {
@@ -669,7 +669,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
669
669
  const executionLevel = currentExecutionContext.executionLevel;
670
670
  const executionContextNamespace = currentExecutionContext.namespace
671
671
  + executionContextName + ".";
672
- const newExecutor = new execute_js_1.ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
672
+ const newExecutor = new execute_js_1.ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.scopeLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
673
673
  executionStack.push(newExecutor);
674
674
  this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
675
675
  return newExecutor;
@@ -15,7 +15,7 @@ const helpers_js_1 = require("./helpers.js");
15
15
  const draw_symbols_js_1 = require("./draw_symbols.js");
16
16
  const utils_js_1 = require("./utils.js");
17
17
  class ExecutionContext {
18
- constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, warnings, parent) {
18
+ constructor(name, namespace, netNamespace, executionLevel = 0, scopeLevel = 0, silent = false, logger, warnings, parent) {
19
19
  this.tmpPointId = 0;
20
20
  this.resolveNet = null;
21
21
  this.stopFurtherExpressions = false;
@@ -30,10 +30,10 @@ class ExecutionContext {
30
30
  this.executionLevel = executionLevel;
31
31
  this.logger = logger;
32
32
  this.scope = ExecutionScope_js_1.ExecutionScope.create();
33
- this.scope.indentLevel = indentLevel;
33
+ this.scope.scopeLevel = scopeLevel;
34
34
  this.setupRoot();
35
35
  this.silent = silent;
36
- this.log('create new execution context', this.namespace, this.name, this.scope.indentLevel);
36
+ this.log('create new execution context', this.namespace, this.name, this.scope.scopeLevel);
37
37
  this.parentContext = parent;
38
38
  this.warnings = warnings;
39
39
  }
@@ -45,8 +45,8 @@ class ExecutionContext {
45
45
  });
46
46
  }
47
47
  log(...params) {
48
- const indentOutput = ''.padStart(this.scope.indentLevel * 4, ' ');
49
- const indentLevelText = this.scope.indentLevel
48
+ const indentOutput = ''.padStart(this.scope.scopeLevel * 4, ' ');
49
+ const indentLevelText = this.scope.scopeLevel
50
50
  .toString()
51
51
  .padStart(3, ' ');
52
52
  const args = ['[' + indentLevelText + ']', indentOutput, ...params];
@@ -398,7 +398,7 @@ class ExecutionContext {
398
398
  this.addPoint(`${globals_js_1.Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
399
399
  this.tmpPointId += 1;
400
400
  }
401
- this.scope.blockStack.set(this.scope.indentLevel, {
401
+ this.scope.blockStack.set(this.scope.scopeLevel, {
402
402
  start_point: [
403
403
  this.scope.currentComponent,
404
404
  this.scope.currentPin,
@@ -411,8 +411,11 @@ class ExecutionContext {
411
411
  });
412
412
  this.log('enter blocks');
413
413
  }
414
- exitBlocks() {
415
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
414
+ exitBlocks(scopeLevel = null) {
415
+ if (scopeLevel === null) {
416
+ scopeLevel = this.scope.scopeLevel;
417
+ }
418
+ const stackRef = this.scope.blockStack.get(scopeLevel);
416
419
  const { type: blockType } = stackRef;
417
420
  if (blockType === globals_js_1.BlockTypes.Join || blockType === globals_js_1.BlockTypes.Parallel) {
418
421
  const { end_point: finalPoint } = stackRef;
@@ -429,16 +432,18 @@ class ExecutionContext {
429
432
  const { start_point: [component, pin,] } = stackRef;
430
433
  this.atComponent(component, pin, { addSequence: true });
431
434
  }
432
- this.scope.blockStack.delete(this.scope.indentLevel);
435
+ this.scope.blockStack.delete(scopeLevel);
433
436
  this.log('exit blocks');
434
437
  }
435
- closeAllBlocks() {
436
- if (this.scope.blockStack.has(this.scope.indentLevel)) {
438
+ closeOpenPathBlocks() {
439
+ const scope = this.scope;
440
+ const scopeLevel = scope.scopeLevel;
441
+ if (scope.blockStack.has(scopeLevel)) {
437
442
  this.exitBlocks();
438
443
  }
439
444
  }
440
445
  enterBlock(blockIndex) {
441
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
446
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel);
442
447
  const { type: blockType } = stackRef;
443
448
  const blockTypeName = (0, utils_js_1.getBlockTypeString)(blockType);
444
449
  stackRef.inner_blocks.set(blockIndex, {
@@ -454,10 +459,10 @@ class ExecutionContext {
454
459
  this.atComponent(component, pin, { addSequence: true });
455
460
  }
456
461
  this.log(`enter inner block of type (${blockTypeName}) >>>`);
457
- this.scope.indentLevel += 1;
462
+ this.scope.scopeLevel += 1;
458
463
  }
459
464
  exitBlock(blockIndex) {
460
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1);
465
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1);
461
466
  const { type: blockType } = stackRef;
462
467
  const blockIndexRef = stackRef.inner_blocks.get(blockIndex);
463
468
  blockIndexRef.last_net = [
@@ -465,7 +470,7 @@ class ExecutionContext {
465
470
  this.scope.currentPin,
466
471
  this.scope.currentWireId
467
472
  ];
468
- this.scope.indentLevel -= 1;
473
+ this.scope.scopeLevel -= 1;
469
474
  this.log('exit inner block <<<');
470
475
  if (blockType === globals_js_1.BlockTypes.Branch) {
471
476
  const { start_point: [component, pin, wireId] } = stackRef;
@@ -506,8 +511,8 @@ class ExecutionContext {
506
511
  }
507
512
  getPointBlockLocation() {
508
513
  this.log('get block point');
509
- for (let i = 0; i < this.scope.indentLevel; i++) {
510
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
514
+ for (let i = 0; i < this.scope.scopeLevel; i++) {
515
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1 - i);
511
516
  const { start_point } = stackRef;
512
517
  const component = start_point[0];
513
518
  if (component.instanceName.startsWith(`${globals_js_1.Delimiter1}point.`)) {
@@ -416,9 +416,28 @@ class Geometry {
416
416
  [segment.end.x, segment.end.y]
417
417
  ];
418
418
  });
419
+ const lines = [];
420
+ let prevPoint;
421
+ let currentLine = [];
422
+ segments.forEach((segment, index) => {
423
+ const [pt1, pt2] = segment;
424
+ if (index === 0 || (prevPoint[0] !== pt1[0] || prevPoint[1] !== pt1[1])) {
425
+ if (currentLine.length > 0) {
426
+ lines.push(currentLine);
427
+ currentLine = [];
428
+ }
429
+ currentLine.push([pt1[0], pt1[1]]);
430
+ }
431
+ currentLine.push(pt2);
432
+ prevPoint = pt2;
433
+ });
434
+ if (currentLine.length > 0) {
435
+ lines.push(currentLine);
436
+ }
419
437
  return {
420
438
  intersectPoints,
421
439
  segments,
440
+ lines,
422
441
  };
423
442
  }
424
443
  }
@@ -106,8 +106,10 @@ var BlockTypes;
106
106
  var NetGraphicsParams;
107
107
  (function (NetGraphicsParams) {
108
108
  NetGraphicsParams["Color"] = "color";
109
- NetGraphicsParams["Highight"] = "highlight";
110
109
  NetGraphicsParams["LineWidth"] = "lineWidth";
110
+ NetGraphicsParams["Highlight"] = "highlight";
111
+ NetGraphicsParams["HighlightWidth"] = "highlightWidth";
112
+ NetGraphicsParams["HighlightOpacity"] = "highlightOpacity";
111
113
  })(NetGraphicsParams || (exports.NetGraphicsParams = NetGraphicsParams = {}));
112
114
  var FrameType;
113
115
  (function (FrameType) {
@@ -137,8 +137,19 @@ class LayoutEngine {
137
137
  const value = net.params.get(globals_js_1.NetGraphicsParams.LineWidth);
138
138
  renderNet.lineWidth = (0, helpers_js_1.milsToMM)(value).toNumber();
139
139
  }
140
- if (net.params.has(globals_js_1.NetGraphicsParams.Highight)) {
141
- renderNet.highlight = net.params.get(globals_js_1.NetGraphicsParams.Highight);
140
+ if (net.params.has(globals_js_1.NetGraphicsParams.Highlight)) {
141
+ renderNet.highlight =
142
+ net.params.get(globals_js_1.NetGraphicsParams.Highlight);
143
+ }
144
+ if (net.params.has(globals_js_1.NetGraphicsParams.HighlightWidth)) {
145
+ renderNet.highlightWidth =
146
+ (0, helpers_js_1.milsToMM)(net.params.get(globals_js_1.NetGraphicsParams.HighlightWidth))
147
+ .toNumber();
148
+ }
149
+ if (net.params.has(globals_js_1.NetGraphicsParams.HighlightOpacity)) {
150
+ renderNet.highlightOpacity =
151
+ net.params.get(globals_js_1.NetGraphicsParams.HighlightOpacity)
152
+ .toNumber();
142
153
  }
143
154
  renderNets.set(net.toString(), renderNet);
144
155
  });
@@ -192,12 +203,13 @@ class LayoutEngine {
192
203
  });
193
204
  }
194
205
  else {
195
- const { intersectPoints, segments } = geometry_js_1.Geometry.mergeWires(allLines);
206
+ const { intersectPoints, segments, lines } = geometry_js_1.Geometry.mergeWires(allLines);
196
207
  mergedWires.push({
197
208
  netName: netName,
198
209
  segments,
199
210
  intersectPoints,
200
211
  net: renderNet,
212
+ lines,
201
213
  });
202
214
  intersectPoints.forEach(([x, y]) => {
203
215
  junctions.push(new RenderJunction((0, ParamDefinition_js_1.numeric)(x), (0, ParamDefinition_js_1.numeric)(y), renderNet));
@@ -15,7 +15,7 @@ class ExecutionScope {
15
15
  this.breakStack = [];
16
16
  this.wires = [];
17
17
  this.frames = [];
18
- this.indentLevel = 0;
18
+ this.scopeLevel = 0;
19
19
  this.netCounter = 1;
20
20
  this.unnamedCounter = 1;
21
21
  this.currentComponent = null;
@@ -181,12 +181,14 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
181
181
  const mergedWireHighlightGroup = canvas.group();
182
182
  const mergedWireGroup = canvas.group();
183
183
  mergedWires.forEach(tmpItem => {
184
- const { segments, intersectPoints, net = null } = tmpItem;
184
+ const { intersectPoints, net = null, lines = null } = tmpItem;
185
185
  let useJunctionColor = globals_js_1.ColorScheme.JunctionColor;
186
186
  let useColor = globals_js_1.ColorScheme.WireColor;
187
187
  let useLineWidth = globals_js_1.defaultWireLineWidth;
188
188
  let displayHighlight = false;
189
189
  let displayHighlightColor = null;
190
+ let displayHighlightOpacity = 0.3;
191
+ let displayHighlightWidth = 5 * globals_js_1.MilsToMM;
190
192
  if (net !== null) {
191
193
  useColor = net.color ?? globals_js_1.ColorScheme.WireColor;
192
194
  useJunctionColor = net.color ?? globals_js_1.ColorScheme.JunctionColor;
@@ -194,25 +196,29 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
194
196
  if (net.highlight !== null) {
195
197
  displayHighlight = true;
196
198
  displayHighlightColor = net.highlight ?? null;
199
+ if (net.highlightOpacity !== undefined) {
200
+ displayHighlightOpacity = net.highlightOpacity;
201
+ }
202
+ if (net.highlightWidth !== undefined) {
203
+ displayHighlightWidth = net.highlightWidth;
204
+ }
197
205
  }
198
206
  }
199
207
  const pathItems = [];
200
- const highlightExtraSize = 5 * globals_js_1.MilsToMM;
201
- segments.forEach(segment => {
202
- const pt1 = segment[0];
203
- const pt2 = segment[1];
204
- pathItems.push(...[
205
- 'M', pt1[0], pt1[1],
206
- 'L', pt2[0], pt2[1]
207
- ]);
208
+ const useLines = lines ?? [];
209
+ useLines.forEach(line => {
210
+ line.forEach((point, index) => {
211
+ const commandType = (index === 0) ? 'M' : 'L';
212
+ pathItems.push(...[commandType, point[0], point[1]]);
213
+ });
208
214
  });
209
215
  if (displayHighlight) {
210
216
  mergedWireHighlightGroup.path(pathItems)
211
217
  .stroke({
212
- width: useLineWidth + highlightExtraSize,
218
+ width: useLineWidth + displayHighlightWidth,
213
219
  color: displayHighlightColor,
214
- opacity: 0.3,
215
- linecap: 'square'
220
+ opacity: displayHighlightOpacity,
221
+ linecap: 'butt'
216
222
  })
217
223
  .fill('none');
218
224
  }
@@ -220,11 +226,11 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
220
226
  .stroke({
221
227
  width: useLineWidth,
222
228
  color: useColor,
223
- linecap: 'square'
229
+ linecap: 'butt'
224
230
  })
225
231
  .fill('none');
226
232
  const halfJunctionSize = globals_js_1.junctionSize.half();
227
- const highlightJunctionSize = (0, ParamDefinition_js_1.numeric)(globals_js_1.junctionSize.toNumber() + highlightExtraSize);
233
+ const highlightJunctionSize = (0, ParamDefinition_js_1.numeric)(globals_js_1.junctionSize.toNumber() + displayHighlightWidth);
228
234
  const tmpHighlightExtraSize = highlightJunctionSize.half();
229
235
  intersectPoints.forEach(point => {
230
236
  const [x, y,] = point;
@@ -104,17 +104,17 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
104
104
  }
105
105
  const scope = this.getScope();
106
106
  const executor = this.getExecutor();
107
- const indentLevel = scope.indentLevel;
108
- if (scope.blockStack.has(indentLevel)) {
109
- const blockStackEntry = scope.blockStack.get(indentLevel);
107
+ const scopeLevel = scope.scopeLevel;
108
+ if (scope.blockStack.has(scopeLevel)) {
109
+ const blockStackEntry = scope.blockStack.get(scopeLevel);
110
110
  if (blockStackEntry.type !== blockType) {
111
111
  executor.exitBlocks();
112
112
  }
113
113
  }
114
- if (!scope.blockStack.has(indentLevel)) {
114
+ if (!scope.blockStack.has(scopeLevel)) {
115
115
  executor.enterBlocks(blockType);
116
116
  }
117
- const blockStackEntry = scope.blockStack.get(indentLevel);
117
+ const blockStackEntry = scope.blockStack.get(scopeLevel);
118
118
  const { current_index } = blockStackEntry;
119
119
  executor.enterBlock(current_index);
120
120
  this.visit(ctx.expressions_block());
@@ -122,12 +122,9 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
122
122
  blockStackEntry.current_index++;
123
123
  };
124
124
  this.visitGraph_expressions = (ctx) => {
125
+ this.getExecutor().log('graph expressions', this.getScope().scopeLevel);
125
126
  if (ctx.path_block() === null) {
126
- const scope = this.getScope();
127
- const indentLevel = scope.indentLevel;
128
- if (scope.blockStack.has(indentLevel)) {
129
- this.getExecutor().exitBlocks();
130
- }
127
+ this.getExecutor().closeOpenPathBlocks();
131
128
  }
132
129
  const ctxPathBlock = ctx.path_block();
133
130
  const ctxNotPathBlock = ctx.graph_linear_expression();
@@ -818,9 +815,10 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
818
815
  this.setResult(ctx, result);
819
816
  };
820
817
  this.visitAt_block_pin_expr = (ctx) => {
821
- const atPin = this.visitResult(ctx.pin_select_expr2());
822
818
  const executor = this.getExecutor();
823
819
  const [currentComponent, currentPin] = executor.getCurrentPoint();
820
+ executor.closeOpenPathBlocks();
821
+ const atPin = this.visitResult(ctx.pin_select_expr2());
824
822
  executor.atComponent(currentComponent, atPin, {
825
823
  addSequence: true
826
824
  });
@@ -841,11 +839,11 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
841
839
  executor.log('entering at block');
842
840
  this.visit(ctx.at_component_expr());
843
841
  const [currentComponent, currentPin] = executor.getCurrentPoint();
844
- executor.scope.indentLevel += 1;
842
+ executor.scope.scopeLevel += 1;
845
843
  ctx.at_block_expressions().forEach(expression => {
846
844
  this.visit(expression);
847
845
  });
848
- executor.scope.indentLevel -= 1;
846
+ executor.scope.scopeLevel -= 1;
849
847
  executor.scope.setCurrent(currentComponent, currentPin);
850
848
  executor.log('leaving at block');
851
849
  };
@@ -127,7 +127,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
127
127
  }
128
128
  const result = this.runExpressions(this.getExecutor(), ctx.expression());
129
129
  this.setResult(ctx, result);
130
- this.getExecutor().closeAllBlocks();
130
+ this.getExecutor().closeOpenPathBlocks();
131
131
  this.log('===', 'end', '===');
132
132
  };
133
133
  visitAssignment_expr = (ctx) => {
@@ -670,7 +670,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
670
670
  const executionLevel = currentExecutionContext.executionLevel;
671
671
  const executionContextNamespace = currentExecutionContext.namespace
672
672
  + executionContextName + ".";
673
- const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
673
+ const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.scopeLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
674
674
  executionStack.push(newExecutor);
675
675
  this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
676
676
  return newExecutor;
@@ -28,17 +28,17 @@ export class ExecutionContext {
28
28
  parentContext;
29
29
  componentAngleFollowsWire = true;
30
30
  warnings = [];
31
- constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, warnings, parent) {
31
+ constructor(name, namespace, netNamespace, executionLevel = 0, scopeLevel = 0, silent = false, logger, warnings, parent) {
32
32
  this.name = name;
33
33
  this.namespace = namespace;
34
34
  this.netNamespace = netNamespace;
35
35
  this.executionLevel = executionLevel;
36
36
  this.logger = logger;
37
37
  this.scope = ExecutionScope.create();
38
- this.scope.indentLevel = indentLevel;
38
+ this.scope.scopeLevel = scopeLevel;
39
39
  this.setupRoot();
40
40
  this.silent = silent;
41
- this.log('create new execution context', this.namespace, this.name, this.scope.indentLevel);
41
+ this.log('create new execution context', this.namespace, this.name, this.scope.scopeLevel);
42
42
  this.parentContext = parent;
43
43
  this.warnings = warnings;
44
44
  }
@@ -50,8 +50,8 @@ export class ExecutionContext {
50
50
  });
51
51
  }
52
52
  log(...params) {
53
- const indentOutput = ''.padStart(this.scope.indentLevel * 4, ' ');
54
- const indentLevelText = this.scope.indentLevel
53
+ const indentOutput = ''.padStart(this.scope.scopeLevel * 4, ' ');
54
+ const indentLevelText = this.scope.scopeLevel
55
55
  .toString()
56
56
  .padStart(3, ' ');
57
57
  const args = ['[' + indentLevelText + ']', indentOutput, ...params];
@@ -403,7 +403,7 @@ export class ExecutionContext {
403
403
  this.addPoint(`${Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
404
404
  this.tmpPointId += 1;
405
405
  }
406
- this.scope.blockStack.set(this.scope.indentLevel, {
406
+ this.scope.blockStack.set(this.scope.scopeLevel, {
407
407
  start_point: [
408
408
  this.scope.currentComponent,
409
409
  this.scope.currentPin,
@@ -416,8 +416,11 @@ export class ExecutionContext {
416
416
  });
417
417
  this.log('enter blocks');
418
418
  }
419
- exitBlocks() {
420
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
419
+ exitBlocks(scopeLevel = null) {
420
+ if (scopeLevel === null) {
421
+ scopeLevel = this.scope.scopeLevel;
422
+ }
423
+ const stackRef = this.scope.blockStack.get(scopeLevel);
421
424
  const { type: blockType } = stackRef;
422
425
  if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
423
426
  const { end_point: finalPoint } = stackRef;
@@ -434,16 +437,18 @@ export class ExecutionContext {
434
437
  const { start_point: [component, pin,] } = stackRef;
435
438
  this.atComponent(component, pin, { addSequence: true });
436
439
  }
437
- this.scope.blockStack.delete(this.scope.indentLevel);
440
+ this.scope.blockStack.delete(scopeLevel);
438
441
  this.log('exit blocks');
439
442
  }
440
- closeAllBlocks() {
441
- if (this.scope.blockStack.has(this.scope.indentLevel)) {
443
+ closeOpenPathBlocks() {
444
+ const scope = this.scope;
445
+ const scopeLevel = scope.scopeLevel;
446
+ if (scope.blockStack.has(scopeLevel)) {
442
447
  this.exitBlocks();
443
448
  }
444
449
  }
445
450
  enterBlock(blockIndex) {
446
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
451
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel);
447
452
  const { type: blockType } = stackRef;
448
453
  const blockTypeName = getBlockTypeString(blockType);
449
454
  stackRef.inner_blocks.set(blockIndex, {
@@ -459,10 +464,10 @@ export class ExecutionContext {
459
464
  this.atComponent(component, pin, { addSequence: true });
460
465
  }
461
466
  this.log(`enter inner block of type (${blockTypeName}) >>>`);
462
- this.scope.indentLevel += 1;
467
+ this.scope.scopeLevel += 1;
463
468
  }
464
469
  exitBlock(blockIndex) {
465
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1);
470
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1);
466
471
  const { type: blockType } = stackRef;
467
472
  const blockIndexRef = stackRef.inner_blocks.get(blockIndex);
468
473
  blockIndexRef.last_net = [
@@ -470,7 +475,7 @@ export class ExecutionContext {
470
475
  this.scope.currentPin,
471
476
  this.scope.currentWireId
472
477
  ];
473
- this.scope.indentLevel -= 1;
478
+ this.scope.scopeLevel -= 1;
474
479
  this.log('exit inner block <<<');
475
480
  if (blockType === BlockTypes.Branch) {
476
481
  const { start_point: [component, pin, wireId] } = stackRef;
@@ -511,8 +516,8 @@ export class ExecutionContext {
511
516
  }
512
517
  getPointBlockLocation() {
513
518
  this.log('get block point');
514
- for (let i = 0; i < this.scope.indentLevel; i++) {
515
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
519
+ for (let i = 0; i < this.scope.scopeLevel; i++) {
520
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1 - i);
516
521
  const { start_point } = stackRef;
517
522
  const component = start_point[0];
518
523
  if (component.instanceName.startsWith(`${Delimiter1}point.`)) {
@@ -416,9 +416,28 @@ export class Geometry {
416
416
  [segment.end.x, segment.end.y]
417
417
  ];
418
418
  });
419
+ const lines = [];
420
+ let prevPoint;
421
+ let currentLine = [];
422
+ segments.forEach((segment, index) => {
423
+ const [pt1, pt2] = segment;
424
+ if (index === 0 || (prevPoint[0] !== pt1[0] || prevPoint[1] !== pt1[1])) {
425
+ if (currentLine.length > 0) {
426
+ lines.push(currentLine);
427
+ currentLine = [];
428
+ }
429
+ currentLine.push([pt1[0], pt1[1]]);
430
+ }
431
+ currentLine.push(pt2);
432
+ prevPoint = pt2;
433
+ });
434
+ if (currentLine.length > 0) {
435
+ lines.push(currentLine);
436
+ }
419
437
  return {
420
438
  intersectPoints,
421
439
  segments,
440
+ lines,
422
441
  };
423
442
  }
424
443
  }
@@ -103,8 +103,10 @@ export var BlockTypes;
103
103
  export var NetGraphicsParams;
104
104
  (function (NetGraphicsParams) {
105
105
  NetGraphicsParams["Color"] = "color";
106
- NetGraphicsParams["Highight"] = "highlight";
107
106
  NetGraphicsParams["LineWidth"] = "lineWidth";
107
+ NetGraphicsParams["Highlight"] = "highlight";
108
+ NetGraphicsParams["HighlightWidth"] = "highlightWidth";
109
+ NetGraphicsParams["HighlightOpacity"] = "highlightOpacity";
108
110
  })(NetGraphicsParams || (NetGraphicsParams = {}));
109
111
  export var FrameType;
110
112
  (function (FrameType) {
@@ -112,8 +112,19 @@ export class LayoutEngine {
112
112
  const value = net.params.get(NetGraphicsParams.LineWidth);
113
113
  renderNet.lineWidth = milsToMM(value).toNumber();
114
114
  }
115
- if (net.params.has(NetGraphicsParams.Highight)) {
116
- renderNet.highlight = net.params.get(NetGraphicsParams.Highight);
115
+ if (net.params.has(NetGraphicsParams.Highlight)) {
116
+ renderNet.highlight =
117
+ net.params.get(NetGraphicsParams.Highlight);
118
+ }
119
+ if (net.params.has(NetGraphicsParams.HighlightWidth)) {
120
+ renderNet.highlightWidth =
121
+ milsToMM(net.params.get(NetGraphicsParams.HighlightWidth))
122
+ .toNumber();
123
+ }
124
+ if (net.params.has(NetGraphicsParams.HighlightOpacity)) {
125
+ renderNet.highlightOpacity =
126
+ net.params.get(NetGraphicsParams.HighlightOpacity)
127
+ .toNumber();
117
128
  }
118
129
  renderNets.set(net.toString(), renderNet);
119
130
  });
@@ -167,12 +178,13 @@ export class LayoutEngine {
167
178
  });
168
179
  }
169
180
  else {
170
- const { intersectPoints, segments } = Geometry.mergeWires(allLines);
181
+ const { intersectPoints, segments, lines } = Geometry.mergeWires(allLines);
171
182
  mergedWires.push({
172
183
  netName: netName,
173
184
  segments,
174
185
  intersectPoints,
175
186
  net: renderNet,
187
+ lines,
176
188
  });
177
189
  intersectPoints.forEach(([x, y]) => {
178
190
  junctions.push(new RenderJunction(numeric(x), numeric(y), renderNet));
@@ -12,7 +12,7 @@ export class ExecutionScope {
12
12
  breakStack = [];
13
13
  wires = [];
14
14
  frames = [];
15
- indentLevel = 0;
15
+ scopeLevel = 0;
16
16
  netCounter = 1;
17
17
  unnamedCounter = 1;
18
18
  currentComponent = null;
@@ -172,12 +172,14 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
172
172
  const mergedWireHighlightGroup = canvas.group();
173
173
  const mergedWireGroup = canvas.group();
174
174
  mergedWires.forEach(tmpItem => {
175
- const { segments, intersectPoints, net = null } = tmpItem;
175
+ const { intersectPoints, net = null, lines = null } = tmpItem;
176
176
  let useJunctionColor = ColorScheme.JunctionColor;
177
177
  let useColor = ColorScheme.WireColor;
178
178
  let useLineWidth = defaultWireLineWidth;
179
179
  let displayHighlight = false;
180
180
  let displayHighlightColor = null;
181
+ let displayHighlightOpacity = 0.3;
182
+ let displayHighlightWidth = 5 * MilsToMM;
181
183
  if (net !== null) {
182
184
  useColor = net.color ?? ColorScheme.WireColor;
183
185
  useJunctionColor = net.color ?? ColorScheme.JunctionColor;
@@ -185,25 +187,29 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
185
187
  if (net.highlight !== null) {
186
188
  displayHighlight = true;
187
189
  displayHighlightColor = net.highlight ?? null;
190
+ if (net.highlightOpacity !== undefined) {
191
+ displayHighlightOpacity = net.highlightOpacity;
192
+ }
193
+ if (net.highlightWidth !== undefined) {
194
+ displayHighlightWidth = net.highlightWidth;
195
+ }
188
196
  }
189
197
  }
190
198
  const pathItems = [];
191
- const highlightExtraSize = 5 * MilsToMM;
192
- segments.forEach(segment => {
193
- const pt1 = segment[0];
194
- const pt2 = segment[1];
195
- pathItems.push(...[
196
- 'M', pt1[0], pt1[1],
197
- 'L', pt2[0], pt2[1]
198
- ]);
199
+ const useLines = lines ?? [];
200
+ useLines.forEach(line => {
201
+ line.forEach((point, index) => {
202
+ const commandType = (index === 0) ? 'M' : 'L';
203
+ pathItems.push(...[commandType, point[0], point[1]]);
204
+ });
199
205
  });
200
206
  if (displayHighlight) {
201
207
  mergedWireHighlightGroup.path(pathItems)
202
208
  .stroke({
203
- width: useLineWidth + highlightExtraSize,
209
+ width: useLineWidth + displayHighlightWidth,
204
210
  color: displayHighlightColor,
205
- opacity: 0.3,
206
- linecap: 'square'
211
+ opacity: displayHighlightOpacity,
212
+ linecap: 'butt'
207
213
  })
208
214
  .fill('none');
209
215
  }
@@ -211,11 +217,11 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
211
217
  .stroke({
212
218
  width: useLineWidth,
213
219
  color: useColor,
214
- linecap: 'square'
220
+ linecap: 'butt'
215
221
  })
216
222
  .fill('none');
217
223
  const halfJunctionSize = junctionSize.half();
218
- const highlightJunctionSize = numeric(junctionSize.toNumber() + highlightExtraSize);
224
+ const highlightJunctionSize = numeric(junctionSize.toNumber() + displayHighlightWidth);
219
225
  const tmpHighlightExtraSize = highlightJunctionSize.half();
220
226
  intersectPoints.forEach(point => {
221
227
  const [x, y,] = point;
@@ -99,17 +99,17 @@ export class ParserVisitor extends BaseVisitor {
99
99
  }
100
100
  const scope = this.getScope();
101
101
  const executor = this.getExecutor();
102
- const indentLevel = scope.indentLevel;
103
- if (scope.blockStack.has(indentLevel)) {
104
- const blockStackEntry = scope.blockStack.get(indentLevel);
102
+ const scopeLevel = scope.scopeLevel;
103
+ if (scope.blockStack.has(scopeLevel)) {
104
+ const blockStackEntry = scope.blockStack.get(scopeLevel);
105
105
  if (blockStackEntry.type !== blockType) {
106
106
  executor.exitBlocks();
107
107
  }
108
108
  }
109
- if (!scope.blockStack.has(indentLevel)) {
109
+ if (!scope.blockStack.has(scopeLevel)) {
110
110
  executor.enterBlocks(blockType);
111
111
  }
112
- const blockStackEntry = scope.blockStack.get(indentLevel);
112
+ const blockStackEntry = scope.blockStack.get(scopeLevel);
113
113
  const { current_index } = blockStackEntry;
114
114
  executor.enterBlock(current_index);
115
115
  this.visit(ctx.expressions_block());
@@ -117,12 +117,9 @@ export class ParserVisitor extends BaseVisitor {
117
117
  blockStackEntry.current_index++;
118
118
  };
119
119
  visitGraph_expressions = (ctx) => {
120
+ this.getExecutor().log('graph expressions', this.getScope().scopeLevel);
120
121
  if (ctx.path_block() === null) {
121
- const scope = this.getScope();
122
- const indentLevel = scope.indentLevel;
123
- if (scope.blockStack.has(indentLevel)) {
124
- this.getExecutor().exitBlocks();
125
- }
122
+ this.getExecutor().closeOpenPathBlocks();
126
123
  }
127
124
  const ctxPathBlock = ctx.path_block();
128
125
  const ctxNotPathBlock = ctx.graph_linear_expression();
@@ -863,9 +860,10 @@ export class ParserVisitor extends BaseVisitor {
863
860
  this.setResult(ctx, result);
864
861
  };
865
862
  visitAt_block_pin_expr = (ctx) => {
866
- const atPin = this.visitResult(ctx.pin_select_expr2());
867
863
  const executor = this.getExecutor();
868
864
  const [currentComponent, currentPin] = executor.getCurrentPoint();
865
+ executor.closeOpenPathBlocks();
866
+ const atPin = this.visitResult(ctx.pin_select_expr2());
869
867
  executor.atComponent(currentComponent, atPin, {
870
868
  addSequence: true
871
869
  });
@@ -886,11 +884,11 @@ export class ParserVisitor extends BaseVisitor {
886
884
  executor.log('entering at block');
887
885
  this.visit(ctx.at_component_expr());
888
886
  const [currentComponent, currentPin] = executor.getCurrentPoint();
889
- executor.scope.indentLevel += 1;
887
+ executor.scope.scopeLevel += 1;
890
888
  ctx.at_block_expressions().forEach(expression => {
891
889
  this.visit(expression);
892
890
  });
893
- executor.scope.indentLevel -= 1;
891
+ executor.scope.scopeLevel -= 1;
894
892
  executor.scope.setCurrent(currentComponent, currentPin);
895
893
  executor.log('leaving at block');
896
894
  };
@@ -200,7 +200,7 @@ export declare class SymbolDrawingCommands extends SymbolDrawing {
200
200
  clone(): SymbolDrawingCommands;
201
201
  eq(other: SymbolDrawingCommands): boolean;
202
202
  }
203
- type SimplePoint = [x: number, y: number];
203
+ export type SimplePoint = [x: number, y: number];
204
204
  type SymbolPinLayout = {
205
205
  pinId: number;
206
206
  angle: number;
@@ -30,7 +30,7 @@ export declare class ExecutionContext {
30
30
  parentContext: ExecutionContext;
31
31
  componentAngleFollowsWire: boolean;
32
32
  warnings: ExecutionWarning[];
33
- constructor(name: string, namespace: string, netNamespace: string, executionLevel: number | undefined, indentLevel: number | undefined, silent: boolean | undefined, logger: Logger, warnings: ExecutionWarning[], parent: ExecutionContext);
33
+ constructor(name: string, namespace: string, netNamespace: string, executionLevel: number | undefined, scopeLevel: number | undefined, silent: boolean | undefined, logger: Logger, warnings: ExecutionWarning[], parent: ExecutionContext);
34
34
  logWarning(message: string, context?: ParserRuleContext, fileName?: string): void;
35
35
  log(...params: any[]): void;
36
36
  private setupRoot;
@@ -61,8 +61,8 @@ export declare class ExecutionContext {
61
61
  }): ComponentPin;
62
62
  copyComponent(component: ClassComponent): ClassComponent;
63
63
  enterBlocks(blockType: BlockTypes): void;
64
- exitBlocks(): void;
65
- closeAllBlocks(): void;
64
+ exitBlocks(scopeLevel?: number | null): void;
65
+ closeOpenPathBlocks(): void;
66
66
  enterBlock(blockIndex: number): void;
67
67
  exitBlock(blockIndex: number): void;
68
68
  atPointBlock(): void;
@@ -2,6 +2,7 @@ import Flatten from '@flatten-js/core';
2
2
  import { Box } from '@svgdotjs/svg.js';
3
3
  import { NumericValue } from './objects/ParamDefinition.js';
4
4
  import { PinTypes } from './objects/PinTypes.js';
5
+ import { SimplePoint } from './draw_symbols.js';
5
6
  export type Segment = Flatten.Segment;
6
7
  export type Polygon = Flatten.Polygon;
7
8
  export type Multiline = Flatten.Multiline;
@@ -76,7 +77,8 @@ export declare class Geometry {
76
77
  y: NumericValue;
77
78
  }[][]): {
78
79
  intersectPoints: WirePointCount[];
79
- segments: [x: number, y: number][][];
80
+ segments: SimplePoint[][];
81
+ lines: SimplePoint[][];
80
82
  };
81
83
  }
82
84
  type WirePointCount = [x: number, y: number, count: number];
@@ -90,8 +90,10 @@ export declare enum BlockTypes {
90
90
  }
91
91
  export declare enum NetGraphicsParams {
92
92
  Color = "color",
93
- Highight = "highlight",
94
- LineWidth = "lineWidth"
93
+ LineWidth = "lineWidth",
94
+ Highlight = "highlight",
95
+ HighlightWidth = "highlightWidth",
96
+ HighlightOpacity = "highlightOpacity"
95
97
  }
96
98
  export declare enum FrameType {
97
99
  Frame = 1,
@@ -1,5 +1,5 @@
1
1
  import { Graph } from '@dagrejs/graphlib';
2
- import { SymbolGraphic, SymbolText, SymbolDrawingCommands } from "./draw_symbols.js";
2
+ import { SymbolGraphic, SymbolText, SymbolDrawingCommands, SimplePoint } from "./draw_symbols.js";
3
3
  import { ClassComponent } from "./objects/ClassComponent.js";
4
4
  import { SequenceItem } from "./objects/ExecutionScope.js";
5
5
  import { WireAutoDirection } from './globals.js';
@@ -61,6 +61,7 @@ export type RenderNet = {
61
61
  lineWidth?: number;
62
62
  highlight?: string;
63
63
  highlightOpacity?: number;
64
+ highlightWidth?: number;
64
65
  };
65
66
  export declare class RenderWire extends RenderObject {
66
67
  id: number;
@@ -85,9 +86,10 @@ export declare class RenderWire extends RenderObject {
85
86
  }
86
87
  export type MergedWire = {
87
88
  netName: string;
88
- segments: [x: number, y: number][][];
89
+ segments: SimplePoint[][];
89
90
  intersectPoints: [x: number, y: number, count: number][];
90
91
  net: RenderNet;
92
+ lines?: SimplePoint[][];
91
93
  };
92
94
  export declare class RenderComponent extends RenderObject {
93
95
  component: ClassComponent;
@@ -23,7 +23,7 @@ export declare class ExecutionScope {
23
23
  breakStack: ParserRuleContext[];
24
24
  wires: Wire[];
25
25
  frames: Frame[];
26
- indentLevel: number;
26
+ scopeLevel: number;
27
27
  netCounter: number;
28
28
  unnamedCounter: number;
29
29
  currentComponent: ClassComponent | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circuitscript",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Interpreter for the circuitscript language",
5
5
  "homepage": "https://circuitscript.net",
6
6
  "engines": {