circuitscript 0.1.4 → 0.1.5

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.
@@ -123,7 +123,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
123
123
  if (paramValue instanceof ParamDefinition_js_1.NumericValue) {
124
124
  appendValue = paramValue.value;
125
125
  }
126
- instanceName += '_' + appendValue;
126
+ instanceName += `${globals_js_1.Delimiter1}${appendValue}`;
127
127
  }
128
128
  const arrange = properties.has('arrange') ?
129
129
  properties.get('arrange') : null;
@@ -614,11 +614,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
614
614
  const executionStack = this.executionStack;
615
615
  const functionCounter = { counter: 0 };
616
616
  const resolveNet = this.createNetResolver(this.executionStack);
617
+ const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
617
618
  const __runFunc = (passedInParameters, options) => {
618
- const executionContextName = functionName + '_' + functionCounter['counter'];
619
+ const executionContextName = `${functionName}-${functionCounter['counter']}`;
619
620
  const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
620
621
  functionCounter['counter'] += 1;
621
622
  newExecutor.resolveNet = resolveNet;
623
+ newExecutor.resolveComponentPinNet = resolveComponentPinNet;
622
624
  const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
623
625
  const lastExecution = executionStack.pop();
624
626
  const nextLastExecution = executionStack[executionStack.length - 1];
@@ -882,15 +884,15 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
882
884
  expandModuleContains(component, netNamespace) {
883
885
  this.getExecutor().log('expanding module `contains`');
884
886
  const executionStack = this.executionStack;
885
- const resolveNet = this.createNetResolver(executionStack);
886
887
  const executor = this.getExecutor();
887
- const executionContextName = executor.namespace + "_"
888
+ const executionContextName = executor.namespace + globals_js_1.Delimiter1
888
889
  + component.instanceName
889
- + '_' + component.moduleCounter;
890
- const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + "_" + component.moduleCounter);
890
+ + globals_js_1.Delimiter1 + component.moduleCounter;
891
+ const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + globals_js_1.Delimiter1 + component.moduleCounter);
891
892
  const newExecutor = this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
892
893
  component.moduleCounter += 1;
893
- newExecutor.resolveNet = resolveNet;
894
+ newExecutor.resolveNet = this.createNetResolver(executionStack);
895
+ newExecutor.resolveComponentPinNet = this.createComponentPinNetResolver(executionStack);
894
896
  this.visit(component.moduleContainsExpressions);
895
897
  const executionContext = executionStack.pop();
896
898
  component.moduleExecutionContext = executionContext;
@@ -9,9 +9,10 @@ import { ClassComponent } from "./objects/ClassComponent";
9
9
  import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition";
10
10
  import { PinTypes } from "./objects/PinTypes";
11
11
  import { Direction, UndeclaredReference } from "./objects/types";
