circuitscript 0.1.15 → 0.1.17

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.
Files changed (49) hide show
  1. package/dist/cjs/BaseVisitor.js +98 -35
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +3 -3
  3. package/dist/cjs/antlr/CircuitScriptParser.js +868 -757
  4. package/dist/cjs/builtinMethods.js +11 -1
  5. package/dist/cjs/draw_symbols.js +18 -17
  6. package/dist/cjs/execute.js +58 -31
  7. package/dist/cjs/globals.js +4 -1
  8. package/dist/cjs/graph.js +372 -0
  9. package/dist/cjs/helpers.js +6 -2
  10. package/dist/cjs/layout.js +18 -259
  11. package/dist/cjs/objects/ClassComponent.js +27 -20
  12. package/dist/cjs/objects/ExecutionScope.js +7 -2
  13. package/dist/cjs/objects/Net.js +1 -1
  14. package/dist/cjs/objects/PinDefinition.js +55 -3
  15. package/dist/cjs/objects/types.js +42 -6
  16. package/dist/cjs/visitor.js +88 -48
  17. package/dist/esm/BaseVisitor.js +98 -35
  18. package/dist/esm/antlr/CircuitScriptLexer.js +3 -3
  19. package/dist/esm/antlr/CircuitScriptParser.js +864 -755
  20. package/dist/esm/antlr/CircuitScriptVisitor.js +2 -0
  21. package/dist/esm/builtinMethods.js +11 -1
  22. package/dist/esm/draw_symbols.js +18 -17
  23. package/dist/esm/execute.js +60 -33
  24. package/dist/esm/globals.js +3 -0
  25. package/dist/esm/graph.js +344 -0
  26. package/dist/esm/helpers.js +6 -2
  27. package/dist/esm/layout.js +14 -235
  28. package/dist/esm/objects/ClassComponent.js +28 -21
  29. package/dist/esm/objects/ExecutionScope.js +7 -2
  30. package/dist/esm/objects/Net.js +1 -1
  31. package/dist/esm/objects/PinDefinition.js +53 -2
  32. package/dist/esm/objects/types.js +42 -6
  33. package/dist/esm/visitor.js +90 -50
  34. package/dist/libs/std.cst +3 -2
  35. package/dist/types/BaseVisitor.d.ts +5 -2
  36. package/dist/types/antlr/CircuitScriptParser.d.ts +42 -26
  37. package/dist/types/antlr/CircuitScriptVisitor.d.ts +4 -0
  38. package/dist/types/draw_symbols.d.ts +13 -7
  39. package/dist/types/execute.d.ts +12 -12
  40. package/dist/types/globals.d.ts +4 -1
  41. package/dist/types/graph.d.ts +29 -0
  42. package/dist/types/layout.d.ts +4 -9
  43. package/dist/types/objects/ClassComponent.d.ts +8 -8
  44. package/dist/types/objects/ExecutionScope.d.ts +8 -7
  45. package/dist/types/objects/Net.d.ts +2 -2
  46. package/dist/types/objects/PinDefinition.d.ts +17 -2
  47. package/dist/types/objects/types.d.ts +31 -7
  48. package/libs/std.cst +3 -2
  49. package/package.json +2 -1
