circuitscript 0.1.3 → 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.
- package/dist/cjs/BaseVisitor.js +27 -12
- package/dist/cjs/builtinMethods.js +22 -0
- package/dist/cjs/draw_symbols.js +4 -1
- package/dist/cjs/execute.js +45 -34
- package/dist/cjs/globals.js +4 -2
- package/dist/cjs/helpers.js +13 -29
- package/dist/cjs/layout.js +3 -3
- package/dist/cjs/main.js +3 -2
- package/dist/cjs/objects/ClassComponent.js +4 -1
- package/dist/cjs/objects/ExecutionScope.js +7 -2
- package/dist/cjs/sizing.js +5 -2
- package/dist/cjs/utils.js +77 -1
- package/dist/cjs/visitor.js +9 -7
- package/dist/esm/BaseVisitor.mjs +28 -13
- package/dist/esm/builtinMethods.mjs +22 -0
- package/dist/esm/draw_symbols.mjs +4 -1
- package/dist/esm/execute.mjs +47 -35
- package/dist/esm/globals.mjs +3 -1
- package/dist/esm/helpers.mjs +15 -31
- package/dist/esm/layout.mjs +3 -3
- package/dist/esm/main.mjs +3 -2
- package/dist/esm/objects/ClassComponent.mjs +4 -1
- package/dist/esm/objects/ExecutionScope.mjs +7 -2
- package/dist/esm/sizing.mjs +5 -2
- package/dist/esm/utils.mjs +73 -0
- package/dist/esm/visitor.mjs +10 -8
- package/dist/types/BaseVisitor.d.ts +2 -1
- package/dist/types/draw_symbols.d.ts +2 -6
- package/dist/types/execute.d.ts +2 -3
- package/dist/types/globals.d.ts +3 -1
- package/dist/types/objects/ClassComponent.d.ts +1 -3
- package/dist/types/objects/ExecutionScope.d.ts +9 -6
- package/dist/types/utils.d.ts +5 -0
- package/libs/lib.cst +12 -22
- package/package.json +2 -2
package/dist/cjs/visitor.js
CHANGED
|
@@ -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 +=
|
|
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
|
|
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
|
-
+
|
|
890
|
-
const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName +
|
|
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 =
|
|
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;
|
package/dist/esm/BaseVisitor.mjs
CHANGED
|
@@ -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(
|
|
45
|
-
this.startingContext.scope
|
|
46
|
-
|
|
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
|
-
|
|
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
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
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;
|
package/dist/esm/execute.mjs
CHANGED
|
@@ -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 =
|
|
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 =
|
|
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
|
-
|
|
170
|
-
this.
|
|
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
|
-
|
|
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
|
|
304
|
-
|
|
305
|
-
|
|
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
|
|
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(
|
|
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.
|
|
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
|
|
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
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
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
|
|
827
|
-
maxPositions
|
|
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
|
|
886
|
+
maxPositions.set(key, position);
|
|
875
887
|
}
|
|
876
888
|
}
|
|
877
889
|
return {
|
package/dist/esm/globals.mjs
CHANGED
|
@@ -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"] = "
|
|
6
|
+
GlobalNames["__root"] = "--root";
|
|
5
7
|
GlobalNames["symbol"] = "symbol";
|
|
6
8
|
})(GlobalNames || (GlobalNames = {}));
|
|
7
9
|
export const NoNetText = 'NO_NET';
|
package/dist/esm/helpers.mjs
CHANGED
|
@@ -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(
|
|
172
|
+
nets.forEach(item => console.log(item.join(" | ")));
|
|
174
173
|
}
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
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('
|
|
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('
|
|
225
|
+
dumpData && writeFileSync(dumpDirectory + 'raw-render.txt', renderLogger.dump());
|
|
242
226
|
svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
|
|
243
227
|
if (outputPath) {
|
|
244
228
|
if (fileExtension === 'svg') {
|
package/dist/esm/layout.mjs
CHANGED
|
@@ -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);
|
|
@@ -1391,7 +1391,7 @@ export class RenderFrame extends RenderObject {
|
|
|
1391
1391
|
padding = milsToMM(100);
|
|
1392
1392
|
gap = milsToMM(100);
|
|
1393
1393
|
borderWidth = numeric(5);
|
|
1394
|
-
direction = FramePlotDirection.
|
|
1394
|
+
direction = FramePlotDirection.Row;
|
|
1395
1395
|
width = null;
|
|
1396
1396
|
height = null;
|
|
1397
1397
|
subgraphId = "";
|
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) {
|
package/dist/esm/sizing.mjs
CHANGED
|
@@ -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:
|
|
92
|
-
height:
|
|
94
|
+
width: finalWidth,
|
|
95
|
+
height: finalHeight,
|
|
93
96
|
box: textbox,
|
|
94
97
|
};
|
|
95
98
|
measureTextSizeCacheHits[key] = 0;
|