circuitscript 0.1.16 → 0.1.18
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 +2 -1
- package/dist/cjs/draw_symbols.js +18 -17
- package/dist/cjs/execute.js +45 -26
- package/dist/cjs/export.js +3 -3
- package/dist/cjs/globals.js +1 -0
- package/dist/cjs/graph.js +101 -27
- package/dist/cjs/helpers.js +55 -22
- package/dist/cjs/layout.js +6 -1
- package/dist/cjs/objects/ClassComponent.js +27 -20
- package/dist/cjs/objects/ExecutionScope.js +9 -4
- package/dist/cjs/objects/Net.js +2 -1
- package/dist/cjs/objects/PinDefinition.js +55 -3
- package/dist/cjs/objects/types.js +17 -1
- package/dist/cjs/visitor.js +78 -20
- package/dist/esm/BaseVisitor.js +2 -1
- package/dist/esm/draw_symbols.js +18 -17
- package/dist/esm/execute.js +46 -27
- package/dist/esm/export.js +1 -1
- package/dist/esm/globals.js +1 -0
- package/dist/esm/graph.js +79 -28
- package/dist/esm/helpers.js +46 -21
- package/dist/esm/layout.js +6 -1
- package/dist/esm/objects/ClassComponent.js +28 -21
- package/dist/esm/objects/ExecutionScope.js +9 -4
- package/dist/esm/objects/Net.js +2 -1
- package/dist/esm/objects/PinDefinition.js +53 -2
- package/dist/esm/objects/types.js +16 -0
- package/dist/esm/visitor.js +80 -22
- package/dist/libs/std.cst +3 -2
- package/dist/types/BaseVisitor.d.ts +2 -1
- package/dist/types/draw_symbols.d.ts +13 -7
- package/dist/types/execute.d.ts +7 -7
- package/dist/types/export.d.ts +2 -2
- package/dist/types/globals.d.ts +1 -0
- package/dist/types/graph.d.ts +2 -1
- package/dist/types/helpers.d.ts +15 -2
- package/dist/types/layout.d.ts +2 -1
- package/dist/types/objects/ClassComponent.d.ts +8 -8
- package/dist/types/objects/ExecutionScope.d.ts +7 -6
- package/dist/types/objects/Net.d.ts +3 -2
- package/dist/types/objects/PinDefinition.d.ts +17 -2
- package/dist/types/objects/types.d.ts +17 -2
- package/dist/types/visitor.d.ts +1 -0
- package/libs/std.cst +3 -2
- package/package.json +2 -1
package/dist/esm/execute.js
CHANGED
|
@@ -3,7 +3,7 @@ import { ClassComponent, ModuleComponent } from './objects/ClassComponent.js';
|
|
|
3
3
|
import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.js';
|
|
4
4
|
import { Net } from './objects/Net.js';
|
|
5
5
|
import { numeric, NumericValue } from './objects/ParamDefinition.js';
|
|
6
|
-
import { PortSide } from './objects/PinDefinition.js';
|
|
6
|
+
import { PinId, PortSide } from './objects/PinDefinition.js';
|
|
7
7
|
import { AnyReference, CFunctionEntry, DeclaredReference, Direction } from './objects/types.js';
|
|
8
8
|
import { Wire } from './objects/Wire.js';
|
|
9
9
|
import { Frame } from './objects/Frame.js';
|
|
@@ -151,7 +151,7 @@ export class ExecutionContext {
|
|
|
151
151
|
const tmpArrangeRight = [];
|
|
152
152
|
pins.forEach((pin, index) => {
|
|
153
153
|
const useArray = (index % 2 === 0) ? tmpArrangeLeft : tmpArrangeRight;
|
|
154
|
-
useArray.push(
|
|
154
|
+
useArray.push(pin.id);
|
|
155
155
|
});
|
|
156
156
|
const arrangeProp = new Map([
|
|
157
157
|
[SymbolPinSide.Left, tmpArrangeLeft],
|
|
@@ -161,11 +161,9 @@ export class ExecutionContext {
|
|
|
161
161
|
}
|
|
162
162
|
if (props.arrange !== null) {
|
|
163
163
|
component.arrangeProps = this.removeArrangePropDuplicates(props.arrange);
|
|
164
|
-
const arrangePropPins = this.getArrangePropPins(component.arrangeProps)
|
|
165
|
-
return item.toNumber();
|
|
166
|
-
});
|
|
164
|
+
const arrangePropPins = this.getArrangePropPins(component.arrangeProps);
|
|
167
165
|
pins.forEach(pin => {
|
|
168
|
-
if (arrangePropPins.
|
|
166
|
+
if (arrangePropPins.find(id => id.equals(pin.id)) === undefined) {
|
|
169
167
|
this.logWarning(`Pin ${pin.id} is not specified in arrange property`);
|
|
170
168
|
}
|
|
171
169
|
});
|
|
@@ -182,6 +180,7 @@ export class ExecutionContext {
|
|
|
182
180
|
});
|
|
183
181
|
if (component.typeProp === ComponentTypes.net) {
|
|
184
182
|
const netName = paramsMap.get(ParamKeys.net_name);
|
|
183
|
+
const netType = paramsMap.get(ParamKeys.net_type);
|
|
185
184
|
let priority = 0;
|
|
186
185
|
if (paramsMap.has(ParamKeys.priority)) {
|
|
187
186
|
priority = paramsMap.get(ParamKeys.priority).toNumber();
|
|
@@ -193,21 +192,26 @@ export class ExecutionContext {
|
|
|
193
192
|
this.log('net found', tmpNet.namespace, tmpNet.name);
|
|
194
193
|
}
|
|
195
194
|
else {
|
|
196
|
-
tmpNet = new Net(this.netNamespace, netName, priority);
|
|
195
|
+
tmpNet = new Net(this.netNamespace, netName, priority, netType);
|
|
197
196
|
this.log('net not found, added net instance', tmpNet.namespace, tmpNet.name);
|
|
198
197
|
}
|
|
199
|
-
const defaultPin = 1;
|
|
198
|
+
const defaultPin = new PinId(1);
|
|
200
199
|
this.scope.setNet(component, defaultPin, tmpNet);
|
|
201
200
|
this.log('set net', netName, 'component', component, defaultPin);
|
|
202
201
|
}
|
|
203
202
|
const { pins: pinSides, maxPositions } = getPortSide(component.pins, component.arrangeProps);
|
|
204
203
|
component.pinsMaxPositions = maxPositions;
|
|
204
|
+
const pinIdKeys = Array.from(component.pins.keys());
|
|
205
205
|
pinSides.forEach(({ pinId, side, position }) => {
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
const matchedPinId = pinIdKeys.find(id => id.equals(pinId));
|
|
207
|
+
if (matchedPinId) {
|
|
208
|
+
const tmpPin = component.pins.get(matchedPinId);
|
|
208
209
|
tmpPin.side = side;
|
|
209
210
|
tmpPin.position = position;
|
|
210
211
|
}
|
|
212
|
+
else {
|
|
213
|
+
throw 'Not found!';
|
|
214
|
+
}
|
|
211
215
|
});
|
|
212
216
|
this.scope.instances.set(instanceName, component);
|
|
213
217
|
const pinsOutput = pins.map((pin) => {
|
|
@@ -230,15 +234,32 @@ export class ExecutionContext {
|
|
|
230
234
|
if (!Array.isArray(items)) {
|
|
231
235
|
items = [items];
|
|
232
236
|
}
|
|
237
|
+
items = items.map(item => {
|
|
238
|
+
if (item instanceof NumericValue) {
|
|
239
|
+
item = item.toNumber();
|
|
240
|
+
}
|
|
241
|
+
if (item instanceof PinId) {
|
|
242
|
+
return item;
|
|
243
|
+
}
|
|
244
|
+
else if (PinId.isPinIdType(item)) {
|
|
245
|
+
return new PinId(item);
|
|
246
|
+
}
|
|
247
|
+
return item;
|
|
248
|
+
});
|
|
249
|
+
arrangeProp.set(side, items);
|
|
250
|
+
if (!Array.isArray(items)) {
|
|
251
|
+
items = [items];
|
|
252
|
+
}
|
|
233
253
|
const uniqueItems = [];
|
|
234
254
|
items.forEach(item => {
|
|
235
|
-
if (item instanceof
|
|
236
|
-
|
|
237
|
-
|
|
255
|
+
if (item instanceof PinId) {
|
|
256
|
+
const found = seenIds.find(id => id.equals(item));
|
|
257
|
+
if (!found) {
|
|
258
|
+
seenIds.push(item);
|
|
238
259
|
uniqueItems.push(item);
|
|
239
260
|
}
|
|
240
261
|
else {
|
|
241
|
-
this.logWarning(`Pin ${item.
|
|
262
|
+
this.logWarning(`Pin ${item.toString()} specified more than once in arrange property`);
|
|
242
263
|
}
|
|
243
264
|
}
|
|
244
265
|
else {
|
|
@@ -261,7 +282,7 @@ export class ExecutionContext {
|
|
|
261
282
|
const items = arrangeProps.get(side);
|
|
262
283
|
if (items) {
|
|
263
284
|
items.forEach(item => {
|
|
264
|
-
if (item instanceof
|
|
285
|
+
if (item instanceof PinId) {
|
|
265
286
|
pins.push(item);
|
|
266
287
|
}
|
|
267
288
|
});
|
|
@@ -348,13 +369,12 @@ export class ExecutionContext {
|
|
|
348
369
|
if (pinId === null) {
|
|
349
370
|
usePinId = component.getDefaultPin();
|
|
350
371
|
}
|
|
372
|
+
else if (component.hasPin(pinId)) {
|
|
373
|
+
usePinId = component.getPin(pinId);
|
|
374
|
+
}
|
|
351
375
|
else {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
throw 'Invalid pin number ' + pinId + ' in ' + component;
|
|
357
|
-
}
|
|
376
|
+
throw new RuntimeExecutionError('Invalid pin number '
|
|
377
|
+
+ pinId + ' in ' + component);
|
|
358
378
|
}
|
|
359
379
|
this.scope.setCurrent(component, usePinId);
|
|
360
380
|
if (!this.scope.hasNet(component, pinId)) {
|
|
@@ -383,7 +403,7 @@ export class ExecutionContext {
|
|
|
383
403
|
const cloneInstanceName = component.instanceName + ':' + idNum;
|
|
384
404
|
this.scope.instances.set(cloneInstanceName, componentCopy);
|
|
385
405
|
componentCopy.instanceName = cloneInstanceName;
|
|
386
|
-
const defaultPin = 1;
|
|
406
|
+
const defaultPin = new PinId(1);
|
|
387
407
|
if (this.scope.getNet(component, defaultPin) === null) {
|
|
388
408
|
const foundNet = this.resolveComponentPinNet(component, defaultPin);
|
|
389
409
|
if (foundNet !== null) {
|
|
@@ -602,7 +622,7 @@ export class ExecutionContext {
|
|
|
602
622
|
else if (type === ReferenceTypes.instance) {
|
|
603
623
|
const tmpComponent = parentValue;
|
|
604
624
|
if (tmpComponent.typeProp === ComponentTypes.net) {
|
|
605
|
-
const usedNet = this.scope.getNet(tmpComponent, 1);
|
|
625
|
+
const usedNet = this.scope.getNet(tmpComponent, new PinId(1));
|
|
606
626
|
if (usedNet) {
|
|
607
627
|
const trailerValue = trailers.join(".");
|
|
608
628
|
useValue = usedNet.params.get(trailerValue) ?? null;
|
|
@@ -696,7 +716,7 @@ export class ExecutionContext {
|
|
|
696
716
|
const linkRootComponent = true;
|
|
697
717
|
const tmpRoot = childScope.componentRoot;
|
|
698
718
|
if (linkRootComponent) {
|
|
699
|
-
const netConnectedToRoot = childScope.getNet(tmpRoot, 1);
|
|
719
|
+
const netConnectedToRoot = childScope.getNet(tmpRoot, new PinId(1));
|
|
700
720
|
if (netConnectedToRoot !== null) {
|
|
701
721
|
let currentNet = this.scope.getNet(currentComponent, currentPin);
|
|
702
722
|
if (currentNet === null) {
|
|
@@ -1043,10 +1063,9 @@ export function getPortSide(pins, arrangeProps) {
|
|
|
1043
1063
|
position += item[0].toNumber();
|
|
1044
1064
|
}
|
|
1045
1065
|
else {
|
|
1046
|
-
|
|
1047
|
-
if (existingPinIds.indexOf(itemValue) !== -1) {
|
|
1066
|
+
if (existingPinIds.find(id => id.equals(item))) {
|
|
1048
1067
|
result.push({
|
|
1049
|
-
pinId:
|
|
1068
|
+
pinId: item,
|
|
1050
1069
|
side: useSide,
|
|
1051
1070
|
position,
|
|
1052
1071
|
order: counter
|
package/dist/esm/export.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NoNetText } from "./globals.js";
|
|
2
2
|
import { NumericValue } from "./objects/ParamDefinition.js";
|
|
3
|
-
export function
|
|
3
|
+
export function generateKiCadNetList(netlist) {
|
|
4
4
|
const componentsList = [];
|
|
5
5
|
const nets = {};
|
|
6
6
|
const missingFootprints = [];
|
package/dist/esm/globals.js
CHANGED
|
@@ -12,6 +12,7 @@ export var ParamKeys;
|
|
|
12
12
|
(function (ParamKeys) {
|
|
13
13
|
ParamKeys["priority"] = "priority";
|
|
14
14
|
ParamKeys["net_name"] = "net_name";
|
|
15
|
+
ParamKeys["net_type"] = "net_type";
|
|
15
16
|
ParamKeys["flip"] = "flip";
|
|
16
17
|
ParamKeys["flipX"] = "flipX";
|
|
17
18
|
ParamKeys["flipY"] = "flipY";
|
package/dist/esm/graph.js
CHANGED
|
@@ -5,7 +5,10 @@ import { milsToMM } from "./helpers.js";
|
|
|
5
5
|
import { RenderFrame, RenderComponent, applyComponentParamsToSymbol, RenderWire } from "./layout.js";
|
|
6
6
|
import { SequenceAction, FrameAction } from "./objects/ExecutionScope.js";
|
|
7
7
|
import { Frame, FixedFrameIds, FrameParamKeys } from "./objects/Frame.js";
|
|
8
|
-
import { numeric
|
|
8
|
+
import { numeric } from "./objects/ParamDefinition.js";
|
|
9
|
+
import { NetTypes, TypeProps } from "./objects/types.js";
|
|
10
|
+
import Matrix, { solve } from "ml-matrix";
|
|
11
|
+
import { getPinDefinition } from "./objects/PinDefinition.js";
|
|
9
12
|
export class NetGraph {
|
|
10
13
|
logger;
|
|
11
14
|
constructor(logger) {
|
|
@@ -73,7 +76,7 @@ export class NetGraph {
|
|
|
73
76
|
if (prevNodeType === RenderItemType.Component) {
|
|
74
77
|
const matchingItem = nets.find(([comp, pin]) => {
|
|
75
78
|
return comp.instanceName === previousNode
|
|
76
|
-
&& pin
|
|
79
|
+
&& pin.equals(previousPin);
|
|
77
80
|
});
|
|
78
81
|
if (matchingItem !== undefined) {
|
|
79
82
|
useNet = matchingItem[2];
|
|
@@ -188,21 +191,71 @@ export class NetGraph {
|
|
|
188
191
|
this.logger.add(params.join(' '));
|
|
189
192
|
}
|
|
190
193
|
generateNetGraph(nets) {
|
|
191
|
-
const
|
|
192
|
-
|
|
194
|
+
const uniqueNets = new Set(nets.map(([, , net]) => net));
|
|
195
|
+
const components = new Set(nets.map(([component, ,]) => component));
|
|
196
|
+
const tmpNets = Array.from(uniqueNets);
|
|
197
|
+
const gndNet = tmpNets.find(item => {
|
|
198
|
+
return item.toString() === '/GND';
|
|
193
199
|
});
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
const otherNets = tmpNets.filter(item => {
|
|
201
|
+
return item !== gndNet;
|
|
202
|
+
});
|
|
203
|
+
const netsIndexed = [];
|
|
204
|
+
if (gndNet) {
|
|
205
|
+
netsIndexed.push(gndNet);
|
|
206
|
+
}
|
|
207
|
+
netsIndexed.push(...otherNets);
|
|
208
|
+
const netsLength = netsIndexed.length;
|
|
209
|
+
const conductanceMatrix = Matrix.zeros(netsLength, netsLength);
|
|
210
|
+
components.forEach(item => {
|
|
211
|
+
if (item.typeProp === TypeProps.Resistor) {
|
|
212
|
+
const net1 = item.pinNets.get(1);
|
|
213
|
+
const net2 = item.pinNets.get(2);
|
|
214
|
+
const net1Index = netsIndexed.indexOf(net1);
|
|
215
|
+
const net2Index = netsIndexed.indexOf(net2);
|
|
216
|
+
const resistance = item.parameters.get('value');
|
|
217
|
+
const resistanceValue = resistance.toNumber();
|
|
218
|
+
const conductanceValue = 1 / resistanceValue;
|
|
219
|
+
const currentValue1 = conductanceMatrix.get(net1Index, net1Index);
|
|
220
|
+
const currentValue2 = conductanceMatrix.get(net2Index, net2Index);
|
|
221
|
+
const currentValue3 = conductanceMatrix.get(net1Index, net2Index);
|
|
222
|
+
const currentValue4 = conductanceMatrix.get(net2Index, net1Index);
|
|
223
|
+
conductanceMatrix.set(net1Index, net1Index, currentValue1 + conductanceValue);
|
|
224
|
+
conductanceMatrix.set(net2Index, net2Index, currentValue2 + conductanceValue);
|
|
225
|
+
conductanceMatrix.set(net1Index, net2Index, currentValue3 - conductanceValue);
|
|
226
|
+
conductanceMatrix.set(net2Index, net1Index, currentValue4 - conductanceValue);
|
|
203
227
|
}
|
|
204
|
-
graph.setEdge(netNodeName, componentNodeName, [component, pin, net]);
|
|
205
228
|
});
|
|
229
|
+
if (gndNet) {
|
|
230
|
+
conductanceMatrix.removeColumn(0);
|
|
231
|
+
conductanceMatrix.removeRow(0);
|
|
232
|
+
}
|
|
233
|
+
const netsWithoutGnd = netsIndexed.filter(net => {
|
|
234
|
+
return (net !== gndNet);
|
|
235
|
+
});
|
|
236
|
+
const netResistances = new Map();
|
|
237
|
+
try {
|
|
238
|
+
netsWithoutGnd.forEach((net, index) => {
|
|
239
|
+
if (net.type === NetTypes.Source) {
|
|
240
|
+
const currentVector = Matrix.zeros(netsWithoutGnd.length, 1);
|
|
241
|
+
currentVector.set(index, 0, 1);
|
|
242
|
+
const solution = solve(conductanceMatrix, currentVector);
|
|
243
|
+
for (let i = 0; i < solution.rows; i++) {
|
|
244
|
+
const resValue = solution.get(i, 0);
|
|
245
|
+
if (resValue > 0) {
|
|
246
|
+
const targetNet = netsIndexed[i];
|
|
247
|
+
netResistances.set(targetNet, resValue);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
nets,
|
|
257
|
+
netResistances,
|
|
258
|
+
};
|
|
206
259
|
}
|
|
207
260
|
findNodePaths(graph, startNode, endNode, seenNodes = []) {
|
|
208
261
|
const edges = graph.nodeEdges(startNode);
|
|
@@ -261,24 +314,22 @@ export function generateLayoutPinDefinition(component) {
|
|
|
261
314
|
useItems = [...items];
|
|
262
315
|
}
|
|
263
316
|
useItems.forEach(pinId => {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
addedPins.push(pinIdValue);
|
|
276
|
-
}
|
|
317
|
+
const existingPin = existingPinIds.find(pin => pin.equals(pinId));
|
|
318
|
+
if (existingPin) {
|
|
319
|
+
const pin = getPinDefinition(pins, existingPin);
|
|
320
|
+
symbolPinDefinitions.push({
|
|
321
|
+
side: key,
|
|
322
|
+
pinId: pinId,
|
|
323
|
+
text: pin.name,
|
|
324
|
+
position: pin.position,
|
|
325
|
+
pinType: pin.pinType,
|
|
326
|
+
});
|
|
327
|
+
addedPins.push(pinId);
|
|
277
328
|
}
|
|
278
329
|
});
|
|
279
330
|
}
|
|
280
331
|
const unplacedPins = existingPinIds.filter(pinId => {
|
|
281
|
-
return addedPins.
|
|
332
|
+
return addedPins.find(id => id.equals(pinId)) === undefined;
|
|
282
333
|
});
|
|
283
334
|
if (unplacedPins.length > 0) {
|
|
284
335
|
component._unplacedPins = unplacedPins;
|
package/dist/esm/helpers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { writeFileSync, createWriteStream, existsSync, mkdirSync } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import PDFDocument from "pdfkit";
|
|
4
|
-
import {
|
|
4
|
+
import { generateKiCadNetList, printTree } from "./export.js";
|
|
5
5
|
import { LayoutEngine } from "./layout.js";
|
|
6
6
|
import { parseFileWithVisitor } from "./parser.js";
|
|
7
7
|
import { generatePdfOutput, generateSvgOutput, renderSheetsToSVG } from "./render.js";
|
|
@@ -148,6 +148,12 @@ export async function validateScript(filePath, scriptData, options) {
|
|
|
148
148
|
return visitorResolver;
|
|
149
149
|
}
|
|
150
150
|
export async function renderScript(scriptData, outputPath, options) {
|
|
151
|
+
const parseHandlers = [
|
|
152
|
+
new KiCadNetListOutputHandler(),
|
|
153
|
+
];
|
|
154
|
+
return renderScriptCustom(scriptData, outputPath, options, parseHandlers);
|
|
155
|
+
}
|
|
156
|
+
export async function renderScriptCustom(scriptData, outputPath, options, parseHandlers) {
|
|
151
157
|
const { dumpNets = false, dumpData = false, showStats = false, environment } = options;
|
|
152
158
|
const errors = [];
|
|
153
159
|
const onErrorHandler = (message, context, error) => {
|
|
@@ -196,6 +202,12 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
196
202
|
printWarnings(visitor.getWarnings());
|
|
197
203
|
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
198
204
|
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
205
|
+
try {
|
|
206
|
+
visitor.annotateComponents();
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
throw new RenderError(`Error during component annotation: ${err}`, 'annotation');
|
|
210
|
+
}
|
|
199
211
|
if (dumpNets) {
|
|
200
212
|
const nets = visitor.dumpNets();
|
|
201
213
|
nets.forEach(item => console.log(item.join(" | ")));
|
|
@@ -208,12 +220,6 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
208
220
|
let svgOutput = "";
|
|
209
221
|
if (errors.length === 0) {
|
|
210
222
|
const { frameComponent } = visitor.applySheetFrameComponent();
|
|
211
|
-
try {
|
|
212
|
-
visitor.annotateComponents();
|
|
213
|
-
}
|
|
214
|
-
catch (err) {
|
|
215
|
-
throw new RenderError(`Error during component annotation: ${err}`, 'annotation');
|
|
216
|
-
}
|
|
217
223
|
const { sequence, nets } = visitor.getGraph();
|
|
218
224
|
const tmpSequence = generateDebugSequenceAction(sequence).map(item => sequenceActionString(item));
|
|
219
225
|
dumpData && writeFileSync(dumpDirectory + 'raw-sequence.txt', tmpSequence.join('\n'));
|
|
@@ -222,21 +228,18 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
222
228
|
let outputDefaultZoom = defaultZoomScale;
|
|
223
229
|
if (outputPath) {
|
|
224
230
|
fileExtension = path.extname(outputPath).substring(1);
|
|
225
|
-
if (fileExtension === "pdf") {
|
|
226
|
-
outputDefaultZoom = 1;
|
|
227
|
-
}
|
|
228
231
|
}
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
232
|
+
for (let i = 0; i < parseHandlers.length; i++) {
|
|
233
|
+
const handler = parseHandlers[i];
|
|
234
|
+
if (handler.beforeRender) {
|
|
235
|
+
const keepParsing = handler.parse(visitor, outputPath, fileExtension);
|
|
236
|
+
if (!keepParsing) {
|
|
237
|
+
return {
|
|
238
|
+
svgOutput: null,
|
|
239
|
+
errors
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
240
243
|
}
|
|
241
244
|
const logger = new Logger();
|
|
242
245
|
const graphEngine = new NetGraph(logger);
|
|
@@ -265,6 +268,9 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
265
268
|
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
266
269
|
dumpData && writeFileSync(dumpDirectory + 'raw-render.txt', renderLogger.dump());
|
|
267
270
|
try {
|
|
271
|
+
if (fileExtension === "pdf") {
|
|
272
|
+
outputDefaultZoom = 1;
|
|
273
|
+
}
|
|
268
274
|
svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
|
|
269
275
|
}
|
|
270
276
|
catch (err) {
|
|
@@ -315,6 +321,25 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
315
321
|
errors
|
|
316
322
|
};
|
|
317
323
|
}
|
|
324
|
+
export class ParseOutputHandler {
|
|
325
|
+
beforeRender = false;
|
|
326
|
+
afterRender = false;
|
|
327
|
+
}
|
|
328
|
+
export class KiCadNetListOutputHandler extends ParseOutputHandler {
|
|
329
|
+
beforeRender = true;
|
|
330
|
+
parse(visitor, outputPath, fileExtension) {
|
|
331
|
+
if (outputPath !== null && fileExtension === "net") {
|
|
332
|
+
const { tree: kiCadNetList, missingFootprints } = generateKiCadNetList(visitor.getNetList());
|
|
333
|
+
missingFootprints.forEach(entry => {
|
|
334
|
+
console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
|
|
335
|
+
});
|
|
336
|
+
writeFileSync(outputPath, printTree(kiCadNetList));
|
|
337
|
+
console.log('Generated file', outputPath);
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
318
343
|
export function detectJSModuleType() {
|
|
319
344
|
if (typeof __filename === 'undefined' &&
|
|
320
345
|
typeof __dirname === 'undefined') {
|
package/dist/esm/layout.js
CHANGED
|
@@ -6,6 +6,7 @@ import { Geometry, HorizontalAlign, VerticalAlign } from './geometry.js';
|
|
|
6
6
|
import { FixedFrameIds, Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.js';
|
|
7
7
|
import { areasOverlap, combineMaps, getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.js';
|
|
8
8
|
import { Direction } from './objects/types.js';
|
|
9
|
+
import { PinId } from './objects/PinDefinition.js';
|
|
9
10
|
import { milsToMM, UnitDimension } from './helpers.js';
|
|
10
11
|
import { numeric } from './objects/ParamDefinition.js';
|
|
11
12
|
import { generateLayoutPinDefinition, getWireName, RenderItemType } from './graph.js';
|
|
@@ -689,7 +690,11 @@ export class LayoutEngine {
|
|
|
689
690
|
}
|
|
690
691
|
if (subgraphEdges.length === 0) {
|
|
691
692
|
const [, node1] = graph.node(firstNodeId);
|
|
692
|
-
|
|
693
|
+
let defaultPin = new PinId(1);
|
|
694
|
+
if (node1 instanceof RenderComponent) {
|
|
695
|
+
defaultPin = node1.component.getDefaultPin();
|
|
696
|
+
}
|
|
697
|
+
this.placeNodeAtPosition(numeric(0), numeric(0), node1, defaultPin);
|
|
693
698
|
return;
|
|
694
699
|
}
|
|
695
700
|
let fixedNode;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { SymbolDrawingCommands } from '../draw_symbols.js';
|
|
2
|
-
import { PinDefinition, PinIdType } from './PinDefinition.js';
|
|
2
|
+
import { PinDefinition, PinId, PinIdType } from './PinDefinition.js';
|
|
3
3
|
import { PinTypes } from './PinTypes.js';
|
|
4
4
|
import { ParamKeys } from '../globals.js';
|
|
5
|
+
import { RuntimeExecutionError } from '../utils.js';
|
|
5
6
|
export class ClassComponent {
|
|
6
7
|
instanceName;
|
|
7
8
|
numPins;
|
|
@@ -35,47 +36,53 @@ export class ClassComponent {
|
|
|
35
36
|
setupPins() {
|
|
36
37
|
for (let i = 1; i < this.numPins + 1; i++) {
|
|
37
38
|
const pinIndex = i;
|
|
38
|
-
this.pins.set(pinIndex, new PinDefinition(pinIndex, PinIdType.Int, pinIndex.toString(), PinTypes.Any));
|
|
39
|
+
this.pins.set(new PinId(pinIndex), new PinDefinition(pinIndex, PinIdType.Int, pinIndex.toString(), PinTypes.Any));
|
|
39
40
|
}
|
|
40
41
|
this.refreshPinsCache();
|
|
41
42
|
}
|
|
42
43
|
getDefaultPin() {
|
|
43
|
-
|
|
44
|
+
const pins = Array.from(this.pins.keys());
|
|
45
|
+
pins.sort();
|
|
46
|
+
return pins[0];
|
|
44
47
|
}
|
|
45
48
|
hasPin(pinId) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
49
|
+
for (const [pin, pinDef] of this.pins) {
|
|
50
|
+
if (pin.equals(pinId)) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (pinId.getType() === PinIdType.Str && (pinDef.name === pinId.getValue() ||
|
|
54
|
+
pinDef.altNames.indexOf(pinId.getValue()) !== -1)) {
|
|
55
|
+
return true;
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
return false;
|
|
58
59
|
}
|
|
59
60
|
getPin(pinId) {
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
for (const [pin,] of this.pins) {
|
|
62
|
+
if (pin.equals(pinId)) {
|
|
63
|
+
return pin;
|
|
64
|
+
}
|
|
62
65
|
}
|
|
63
|
-
|
|
66
|
+
if (pinId.getType() === PinIdType.Str) {
|
|
67
|
+
const pinIdStringValue = pinId.getValue();
|
|
64
68
|
for (const [pin, pinDef] of this.pins) {
|
|
65
|
-
if (pinDef.name ===
|
|
66
|
-
pinDef.altNames.indexOf(
|
|
69
|
+
if (pinDef.name === pinIdStringValue ||
|
|
70
|
+
pinDef.altNames.indexOf(pinIdStringValue) !== -1) {
|
|
67
71
|
return pin;
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
|
-
return -1;
|
|
71
74
|
}
|
|
75
|
+
throw new RuntimeExecutionError(`Could not find pin '${pinId}' on component '${this.instanceName}'`);
|
|
72
76
|
}
|
|
73
77
|
getNextPinAfter(pinIndex) {
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
const pins = Array.from(this.pins.keys());
|
|
79
|
+
pins.sort();
|
|
80
|
+
const index = pins.findIndex(tmp => tmp.equals(pinIndex));
|
|
81
|
+
if (index + 1 < pins.length) {
|
|
82
|
+
return pins[index + 1];
|
|
76
83
|
}
|
|
77
84
|
else {
|
|
78
|
-
return
|
|
85
|
+
return this.getDefaultPin();
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
setParam(key, value) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Property_key_exprContext } from '../antlr/CircuitScriptParser.js';
|
|
2
|
+
import { PinId } from './PinDefinition.js';
|
|
3
|
+
import { RuntimeExecutionError } from '../utils.js';
|
|
2
4
|
export class ExecutionScope {
|
|
3
5
|
scopeId;
|
|
4
6
|
nets = [];
|
|
@@ -32,8 +34,11 @@ export class ExecutionScope {
|
|
|
32
34
|
return scope;
|
|
33
35
|
}
|
|
34
36
|
findNet(component, pin) {
|
|
37
|
+
if (!(pin instanceof PinId)) {
|
|
38
|
+
throw new RuntimeExecutionError('Invalid value for PinId: ' + pin);
|
|
39
|
+
}
|
|
35
40
|
return this.nets.find(([tmpComponent, tmpPin]) => {
|
|
36
|
-
return tmpComponent.isEqual(component) && tmpPin
|
|
41
|
+
return tmpComponent.isEqual(component) && tmpPin.equals(pin);
|
|
37
42
|
});
|
|
38
43
|
}
|
|
39
44
|
getNetWithName(name) {
|
|
@@ -81,8 +86,8 @@ export class ExecutionScope {
|
|
|
81
86
|
const sortedNet = [...this.nets].sort((a, b) => {
|
|
82
87
|
const netA = a[2];
|
|
83
88
|
const netB = b[2];
|
|
84
|
-
const netAId = netA.
|
|
85
|
-
const netBId = netB.
|
|
89
|
+
const netAId = netA.toString();
|
|
90
|
+
const netBId = netB.toString();
|
|
86
91
|
if (netAId > netBId) {
|
|
87
92
|
return 1;
|
|
88
93
|
}
|
|
@@ -94,7 +99,7 @@ export class ExecutionScope {
|
|
|
94
99
|
}
|
|
95
100
|
});
|
|
96
101
|
return sortedNet.map(([component, pin, net]) => {
|
|
97
|
-
return [net.toString(), component.instanceName, pin];
|
|
102
|
+
return [net.toString(), component.instanceName, pin.value];
|
|
98
103
|
});
|
|
99
104
|
}
|
|
100
105
|
printNets() {
|
package/dist/esm/objects/Net.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NetTypes } from "./types.js";
|
|
1
2
|
export class Net {
|
|
2
3
|
name;
|
|
3
4
|
baseName;
|
|
@@ -5,7 +6,7 @@ export class Net {
|
|
|
5
6
|
priority;
|
|
6
7
|
type;
|
|
7
8
|
params = new Map();
|
|
8
|
-
constructor(namespace, name, priority = 0, type =
|
|
9
|
+
constructor(namespace, name, priority = 0, type = NetTypes.Any) {
|
|
9
10
|
if (namespace.indexOf(' ') !== -1) {
|
|
10
11
|
throw "Invalid net namespace provided";
|
|
11
12
|
}
|