@@ -0,0 +1,372 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.RenderItemType = exports.generateLayoutPinDefinition = exports.getWireName = exports.NetGraph = void 0;
27
+ const graphlib_1 = require("@dagrejs/graphlib");
28
+ const draw_symbols_js_1 = require("./draw_symbols.js");
29
+ const globals_js_1 = require("./globals.js");
30
+ const helpers_js_1 = require("./helpers.js");
31
+ const layout_js_1 = require("./layout.js");
32
+ const ExecutionScope_js_1 = require("./objects/ExecutionScope.js");
33
+ const Frame_js_1 = require("./objects/Frame.js");
34
+ const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
35
+ const types_js_1 = require("./objects/types.js");
36
+ const ml_matrix_1 = __importStar(require("ml-matrix"));
37
+ const PinDefinition_js_1 = require("./objects/PinDefinition.js");
38
+ class NetGraph {
39
+ constructor(logger) {
40
+ this.logger = logger;
41
+ }
42
+ generateLayoutGraph(sequence, nets) {
43
+ this.print('===== creating graph and populating with nodes =====');
44
+ let previousNode = null;
45
+ let previousPin = null;
46
+ const graph = new graphlib_1.Graph({
47
+ directed: true,
48
+ compound: true,
49
+ });
50
+ this.print('sequence length:', sequence.length);
51
+ const baseFrame = new layout_js_1.RenderFrame(new Frame_js_1.Frame(Frame_js_1.FixedFrameIds.BaseFrame));
52
+ const frameStack = [baseFrame];
53
+ const containerFrames = [baseFrame];
54
+ sequence.forEach((sequenceStep, index) => {
55
+ const action = sequenceStep[0];
56
+ let tmpComponent;
57
+ switch (action) {
58
+ case ExecutionScope_js_1.SequenceAction.To:
59
+ case ExecutionScope_js_1.SequenceAction.At: {
60
+ this.print(...sequenceStep);
61
+ const [, component, pin] = sequenceStep;
62
+ const tmpInstanceName = component.instanceName;
63
+ if (!graph.hasNode(tmpInstanceName)) {
64
+ this.print('create instance', tmpInstanceName);
65
+ const { displayProp = null } = component;
66
+ let tmpSymbol;
67
+ if (displayProp instanceof draw_symbols_js_1.SymbolDrawing) {
68
+ tmpSymbol = new draw_symbols_js_1.SymbolPlaceholder(displayProp);
69
+ tmpSymbol.drawing.logger = this.logger;
70
+ }
71
+ else {
72
+ const symbolPinDefinitions = generateLayoutPinDefinition(component);
73
+ if (component.typeProp === globals_js_1.ComponentTypes.module) {
74
+ tmpSymbol = new draw_symbols_js_1.SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
75
+ }
76
+ else {
77
+ tmpSymbol = new draw_symbols_js_1.SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
78
+ }
79
+ }
80
+ (0, layout_js_1.applyComponentParamsToSymbol)(component, tmpSymbol);
81
+ tmpSymbol.refreshDrawing();
82
+ const { width: useWidth, height: useHeight } = tmpSymbol.size();
83
+ tmpComponent = new layout_js_1.RenderComponent(component, useWidth, useHeight);
84
+ tmpComponent.symbol = tmpSymbol;
85
+ graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, index]);
86
+ const currentFrame = frameStack[frameStack.length - 1];
87
+ currentFrame && currentFrame.innerItems.push(tmpComponent);
88
+ }
89
+ if (action === ExecutionScope_js_1.SequenceAction.To && previousNode && previousPin) {
90
+ this.setGraphEdge(graph, previousNode, tmpInstanceName, makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, index));
91
+ }
92
+ previousNode = tmpInstanceName;
93
+ previousPin = pin;
94
+ break;
95
+ }
96
+ case ExecutionScope_js_1.SequenceAction.Wire: {
97
+ const [, wireId, wireSegments] = sequenceStep;
98
+ let useNet;
99
+ if (previousNode !== null) {
100
+ const [prevNodeType, prevNodeItem] = graph.node(previousNode);
101
+ if (prevNodeType === RenderItemType.Component) {
102
+ const matchingItem = nets.find(([comp, pin]) => {
103
+ return comp.instanceName === previousNode
104
+ && pin.equals(previousPin);
105
+ });
106
+ if (matchingItem !== undefined) {
107
+ useNet = matchingItem[2];
108
+ }
109
+ }
110
+ else if (prevNodeType === RenderItemType.Wire) {
111
+ useNet = prevNodeItem.net;
112
+ }
113
+ }
114
+ const wire = new layout_js_1.RenderWire(useNet, (0, ParamDefinition_js_1.numeric)(0), (0, ParamDefinition_js_1.numeric)(0), wireSegments);
115
+ wire.id = wireId;
116
+ wire.netName = useNet.toString();
117
+ const wireName = getWireName(wire.id);
118
+ graph.setNode(wireName, [RenderItemType.Wire, wire, index]);
119
+ this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, index));
120
+ previousNode = wireName;
121
+ previousPin = 1;
122
+ const wireSegmentsInfo = wireSegments.map(item => {
123
+ const tmp = {
124
+ direction: item.direction,
125
+ value: item.value,
126
+ };
127
+ if (item.valueXY) {
128
+ tmp.valueXY = item.valueXY;
129
+ }
130
+ if (item.until) {
131
+ tmp.until = [item.until[0].toString(), item.until[1]];
132
+ }
133
+ return tmp;
134
+ });
135
+ this.print(ExecutionScope_js_1.SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
136
+ break;
137
+ }
138
+ case ExecutionScope_js_1.SequenceAction.WireJump: {
139
+ this.print(...sequenceStep);
140
+ const wireId = sequenceStep[1];
141
+ const wireName = getWireName(wireId);
142
+ let wirePin = 1;
143
+ if (sequenceStep.length === 3) {
144
+ wirePin = sequenceStep[2];
145
+ }
146
+ previousNode = wireName;
147
+ previousPin = wirePin;
148
+ break;
149
+ }
150
+ case ExecutionScope_js_1.SequenceAction.Frame: {
151
+ const [, frameObject, frameAction] = sequenceStep;
152
+ if (frameAction === ExecutionScope_js_1.FrameAction.Enter) {
153
+ const prevFrame = frameStack[frameStack.length - 1];
154
+ const newFrame = new layout_js_1.RenderFrame(frameObject);
155
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Direction)) {
156
+ newFrame.direction =
157
+ frameObject.parameters.get(Frame_js_1.FrameParamKeys.Direction);
158
+ }
159
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Padding)) {
160
+ newFrame.padding = (0, helpers_js_1.milsToMM)(frameObject.parameters.get(Frame_js_1.FrameParamKeys.Padding));
161
+ }
162
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Border)) {
163
+ newFrame.borderWidth =
164
+ frameObject.parameters.get(Frame_js_1.FrameParamKeys.Border);
165
+ }
166
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Width)) {
167
+ newFrame.width = (0, helpers_js_1.milsToMM)(frameObject.parameters.get(Frame_js_1.FrameParamKeys.Width));
168
+ }
169
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Height)) {
170
+ newFrame.height = (0, helpers_js_1.milsToMM)(frameObject.parameters.get(Frame_js_1.FrameParamKeys.Height));
171
+ }
172
+ containerFrames.push(newFrame);
173
+ frameStack.push(newFrame);
174
+ prevFrame && prevFrame.innerItems.push(newFrame);
175
+ }
176
+ else if (frameAction === ExecutionScope_js_1.FrameAction.Exit) {
177
+ frameStack.pop();
178
+ }
179
+ break;
180
+ }
181
+ }
182
+ });
183
+ this.print('===== done populating graph =====');
184
+ this.print('');
185
+ const logNodesAndEdges = true;
186
+ if (logNodesAndEdges) {
187
+ this.print('===== graph edges =====');
188
+ const allEdges = graph.edges();
189
+ allEdges.forEach(edge => {
190
+ const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
191
+ this.print(nodeId1, 'pin', pin1, '-----', nodeId2, 'pin', pin2);
192
+ });
193
+ this.print('===== end edges =====');
194
+ this.print();
195
+ this.print('===== graph nodes =====');
196
+ const nodes = graph.nodes();
197
+ nodes.forEach(node => {
198
+ this.print(`name:${node}, value:${graph.node(node)}`);
199
+ });
200
+ this.print('===== end nodes =====');
201
+ this.print('');
202
+ }
203
+ return {
204
+ graph,
205
+ containerFrames,
206
+ };
207
+ }
208
+ setGraphEdge(graph, node1, node2, edgeValue) {
209
+ if (!graph.isDirected && graph.hasEdge(node1, node2)) {
210
+ this.print(`Warning: edge already exists ${node1} ${node2}`);
211
+ }
212
+ graph.setEdge(node1, node2, edgeValue);
213
+ this.print(`created edge: node1:${node1} node2:${node2} edgeValue:${edgeValue}`);
214
+ }
215
+ print(...params) {
216
+ this.logger.add(params.join(' '));
217
+ }
218
+ generateNetGraph(nets) {
219
+ const uniqueNets = new Set(nets.map(([, , net]) => net));
220
+ const components = new Set(nets.map(([component, ,]) => component));
221
+ const tmpNets = Array.from(uniqueNets);
222
+ const gndNet = tmpNets.find(item => {
223
+ return item.toString() === '/GND';
224
+ });
225
+ const otherNets = tmpNets.filter(item => {
226
+ return item !== gndNet;
227
+ });
228
+ const netsIndexed = [];
229
+ if (gndNet) {
230
+ netsIndexed.push(gndNet);
231
+ }
232
+ netsIndexed.push(...otherNets);
233
+ const netsLength = netsIndexed.length;
234
+ const conductanceMatrix = ml_matrix_1.default.zeros(netsLength, netsLength);
235
+ components.forEach(item => {
236
+ if (item.typeProp === types_js_1.TypeProps.Resistor) {
237
+ const net1 = item.pinNets.get(1);
238
+ const net2 = item.pinNets.get(2);
239
+ const net1Index = netsIndexed.indexOf(net1);
240
+ const net2Index = netsIndexed.indexOf(net2);
241
+ const resistance = item.parameters.get('value');
242
+ const resistanceValue = resistance.toNumber();
243
+ const conductanceValue = 1 / resistanceValue;
244
+ const currentValue1 = conductanceMatrix.get(net1Index, net1Index);
245
+ const currentValue2 = conductanceMatrix.get(net2Index, net2Index);
246
+ const currentValue3 = conductanceMatrix.get(net1Index, net2Index);
247
+ const currentValue4 = conductanceMatrix.get(net2Index, net1Index);
248
+ conductanceMatrix.set(net1Index, net1Index, currentValue1 + conductanceValue);
249
+ conductanceMatrix.set(net2Index, net2Index, currentValue2 + conductanceValue);
250
+ conductanceMatrix.set(net1Index, net2Index, currentValue3 - conductanceValue);
251
+ conductanceMatrix.set(net2Index, net1Index, currentValue4 - conductanceValue);
252
+ }
253
+ });
254
+ if (gndNet) {
255
+ conductanceMatrix.removeColumn(0);
256
+ conductanceMatrix.removeRow(0);
257
+ }
258
+ const netsWithoutGnd = netsIndexed.filter(net => {
259
+ return (net !== gndNet);
260
+ });
261
+ const netResistances = new Map();
262
+ try {
263
+ netsWithoutGnd.forEach((net, index) => {
264
+ if (net.type === types_js_1.NetTypes.Source) {
265
+ const currentVector = ml_matrix_1.default.zeros(netsWithoutGnd.length, 1);
266
+ currentVector.set(index, 0, 1);
267
+ const solution = (0, ml_matrix_1.solve)(conductanceMatrix, currentVector);
268
+ for (let i = 0; i < solution.rows; i++) {
269
+ const resValue = solution.get(i, 0);
270
+ if (resValue > 0) {
271
+ const targetNet = netsIndexed[i];
272
+ netResistances.set(targetNet, resValue);
273
+ }
274
+ }
275
+ }
276
+ });
277
+ }
278
+ catch (err) {
279
+ }
280
+ return {
281
+ nets,
282
+ netResistances,
283
+ };
284
+ }
285
+ findNodePaths(graph, startNode, endNode, seenNodes = []) {
286
+ const edges = graph.nodeEdges(startNode);
287
+ const paths = [];
288
+ for (let i = 0; i < edges.length; i++) {
289
+ const edge = edges[i];
290
+ const node1 = edge.v;
291
+ const node2 = edge.w;
292
+ let nextNode = "";
293
+ if (node1 === startNode) {
294
+ nextNode = node2;
295
+ }
296
+ else {
297
+ nextNode = node1;
298
+ }
299
+ if (nextNode === endNode) {
300
+ paths.push([startNode, endNode]);
301
+ continue;
302
+ }
303
+ else if (seenNodes.indexOf(nextNode) !== -1) {
304
+ continue;
305
+ }
306
+ seenNodes.push(startNode);
307
+ const routes = this.findNodePaths(graph, nextNode, endNode, seenNodes);
308
+ for (let j = 0; j < routes.length; j++) {
309
+ paths.push([startNode, ...routes[j]]);
310
+ }
311
+ }
312
+ return paths;
313
+ }
314
+ getNetNodeName(net) {
315
+ return 'net:' + net.toString();
316
+ }
317
+ getComponentName(component) {
318
+ return 'component:' + component.instanceName;
319
+ }
320
+ }
321
+ exports.NetGraph = NetGraph;
322
+ function makeEdgeValue(instanceName1, instancePin1, instanceName2, instancePin2, priority) {
323
+ return [instanceName1, instancePin1, instanceName2, instancePin2, priority];
324
+ }
325
+ function getWireName(wireId) {
326
+ return 'wire:' + wireId;
327
+ }
328
+ exports.getWireName = getWireName;
329
+ function generateLayoutPinDefinition(component) {
330
+ const pins = component.pins;
331
+ const symbolPinDefinitions = [];
332
+ const existingPinIds = Array.from(pins.keys());
333
+ const arrangeProps = component.arrangeProps ?? [];
334
+ const addedPins = [];
335
+ for (const [key, items] of arrangeProps) {
336
+ let useItems;
337
+ if (!Array.isArray(items)) {
338
+ useItems = [items];
339
+ }
340
+ else {
341
+ useItems = [...items];
342
+ }
343
+ useItems.forEach(pinId => {
344
+ const existingPin = existingPinIds.find(pin => pin.equals(pinId));
345
+ if (existingPin) {
346
+ const pin = (0, PinDefinition_js_1.getPinDefinition)(pins, existingPin);
347
+ symbolPinDefinitions.push({
348
+ side: key,
349
+ pinId: pinId,
350
+ text: pin.name,
351
+ position: pin.position,
352
+ pinType: pin.pinType,
353
+ });
354
+ addedPins.push(pinId);
355
+ }
356
+ });
357
+ }
358
+ const unplacedPins = existingPinIds.filter(pinId => {
359
+ return addedPins.find(id => id.equals(pinId)) === undefined;
360
+ });
361
+ if (unplacedPins.length > 0) {
362
+ component._unplacedPins = unplacedPins;
363
+ console.warn("Warning: There are unplaced pins: " + unplacedPins);
364
+ }
365
+ return symbolPinDefinitions;
366
+ }
367
+ exports.generateLayoutPinDefinition = generateLayoutPinDefinition;
368
+ var RenderItemType;
369
+ (function (RenderItemType) {
370
+ RenderItemType["Wire"] = "wire";
371
+ RenderItemType["Component"] = "component";
372
+ })(RenderItemType || (exports.RenderItemType = RenderItemType = {}));
@@ -23,6 +23,7 @@ const globals_js_1 = require("./globals.js");
23
23
  const Frame_js_1 = require("./objects/Frame.js");