12
- import { GlobalDocumentName, ReferenceTypes } from './globals';
12
+ import { DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals';
13
13
  import { linkBuiltInMethods } from './builtinMethods';
14
14
  import { resolveToNumericValue, throwWithContext } from './utils';
15
+ import { SequenceAction } from './objects/ExecutionScope';
15
16
  export class BaseVisitor extends CircuitScriptVisitor {
16
17
  indentLevel = 0;
17
18
  startingContext;
@@ -41,12 +42,18 @@ export class BaseVisitor extends CircuitScriptVisitor {
41
42
  super();
42
43
  this.logger = new Logger();
43
44
  this.onErrorCallbackHandler = onErrorHandler;
44
- this.startingContext = new ExecutionContext('__', '__.', '/', 0, 0, silent, this.logger, null);
45
- this.startingContext.scope.variables.set(GlobalDocumentName, {});
46
- this.setupPrintFunction(this.startingContext);
45
+ this.startingContext = new ExecutionContext(DoubleDelimiter1, `${DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, null);
46
+ const scope = this.startingContext.scope;
47
+ scope.sequence.push([
48
+ SequenceAction.At, scope.componentRoot, scope.currentPin
49
+ ]);
50
+ scope.variables.set(GlobalDocumentName, {});
51
+ this.setupBuiltInFunctions(this.startingContext);
47
52
  this.executionStack = [this.startingContext];
48
53
  this.startingContext.resolveNet =
49
54
  this.createNetResolver(this.executionStack);
55
+ this.startingContext.resolveComponentPinNet =
56
+ this.createComponentPinNetResolver(this.executionStack);
50
57
  this.silent = silent;
51
58
  this.currentDirectory = currentDirectory;
52
59
  this.defaultLibsPath = defaultLibsPath;
@@ -54,7 +61,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
54
61
  getExecutor() {
55
62
  return this.executionStack[this.executionStack.length - 1];
56
63
  }
57
- setupPrintFunction(context) {
64
+ setupBuiltInFunctions(context) {
58
65
  linkBuiltInMethods(context, this);
59
66
  }
60
67
  createNetResolver(executionStack) {
@@ -77,6 +84,19 @@ export class BaseVisitor extends CircuitScriptVisitor {
77
84
  };
78
85
  return resolveNet;
79
86
  }
87
+ createComponentPinNetResolver(executionStack) {
88
+ return (component, pin) => {
89
+ const reversed = [...executionStack].reverse();
90
+ for (let i = 0; i < reversed.length; i++) {
91
+ const context = reversed[i];
92
+ const net = context.scope.getNet(component, pin);
93
+ if (net !== null) {
94
+ return net;
95
+ }
96
+ }
97
+ return null;
98
+ };
99
+ }
80
100
  log(...params) {
81
101
  const indentOutput = ''.padStart(this.indentLevel * 4, ' ');
82
102
  const indentLevelText = this.indentLevel.toString().padStart(3, ' ');
@@ -103,12 +123,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
103
123
  const trailers = reference.trailers ?? [];
104
124
  if (trailers.length === 0) {
105
125
  if (value instanceof ClassComponent) {
106
- const instances = this.getExecutor().scope.instances;
107
- const tmpComponent = value;
108
- const oldName = tmpComponent.instanceName;
109
- tmpComponent.instanceName = reference.name;
110
- instances.delete(oldName);
111
- instances.set(reference.name, tmpComponent);
126
+ const variables = this.getExecutor().scope.variables;
127
+ variables.set(reference.name, value);
128
+ this.getExecutor().scope.sequence.push([SequenceAction.Assign, reference.name, value]);
112
129
  this.log2(`assigned '${reference.name}' to ClassComponent`);
113
130
  }
114
131
  else {
@@ -229,7 +246,6 @@ export class BaseVisitor extends CircuitScriptVisitor {
229
246
  executor.scope.setNet(tmpComponent, pinId, net);
230
247
  }
231
248
  }
232
- this.log2(`atomId: ${atomId} ${currentReference}`);
233
249
  if (ctx.parent instanceof ExpressionContext && !currentReference.found) {
234
250
  this.throwWithContext(ctx, "Unknown symbol: " + atomId);
235
251
  }
@@ -594,7 +610,6 @@ export class BaseVisitor extends CircuitScriptVisitor {
594
610
  const executionContextNamespace = currentExecutionContext.namespace
595
611
  + executionContextName + ".";
596
612
  const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, parentContext);
597
- this.setupPrintFunction(newExecutor);
598
613
  executionStack.push(newExecutor);
599
614
  this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
600
615
  return newExecutor;
@@ -17,6 +17,8 @@ export function linkBuiltInMethods(context, visitor) {
17
17
  ['toMils', toMils],
18
18
  ['range', range],
19
19
  ['len', objectLength],
20
+ ['arrayPush', arrayPush],
21
+ ['arrayGet', arrayGet],
20
22
  ];
21
23
  builtIns.forEach(([functionName, functionImpl]) => {
22
24
  context.createFunction(functionName, params => {
@@ -80,6 +82,26 @@ function objectLength(obj) {
80
82
  }
81
83
  }
82
84
  }
85
+ function arrayPush(arrayObject, valueToPush) {
86
+ if (!Array.isArray(arrayObject)) {
87
+ throw "Invalid array object to push";
88
+ }
89
+ arrayObject.push(valueToPush);
90
+ return arrayObject;
91
+ }
92
+ function arrayGet(arrayObject, index) {
93
+ if (!Array.isArray(arrayObject)) {
94
+ throw "Invalid array object to get";
95
+ }
96
+ let useValue;
97
+ if (index instanceof NumericValue) {
98
+ useValue = index.toNumber();
99
+ }
100
+ else {
101
+ useValue = index;
102
+ }
103
+ return arrayObject[useValue];
104
+ }
83
105
  function getPositionParams(params) {
84
106
  return params.map(([, , value]) => value);
85
107
  }
@@ -789,7 +789,10 @@ export class SymbolCustom extends SymbolGraphic {
789
789
  calculateSize() {
790
790
  const tmpPinSpacing = this.pinSpacing.toNumber();
791
791
  const tmpPinLength = this.pinLength.toNumber();
792
- const { [SymbolPinSide.Top]: maxTopPins, [SymbolPinSide.Bottom]: maxBottomPins, [SymbolPinSide.Left]: maxLeftPins, [SymbolPinSide.Right]: maxRightPins } = this.pinMaxPositions;
792
+ const maxTopPins = this.pinMaxPositions.get(SymbolPinSide.Top);
793
+ const maxBottomPins = this.pinMaxPositions.get(SymbolPinSide.Bottom);
794
+ const maxLeftPins = this.pinMaxPositions.get(SymbolPinSide.Left);
795
+ const maxRightPins = this.pinMaxPositions.get(SymbolPinSide.Right);
793
796
  const bodyWidthFromPins = numeric((1 + Math.max(maxTopPins, maxBottomPins)) * tmpPinSpacing);
794
797
  const bodyWidth = Math.max(bodyWidthFromPins.toNumber(), this.bodyWidth.toNumber());
795
798
  let tmpBodyHeight = 0;
@@ -1,4 +1,4 @@
1
- import { BlockTypes, ComponentTypes, GlobalNames, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide } from './globals.mjs';
1
+ import { BlockTypes, ComponentTypes, Delimiter1, GlobalNames, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide } from './globals.mjs';
2
2
  import { ClassComponent, ModuleComponent } from './objects/ClassComponent.mjs';
3
3
  import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.mjs';
4
4
  import { Net } from './objects/Net.mjs';
@@ -10,6 +10,7 @@ import { Frame } from './objects/Frame.mjs';
10
10
  import { CalculatePinPositions } from './layout.mjs';
11
11
  import { UnitDimension } from './helpers.mjs';
12
12
  import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.mjs';
13
+ import { getBlockTypeString } from './utils.mjs';
13
14
  export class ExecutionContext {
14
15
  name;
15
16
  namespace;
@@ -18,6 +19,7 @@ export class ExecutionContext {
18
19
  scope;
19
20
  tmpPointId = 0;
20
21
  resolveNet = null;
22
+ resolveComponentPinNet;
21
23
  stopFurtherExpressions = false;
22
24
  returnValue = null;
23
25
  silent = false;
@@ -34,13 +36,6 @@ export class ExecutionContext {
34
36
  this.scope = ExecutionScope.create();
35
37
  this.scope.indentLevel = indentLevel;
36
38
  this.setupRoot();
37
- if (name === '__') {
38
- this.scope.sequence.push([
39
- SequenceAction.At,
40
- this.scope.componentRoot,
41
- this.scope.currentPin
42
- ]);
43
- }
44
39
  this.silent = silent;
45
40
  this.log('create new execution context', this.namespace, this.name, this.scope.indentLevel);
46
41
  this.parentContext = parent;
@@ -66,12 +61,12 @@ export class ExecutionContext {
66
61
  this.scope.componentRoot = componentRoot;
67
62
  }
68
63
  getUniqueInstanceName() {
69
- const tmpName = 'COMP_' + this.scope.unnamedCounter;
64
+ const tmpName = `COMP${Delimiter1}${this.scope.unnamedCounter}`;
70
65
  this.scope.unnamedCounter += 1;
71
66
  return tmpName;
72
67
  }
73
68
  getUniqueNetName() {
74
- const tmpName = 'NET_' + this.scope.netCounter;
69
+ const tmpName = `NET${Delimiter1}${this.scope.netCounter}`;
75
70
  this.scope.netCounter++;
76
71
  return tmpName;
77
72
  }
@@ -81,7 +76,7 @@ export class ExecutionContext {
81
76
  linkComponentPinNet(component1, component1Pin, component2, component2Pin) {
82
77
  const net1 = this.scope.getNet(component1, component1Pin);
83
78
  const net2 = this.scope.getNet(component2, component2Pin);
84
- this.log('link nets', component1, component1Pin, net1, 'to', component2, component2Pin, net2);
79
+ this.log('link nets', component1, component1Pin, net1, 'priority:' + net1?.priority, 'to', component2, component2Pin, net2, 'priority:' + net2?.priority);
85
80
  let returnNet;
86
81
  if (net1 === null && net2 === null) {
87
82
  const tmpNet = new Net(this.netNamespace, this.getUniqueNetName());
@@ -105,7 +100,7 @@ export class ExecutionContext {
105
100
  returnNet = net1;
106
101
  }
107
102
  }
108
- this.log('final net after link: ', returnNet);
103
+ this.log('final net after link: ', returnNet, returnNet.priority);
109
104
  return returnNet;
110
105
  }
111
106
  mergeNets(net1, net2) {
@@ -166,8 +161,9 @@ export class ExecutionContext {
166
161
  tmpNet = new Net(this.netNamespace, netName, priority);
167
162
  this.log('net not found, added net instance', tmpNet.namespace, tmpNet.name);
168
163
  }
169
- this.scope.setNet(component, 1, tmpNet);
170
- this.log('set net', netName, 'component', component);
164
+ const defaultPin = 1;
165
+ this.scope.setNet(component, defaultPin, tmpNet);
166
+ this.log('set net', netName, 'component', component, defaultPin);
171
167
  }
172
168
  const { pins: pinSides, maxPositions } = getPortSide(component.pins, component.arrangeProps);
173
169
  component.pinsMaxPositions = maxPositions;
@@ -209,7 +205,6 @@ export class ExecutionContext {
209
205
  this.atComponent(component, nextPin, {
210
206
  addSequence: true
211
207
  });
212
- this.printPoint();
213
208
  return this.getCurrentPoint();
214
209
  }
215
210
  toComponent(component, pinId, options) {
@@ -283,6 +278,7 @@ export class ExecutionContext {
283
278
  return this.getCurrentPoint();
284
279
  }
285
280
  copyComponent(component) {
281
+ this.log('create clone of net component:', component);
286
282
  let componentCopy = null;
287
283
  if (!this.scope.copyIDs.has(component.instanceName)) {
288
284
  this.scope.copyIDs.set(component.instanceName, 0);
@@ -295,14 +291,24 @@ export class ExecutionContext {
295
291
  const cloneInstanceName = component.instanceName + ':' + idNum;
296
292
  this.scope.instances.set(cloneInstanceName, componentCopy);
297
293
  componentCopy.instanceName = cloneInstanceName;
298
- this.linkComponentPinNet(component, 1, componentCopy, 1);
294
+ const defaultPin = 1;
295
+ if (this.scope.getNet(component, defaultPin) === null) {
296
+ const foundNet = this.resolveComponentPinNet(component, defaultPin);
297
+ if (foundNet !== null) {
298
+ this.log('found net in upper scopes', foundNet);
299
+ this.scope.setNet(component, defaultPin, foundNet);
300
+ }
301
+ }
302
+ this.linkComponentPinNet(component, defaultPin, componentCopy, defaultPin);
299
303
  this.log('created clone of net component:', cloneInstanceName);
300
304
  return componentCopy;
301
305
  }
302
306
  enterBlocks(blockType) {
303
- if (blockType === BlockTypes.Point || blockType === BlockTypes.Parallel) {
304
- const key = blockType === BlockTypes.Point ? 'point' : 'parallel';
305
- this.addPoint(`_${key}.${this.name}.${this.tmpPointId}`, false);
307
+ if (blockType === BlockTypes.Point
308
+ || blockType === BlockTypes.Parallel
309
+ || blockType === BlockTypes.Branch) {
310
+ const key = getBlockTypeString(blockType);
311
+ this.addPoint(`${Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
306
312
  this.tmpPointId += 1;
307
313
  }
308
314
  this.scope.blockStack.set(this.scope.indentLevel, {
@@ -377,7 +383,7 @@ export class ExecutionContext {
377
383
  }
378
384
  else if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
379
385
  if (blockIndex === 0) {
380
- const pointIdName = (blockType === BlockTypes.Join) ? '_join' : '_parallel';
386
+ const pointIdName = `${Delimiter1}${getBlockTypeString(blockType)}`;
381
387
  this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
382
388
  this.tmpPointId += 1;
383
389
  stackRef['final_point'] = [
@@ -411,7 +417,7 @@ export class ExecutionContext {
411
417
  const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
412
418
  const { entered_at } = stackRef;
413
419
  const component = entered_at[0];
414
- if (component.instanceName.startsWith('_point.')) {
420
+ if (component.instanceName.startsWith(`${Delimiter1}point.`)) {
415
421
  return entered_at;
416
422
  }
417
423
  }
@@ -526,14 +532,12 @@ export class ExecutionContext {
526
532
  const currentComponent = this.scope.currentComponent;
527
533
  const currentPin = this.scope.currentPin;
528
534
  const currentWireId = this.scope.currentWireId;
529
- const gndCopyIdOffset = 0;
530
535
  const tmpInstances = childScope.instances;
531
536
  const tmpNets = childScope.getNets();
532
537
  for (const [instanceName, component] of tmpInstances) {
533
538
  const newInstanceName = `${namespace}.${instanceName}`;
534
539
  component.instanceName = newInstanceName;
535
- if (component === childScope.componentGnd ||
536
- component === childScope.componentRoot) {
540
+ if (component === childScope.componentRoot) {
537
541
  continue;
538
542
  }
539
543
  if (!this.scope.instances.has(newInstanceName)) {
@@ -543,6 +547,16 @@ export class ExecutionContext {
543
547
  throw "Invalid instance name to merge into parent scope!";
544
548
  }
545
549
  }
550
+ const childScopeUniqueNets = new Set(tmpNets.map(([, , net]) => net));
551
+ childScopeUniqueNets.forEach(net => {
552
+ if (net.priority === 0
553
+ && this.scope.getNetWithNamespacePath(net.namespace, net.name) !== null) {
554
+ this.log('net namespace and name already used in parent scope', net);
555
+ const newNetName = this.getUniqueNetName();
556
+ net.name = newNetName;
557
+ this.log('assigned new name: ', net);
558
+ }
559
+ });
546
560
  tmpNets.forEach(([component, pin, net]) => {
547
561
  this.scope.setNet(component, pin, net);
548
562
  });
@@ -557,7 +571,6 @@ export class ExecutionContext {
557
571
  this.scope.setNet(currentComponent, currentPin, netConnectedToRoot);
558
572
  currentNet = tmpNet;
559
573
  }
560
- netConnectedToRoot.priority = currentNet.priority - 1;
561
574
  this.toComponent(tmpRoot, 1);
562
575
  }
563
576
  }
@@ -646,7 +659,7 @@ export class ExecutionContext {
646
659
  this.log('Warning: ' + pointId + ' is being redefined');
647
660
  }
648
661
  const useName = userDefined ? 'point.' + pointId : pointId;
649
- const componentPoint = ClassComponent.simple(useName, 1, "point");
662
+ const componentPoint = ClassComponent.simple(useName, 1);
650
663
  componentPoint.displayProp = this.getPointSymbol();
651
664
  componentPoint.typeProp = ComponentTypes.net;
652
665
  this.scope.instances.set(pointId, componentPoint);
@@ -800,12 +813,11 @@ function isWireSegmentsEndAuto(segments) {
800
813
  }
801
814
  export function getPortSide(pins, arrangeProps) {
802
815
  const result = [];
803
- const maxPositions = {
804
- [SymbolPinSide.Left]: 0,
805
- [SymbolPinSide.Right]: 0,
806
- [SymbolPinSide.Top]: 0,
807
- [SymbolPinSide.Bottom]: 0,
808
- };
816
+ const maxPositions = new Map();
817
+ maxPositions.set(SymbolPinSide.Left, 0);
818
+ maxPositions.set(SymbolPinSide.Right, 0);
819
+ maxPositions.set(SymbolPinSide.Top, 0);
820
+ maxPositions.set(SymbolPinSide.Bottom, 0);
809
821
  if (arrangeProps === null) {
810
822
  let counter = 0;
811
823
  for (const [pinId] of pins) {
@@ -823,8 +835,8 @@ export function getPortSide(pins, arrangeProps) {
823
835
  const rightSideItems = result.filter(item => {
824
836
  return item.side === PortSide.EAST;
825
837
  });
826
- maxPositions[SymbolPinSide.Left] = leftSideItems.length;
827
- maxPositions[SymbolPinSide.Right] = rightSideItems.length;
838
+ maxPositions.set(SymbolPinSide.Left, leftSideItems.length);
839
+ maxPositions.set(SymbolPinSide.Right, rightSideItems.length);
828
840
  }
829
841
  else {
830
842
  let counter = pins.size;
@@ -871,7 +883,7 @@ export function getPortSide(pins, arrangeProps) {
871
883
  }
872
884
  }
873
885
  });
874
- maxPositions[key] = position;
886
+ maxPositions.set(key, position);
875
887
  }
876
888
  }
877
889
  return {
@@ -1,7 +1,9 @@
1
1
  import { numeric } from "./objects/ParamDefinition";
2
+ export const Delimiter1 = '-';
3
+ export const DoubleDelimiter1 = `${Delimiter1}${Delimiter1}`;
2
4
  export var GlobalNames;
3
5
  (function (GlobalNames) {
4
- GlobalNames["__root"] = "__root";
6
+ GlobalNames["__root"] = "--root";
5
7
  GlobalNames["symbol"] = "symbol";
6
8
  })(GlobalNames || (GlobalNames = {}));
7
9
  export const NoNetText = 'NO_NET';
@@ -1,12 +1,11 @@
1
- import { readFileSync, writeFileSync, createWriteStream } from "fs";
1
+ import { readFileSync, writeFileSync, createWriteStream, existsSync, mkdirSync } from "fs";
2
2
  import path from "path";
3
3
  import PDFDocument from "pdfkit";
4
4
  import { generateKiCADNetList, printTree } from "./export.mjs";
5
5
  import { LayoutEngine } from "./layout.mjs";
6
- import { SequenceAction } from "./objects/ExecutionScope.mjs";
7
6
  import { parseFileWithVisitor } from "./parser.mjs";
8
7
  import { generatePdfOutput, generateSvgOutput, renderSheetsToSVG } from "./render.mjs";
9
- import { resolveToNumericValue, SimpleStopwatch } from "./utils.mjs";
8
+ import { generateDebugSequenceAction, resolveToNumericValue, sequenceActionString, SimpleStopwatch } from "./utils.mjs";
10
9
  import { ParserVisitor, VisitorExecutionException } from "./visitor.mjs";
11
10
  import { createContext } from "this-file";
12
11
  import { SymbolValidatorResolveVisitor, SymbolValidatorVisitor } from "./SymbolValidatorVisitor.mjs";
@@ -170,10 +169,16 @@ export function renderScript(scriptData, outputPath, options) {
170
169
  showStats && console.log('Parsing took:', parserTimeTaken);
171
170
  if (dumpNets) {
172
171
  const nets = visitor.dumpNets();
173
- console.log(nets);
172
+ nets.forEach(item => console.log(item.join(" | ")));
174
173
  }
175
- dumpData && writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
176
- dumpData && writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
174
+ const dumpDirectory = currentDirectory + '/dump/';
175
+ if (dumpData) {
176
+ if (!existsSync(dumpDirectory)) {
177
+ mkdirSync(dumpDirectory);
178
+ }
179
+ }
180
+ dumpData && writeFileSync(dumpDirectory + 'tree.lisp', tree.toStringTree(null, parser));
181
+ dumpData && writeFileSync(dumpDirectory + 'raw-parser.txt', visitor.logger.dump());
177
182
  if (hasError || hasParseError) {
178
183
  console.log('Error while parsing');
179
184
  return null;
@@ -186,29 +191,8 @@ export function renderScript(scriptData, outputPath, options) {
186
191
  console.log('Error during annotation: ', err);
187
192
  }
188
193
  const { sequence, nets } = visitor.getGraph();
189
- const tmpSequence = sequence.map(item => {
190
- const tmp = [...item];
191
- const action = tmp[0];
192
- if (action === SequenceAction.Wire) {
193
- tmp[2] = tmp[2].map(item2 => {
194
- const lengthValue = item2.value;
195
- const useValue = [item2.direction];
196
- if (lengthValue !== null) {
197
- useValue.push(lengthValue.value);
198
- useValue.push(lengthValue.type);
199
- }
200
- return useValue.join(",");
201
- }).join(" ");
202
- }
203
- else if (action === SequenceAction.Frame) {
204
- tmp[1] = item[1].frameId;
205
- }
206
- else if (action !== SequenceAction.WireJump) {
207
- tmp[1] = item[1].instanceName;
208
- }
209
- return tmp.join(" | ");
210
- });
211
- dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
194
+ const tmpSequence = generateDebugSequenceAction(sequence).map(item => sequenceActionString(item));
195
+ dumpData && writeFileSync(dumpDirectory + 'raw-sequence.txt', tmpSequence.join('\n'));
212
196
  let svgOutput = "";
213
197
  try {
214
198
  let fileExtension = null;
@@ -233,12 +217,12 @@ export function renderScript(scriptData, outputPath, options) {
233
217
  const sheetFrames = layoutEngine.runLayout(sequence, nets);
234
218
  layoutEngine.printWarnings();
235
219
  showStats && console.log('Layout took:', layoutTimer.lap());
236
- dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
220
+ dumpData && writeFileSync(dumpDirectory + 'raw-layout.txt', layoutEngine.logger.dump());
237
221
  const generateSvgTimer = new SimpleStopwatch();
238
222
  const renderLogger = new Logger();
239
223
  const svgCanvas = renderSheetsToSVG(sheetFrames, renderLogger);
240
224
  showStats && console.log('Render took:', generateSvgTimer.lap());
241
- dumpData && writeFileSync('dump/raw-render.txt', renderLogger.dump());
225
+ dumpData && writeFileSync(dumpDirectory + 'raw-render.txt', renderLogger.dump());
242
226
  svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
243
227
  if (outputPath) {
244
228
  if (fileExtension === 'svg') {
@@ -346,7 +346,7 @@ export class LayoutEngine {
346
346
  const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
347
347
  const overlaps = avoidAreas.filter(area => areasOverlap(frameArea, area));
348
348
  const doesOverlapAreasToAvoid = overlaps.length > 0;
349
- if (doesExceedFrameHeight || doesOverlapAreasToAvoid) {
349
+ if (boundPoints.length > 0 && (doesExceedFrameHeight || doesOverlapAreasToAvoid)) {
350
350
  innerFrameY = offsetY;
351
351
  const nextX = numeric(xmax).sub(offsetX).add(frame.gap);
352
352
  innerFrameX = offsetX.add(nextX);
@@ -376,7 +376,7 @@ export class LayoutEngine {
376
376
  const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
377
377
  const overlaps = avoidAreas.filter(area => areasOverlap(frameArea, area));
378
378
  const doesOverlapAreasToAvoid = overlaps.length > 0;
379
- if (doesExceedFrameWidth || doesOverlapAreasToAvoid) {
379
+ if (boundPoints.length > 0 && (doesExceedFrameWidth || doesOverlapAreasToAvoid)) {
380
380
  innerFrameX = offsetX.add(centeredOffsetX);
381
381
  const { ymax } = getBoundsFromPoints(boundPoints);
382
382
  const nextY = numeric(ymax).sub(offsetY).add(frame.gap);
package/dist/esm/main.mjs CHANGED
@@ -19,7 +19,8 @@ export default async function main() {
19
19
  .option('-w, --watch', 'Watch for file changes')
20
20
  .option('-n, --dump-nets', 'Dump out net information')
21
21
  .option('-d, --dump-data', 'Dump data during parsing')
22
- .option('-s, --stats', 'Show stats during generation');
22
+ .option('-s, --stats', 'Show stats during generation')
23
+ .option('-x, --skip-output', 'Skip output generation');
23
24
  program.addHelpText('before', figlet.textSync('circuitscript', {
24
25
  font: 'Small Slant'
25
26
  }));
@@ -75,7 +76,7 @@ export default async function main() {
75
76
  outputPath = args[1];
76
77
  }
77
78
  const output = renderScript(scriptData, outputPath, scriptOptions);
78
- if (outputPath === null && output) {
79
+ if (outputPath === null && output && (options.skipOutput === undefined)) {
79
80
  console.log(output);
80
81
  }
81
82
  if (watchFileChanges) {
@@ -9,7 +9,7 @@ export class ClassComponent {
9
9
  pins = new Map();
10
10
  pinNets = new Map();
11
11
  pinWires = new Map();
12
- pinsMaxPositions = {};
12
+ pinsMaxPositions = new Map();
13
13
  _cachedPins;
14
14
  _cachedParams;
15
15
  _copyID = null;
@@ -145,6 +145,9 @@ export class ClassComponent {
145
145
  for (const [key, value] of this.pins) {
146
146
  component.pins.set(key, value);
147
147
  }
148
+ for (const [key, value] of this.pinsMaxPositions) {
149
+ component.pinsMaxPositions.set(key, value);
150
+ }
148
151
  component.refreshCache();
149
152
  return component;
150
153
  }
@@ -16,8 +16,6 @@ export class ExecutionScope {
16
16
  currentPin = null;
17
17
  currentWireId = -1;
18
18
  currentFrameId = -1;
19
- netGnd = null;
20
- componentGnd = null;
21
19
  componentRoot = null;
22
20
  copyIDs = new Map();
23
21
  sequence = [];
@@ -41,6 +39,12 @@ export class ExecutionScope {
41
39
  });
42
40
  return found ? found[2] : null;
43
41
  }
42
+ getNetWithNamespacePath(namespace, name) {
43
+ const found = this.nets.find(([, , net]) => {
44
+ return net.namespace === namespace && net.name === name;
45
+ });
46
+ return found ? found[2] : null;
47
+ }
44
48
  hasNet(component, pin) {
45
49
  return this.findNet(component, pin) !== undefined;
46
50
  }
@@ -126,6 +130,7 @@ export var SequenceAction;
126
130
  SequenceAction["Wire"] = "wire";
127
131
  SequenceAction["WireJump"] = "wire-jump";
128
132
  SequenceAction["Frame"] = "frame";
133
+ SequenceAction["Assign"] = "assign";
129
134
  })(SequenceAction || (SequenceAction = {}));
130
135
  export var FrameAction;
131
136
  (function (FrameAction) {
@@ -1,4 +1,5 @@
1
1
  import { SVG, registerWindow } from '@svgdotjs/svg.js';
2
+ import { Big } from 'big.js';
2
3
  import { HorizontalAlign, HorizontalAlignProp, VerticalAlign, VerticalAlignProp } from './geometry.mjs';
3
4
  import { defaultFont } from './globals.mjs';
4
5
  import { JSModuleType, detectJSModuleType } from './helpers.mjs';
@@ -87,9 +88,11 @@ export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regul
87
88
  }
88
89
  const { width, height } = textbox;
89
90
  tmpTextElement.remove();
91
+ const finalWidth = new Big(width).round(4).toNumber();
92
+ const finalHeight = new Big(height).round(4).toNumber();
90
93
  measureTextSizeCache[key] = {
91
- width: Math.round(width * 100) / 100,
92
- height: Math.round(height * 100) / 100,
94
+ width: finalWidth,
95
+ height: finalHeight,
93
96
  box: textbox,
94
97
  };
95
98
  measureTextSizeCacheHits[key] = 0;