24
24
  const big_js_1 = __importDefault(require("big.js"));
25
25
  const logger_js_1 = require("./logger.js");
26
+ const graph_js_1 = require("./graph.js");
26
27
  var JSModuleType;
27
28
  (function (JSModuleType) {
28
29
  JSModuleType["CommonJs"] = "cjs";
@@ -247,11 +248,14 @@ async function renderScript(scriptData, outputPath, options) {
247
248
  errors,
248
249
  };
249
250
  }
250
- const layoutEngine = new layout_js_1.LayoutEngine();
251
+ const logger = new logger_js_1.Logger();
252
+ const graphEngine = new graph_js_1.NetGraph(logger);
253
+ const layoutEngine = new layout_js_1.LayoutEngine(logger);
251
254
  const layoutTimer = new utils_js_1.SimpleStopwatch();
252
255
  let sheetFrames;
253
256
  try {
254
- sheetFrames = layoutEngine.runLayout(sequence, nets);
257
+ const { graph, containerFrames } = graphEngine.generateLayoutGraph(sequence, nets);
258
+ sheetFrames = layoutEngine.runLayout(graph, containerFrames, nets);
255
259
  }
256
260
  catch (err) {
257
261
  throw new utils_js_1.RenderError(`Error during layout generation: ${err}`, 'layout');