circuitscript 0.1.7 → 0.1.8
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/export.js +0 -5
- package/dist/cjs/helpers.js +19 -2
- package/dist/cjs/layout.js +55 -38
- package/dist/cjs/regenerate-tests.js +6 -5
- package/dist/cjs/validate.js +19 -0
- package/dist/esm/export.js +1 -6
- package/dist/esm/helpers.js +19 -2
- package/dist/esm/layout.js +32 -35
- package/dist/esm/regenerate-tests.js +6 -5
- package/dist/esm/validate.js +19 -0
- package/dist/types/layout.d.ts +148 -0
- package/package.json +2 -2
package/dist/cjs/export.js
CHANGED
|
@@ -50,11 +50,6 @@ function generateKiCADNetList(netlist) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
else {
|
|
53
|
-
if (instance.typeProp !== globals_js_1.ComponentTypes.net &&
|
|
54
|
-
instance.typeProp !== globals_js_1.ComponentTypes.graphic &&
|
|
55
|
-
instance.typeProp !== null) {
|
|
56
|
-
console.log('Skipping', instance.instanceName);
|
|
57
|
-
}
|
|
58
53
|
}
|
|
59
54
|
});
|
|
60
55
|
const netItems = [];
|
package/dist/cjs/helpers.js
CHANGED
|
@@ -164,7 +164,21 @@ async function renderScript(scriptData, outputPath, options) {
|
|
|
164
164
|
errors.push(error);
|
|
165
165
|
}
|
|
166
166
|
else if (error && error instanceof antlr4ng_1.RecognitionException) {
|
|
167
|
-
|
|
167
|
+
if (context !== null) {
|
|
168
|
+
errors.push(new utils_js_1.ParseSyntaxError(message, context.start, context.stop));
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
if (error.recognizer) {
|
|
172
|
+
const recognizer = error.recognizer;
|
|
173
|
+
errors.push(new utils_js_1.ParseSyntaxError(message, {
|
|
174
|
+
line: recognizer.currentTokenStartLine,
|
|
175
|
+
column: recognizer.currentTokenColumn
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
errors.push(new utils_js_1.ParseSyntaxError(message));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
168
182
|
}
|
|
169
183
|
else {
|
|
170
184
|
errors.push(new utils_js_1.ParseError(message, context.start, context.stop));
|
|
@@ -224,7 +238,10 @@ async function renderScript(scriptData, outputPath, options) {
|
|
|
224
238
|
});
|
|
225
239
|
(0, fs_1.writeFileSync)(outputPath, (0, export_js_1.printTree)(kicadNetList));
|
|
226
240
|
console.log('Generated file', outputPath);
|
|
227
|
-
return
|
|
241
|
+
return {
|
|
242
|
+
svgOutput: null,
|
|
243
|
+
errors,
|
|
244
|
+
};
|
|
228
245
|
}
|
|
229
246
|
const layoutEngine = new layout_js_1.LayoutEngine();
|
|
230
247
|
const layoutTimer = new utils_js_1.SimpleStopwatch();
|
package/dist/cjs/layout.js
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
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;
|
|
4
24
|
};
|
|
5
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
26
|
exports.ExtractDrawingRects = exports.CalculatePinPositions = exports.RenderJunction = exports.RenderFrameType = exports.RenderFrame = exports.RenderText = exports.RenderComponent = exports.RenderWire = exports.RenderObject = exports.getBounds = exports.applyComponentParamsToSymbol = exports.LayoutEngine = void 0;
|
|
7
|
-
const graphlib_1 =
|
|
8
|
-
const {
|
|
27
|
+
const graphlib_1 = __importStar(require("@dagrejs/graphlib"));
|
|
28
|
+
const { alg } = graphlib_1.default;
|
|
9
29
|
const draw_symbols_js_1 = require("./draw_symbols.js");
|
|
10
30
|
const ExecutionScope_js_1 = require("./objects/ExecutionScope.js");
|
|
11
31
|
const globals_js_1 = require("./globals.js");
|
|
@@ -35,7 +55,7 @@ class LayoutEngine {
|
|
|
35
55
|
return "[" + value + "]" + padding;
|
|
36
56
|
}
|
|
37
57
|
runLayout(sequence, nets) {
|
|
38
|
-
const logNodesAndEdges =
|
|
58
|
+
const logNodesAndEdges = true;
|
|
39
59
|
this.print('===== creating graph and populating with nodes =====');
|
|
40
60
|
const { graph, containerFrames } = this.generateLayoutGraph(sequence, nets);
|
|
41
61
|
this.print('===== done populating graph =====');
|
|
@@ -52,7 +72,7 @@ class LayoutEngine {
|
|
|
52
72
|
this.print('===== graph nodes =====');
|
|
53
73
|
const nodes = graph.nodes();
|
|
54
74
|
nodes.forEach(node => {
|
|
55
|
-
this.print(node, graph.node(node));
|
|
75
|
+
this.print(`name:${node}, value:${graph.node(node)}`);
|
|
56
76
|
});
|
|
57
77
|
this.print('===== end nodes =====');
|
|
58
78
|
this.print('');
|
|
@@ -610,8 +630,8 @@ class LayoutEngine {
|
|
|
610
630
|
generateLayoutGraph(sequence, nets) {
|
|
611
631
|
let previousNode = null;
|
|
612
632
|
let previousPin = null;
|
|
613
|
-
const graph = new Graph({
|
|
614
|
-
directed:
|
|
633
|
+
const graph = new graphlib_1.Graph({
|
|
634
|
+
directed: true,
|
|
615
635
|
compound: true,
|
|
616
636
|
});
|
|
617
637
|
this.print('sequence length:', sequence.length);
|
|
@@ -629,7 +649,7 @@ class LayoutEngine {
|
|
|
629
649
|
const tmpInstanceName = component.instanceName;
|
|
630
650
|
if (!graph.hasNode(tmpInstanceName)) {
|
|
631
651
|
this.print('create instance', tmpInstanceName);
|
|
632
|
-
const { displayProp = null
|
|
652
|
+
const { displayProp = null } = component;
|
|
633
653
|
let tmpSymbol;
|
|
634
654
|
if (displayProp instanceof draw_symbols_js_1.SymbolDrawing) {
|
|
635
655
|
tmpSymbol = new draw_symbols_js_1.SymbolPlaceholder(displayProp);
|
|
@@ -645,26 +665,6 @@ class LayoutEngine {
|
|
|
645
665
|
}
|
|
646
666
|
}
|
|
647
667
|
applyComponentParamsToSymbol(component, tmpSymbol);
|
|
648
|
-
if (component.parameters.has(globals_js_1.ParamKeys.angle)) {
|
|
649
|
-
const value = component.parameters.get(globals_js_1.ParamKeys.angle).toNumber();
|
|
650
|
-
tmpSymbol.angle = value;
|
|
651
|
-
}
|
|
652
|
-
if (component.parameters.has(globals_js_1.ParamKeys.flipX)) {
|
|
653
|
-
tmpSymbol.flipX =
|
|
654
|
-
component.parameters.get(globals_js_1.ParamKeys.flipX);
|
|
655
|
-
}
|
|
656
|
-
if (component.parameters.has(globals_js_1.ParamKeys.flipY)) {
|
|
657
|
-
tmpSymbol.flipY =
|
|
658
|
-
component.parameters.get(globals_js_1.ParamKeys.flipY);
|
|
659
|
-
}
|
|
660
|
-
if (tmpSymbol instanceof draw_symbols_js_1.SymbolCustom) {
|
|
661
|
-
if (widthProp) {
|
|
662
|
-
tmpSymbol.bodyWidth = (0, helpers_js_1.milsToMM)(widthProp);
|
|
663
|
-
}
|
|
664
|
-
if (heightProp) {
|
|
665
|
-
tmpSymbol.bodyHeight = (0, helpers_js_1.milsToMM)(heightProp);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
668
|
tmpSymbol.refreshDrawing();
|
|
669
669
|
const { width: useWidth, height: useHeight } = tmpSymbol.size();
|
|
670
670
|
tmpComponent = new RenderComponent(component, useWidth, useHeight);
|
|
@@ -770,7 +770,11 @@ class LayoutEngine {
|
|
|
770
770
|
};
|
|
771
771
|
}
|
|
772
772
|
setGraphEdge(graph, node1, node2, edgeValue) {
|
|
773
|
+
if (!graph.isDirected && graph.hasEdge(node1, node2)) {
|
|
774
|
+
this.print(`Warning: edge already exists ${node1} ${node2}`);
|
|
775
|
+
}
|
|
773
776
|
graph.setEdge(node1, node2, edgeValue);
|
|
777
|
+
this.print(`created edge: node1:${node1} node2:${node2} edgeValue:${edgeValue}`);
|
|
774
778
|
}
|
|
775
779
|
sizeSubGraphs(graph) {
|
|
776
780
|
const subGraphs = alg.components(graph);
|
|
@@ -827,7 +831,6 @@ class LayoutEngine {
|
|
|
827
831
|
this.placeSubgraphV2(graph, firstNodeId, subgraphEdges);
|
|
828
832
|
}
|
|
829
833
|
placeSubgraphV2(graph, firstNodeId, subgraphEdges) {
|
|
830
|
-
let firstNodePlaced = false;
|
|
831
834
|
const originNodes = [];
|
|
832
835
|
const originNodeGroups = new Map();
|
|
833
836
|
function findOriginNode(node) {
|
|
@@ -853,14 +856,6 @@ class LayoutEngine {
|
|
|
853
856
|
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
854
857
|
const [, node1] = graph.node(nodeId1);
|
|
855
858
|
const [, node2] = graph.node(nodeId2);
|
|
856
|
-
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
857
|
-
this.print('first node placed at origin');
|
|
858
|
-
this.placeNodeAtPosition((0, ParamDefinition_js_1.numeric)(0), (0, ParamDefinition_js_1.numeric)(0), node1, pin1);
|
|
859
|
-
firstNodePlaced = true;
|
|
860
|
-
node1.isFloating = false;
|
|
861
|
-
originNodes.push(node1);
|
|
862
|
-
originNodeGroups.set(node1.toString(), [node1]);
|
|
863
|
-
}
|
|
864
859
|
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
865
860
|
if (!node1.isFloating && node2.isFloating) {
|
|
866
861
|
fixedNode = node1;
|
|
@@ -938,6 +933,7 @@ class LayoutEngine {
|
|
|
938
933
|
this.print(`set wire auto end at: ${untilX} ${untilY}`);
|
|
939
934
|
}
|
|
940
935
|
});
|
|
936
|
+
this.print('----');
|
|
941
937
|
});
|
|
942
938
|
}
|
|
943
939
|
mergeOriginNodes(node1, pin1, node2, pin2, originNode1, originNode2, originNodes, originNodeGroups) {
|
|
@@ -1138,11 +1134,32 @@ function generateLayoutPinDefinition(component) {
|
|
|
1138
1134
|
return symbolPinDefinitions;
|
|
1139
1135
|
}
|
|
1140
1136
|
function applyComponentParamsToSymbol(component, symbol) {
|
|
1137
|
+
const { widthProp = null, heightProp = null } = component;
|
|
1141
1138
|
const newMap = new Map(component.parameters);
|
|
1142
1139
|
if (!newMap.has('refdes')) {
|
|
1143
1140
|
newMap.set('refdes', component.assignedRefDes ?? "?");
|
|
1144
1141
|
}
|
|
1145
1142
|
symbol.drawing.variables = newMap;
|
|
1143
|
+
if (component.parameters.has(globals_js_1.ParamKeys.angle)) {
|
|
1144
|
+
const value = component.parameters.get(globals_js_1.ParamKeys.angle).toNumber();
|
|
1145
|
+
symbol.angle = value;
|
|
1146
|
+
}
|
|
1147
|
+
if (component.parameters.has(globals_js_1.ParamKeys.flipX)) {
|
|
1148
|
+
symbol.flipX =
|
|
1149
|
+
component.parameters.get(globals_js_1.ParamKeys.flipX);
|
|
1150
|
+
}
|
|
1151
|
+
if (component.parameters.has(globals_js_1.ParamKeys.flipY)) {
|
|
1152
|
+
symbol.flipY =
|
|
1153
|
+
component.parameters.get(globals_js_1.ParamKeys.flipY);
|
|
1154
|
+
}
|
|
1155
|
+
if (symbol instanceof draw_symbols_js_1.SymbolCustom) {
|
|
1156
|
+
if (widthProp) {
|
|
1157
|
+
symbol.bodyWidth = (0, helpers_js_1.milsToMM)(widthProp);
|
|
1158
|
+
}
|
|
1159
|
+
if (heightProp) {
|
|
1160
|
+
symbol.bodyHeight = (0, helpers_js_1.milsToMM)(heightProp);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1146
1163
|
}
|
|
1147
1164
|
exports.applyComponentParamsToSymbol = applyComponentParamsToSymbol;
|
|
1148
1165
|
function calculateSymbolAngle(symbol, pin, direction) {
|
|
@@ -10,7 +10,7 @@ const mainDir = './__tests__/renderData/';
|
|
|
10
10
|
const env = new environment_js_1.NodeScriptEnvironment();
|
|
11
11
|
environment_js_1.NodeScriptEnvironment.setInstance(env);
|
|
12
12
|
async function regenerateTests(extra = "") {
|
|
13
|
-
env.prepareSVGEnvironment();
|
|
13
|
+
await env.prepareSVGEnvironment();
|
|
14
14
|
const cstFiles = [];
|
|
15
15
|
const files = fs_1.default.readdirSync(mainDir);
|
|
16
16
|
files.forEach(file => {
|
|
@@ -18,19 +18,20 @@ async function regenerateTests(extra = "") {
|
|
|
18
18
|
cstFiles.push(file);
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
-
cstFiles.
|
|
21
|
+
for (let i = 0; i < cstFiles.length; i++) {
|
|
22
|
+
const file = cstFiles[i];
|
|
22
23
|
const inputPath = mainDir + file;
|
|
23
24
|
const scriptData = fs_1.default.readFileSync(inputPath, { encoding: 'utf-8' });
|
|
24
25
|
const outputPath = mainDir + 'svgs/' + file + extra + '.svg';
|
|
25
26
|
env.setModuleDirectory(mainDir);
|
|
26
|
-
|
|
27
|
+
env.setDefaultLibsPath(mainDir + '../../libs/');
|
|
28
|
+
await (0, helpers_js_1.renderScript)(scriptData, outputPath, {
|
|
27
29
|
dumpNets: false,
|
|
28
30
|
dumpData: false,
|
|
29
31
|
showStats: false,
|
|
30
32
|
environment: env,
|
|
31
33
|
});
|
|
32
|
-
|
|
33
|
-
});
|
|
34
|
+
}
|
|
34
35
|
return cstFiles;
|
|
35
36
|
}
|
|
36
37
|
(async () => {
|
package/dist/cjs/validate.js
CHANGED
|
@@ -69,6 +69,7 @@ async function validate() {
|
|
|
69
69
|
};
|
|
70
70
|
const visitor = await (0, helpers_js_1.validateScript)(inputFilePath, scriptData, scriptOptions);
|
|
71
71
|
const symbols = visitor.getSymbols().getSymbols();
|
|
72
|
+
const undefinedSymbols = [];
|
|
72
73
|
symbols.forEach((value, key) => {
|
|
73
74
|
if (value.type !== types_js_1.ParseSymbolType.Undefined) {
|
|
74
75
|
value = value;
|
|
@@ -78,12 +79,30 @@ async function validate() {
|
|
|
78
79
|
console.log(" " + instance.line + ":" + instance.column + " " + instance.start);
|
|
79
80
|
});
|
|
80
81
|
}
|
|
82
|
+
else {
|
|
83
|
+
undefinedSymbols.push(value);
|
|
84
|
+
}
|
|
81
85
|
});
|
|
82
86
|
const { parsedTokens } = await (0, helpers_js_1.getSemanticTokens)(scriptData, scriptOptions);
|
|
83
87
|
parsedTokens.forEach(item => {
|
|
84
88
|
const { line, column, tokenType, tokenModifiers, textValue } = item;
|
|
85
89
|
console.log(`${line}:${column} - ${textValue} - ${tokenType} | ${tokenModifiers.join(',')}`);
|
|
86
90
|
});
|
|
91
|
+
console.log('--- undefined ---');
|
|
92
|
+
undefinedSymbols.forEach(symbol => {
|
|
93
|
+
const { token } = symbol;
|
|
94
|
+
const info = {
|
|
95
|
+
start: {
|
|
96
|
+
line: (token?.line || 1),
|
|
97
|
+
character: token?.column || 0
|
|
98
|
+
},
|
|
99
|
+
end: {
|
|
100
|
+
line: (token?.line || 1),
|
|
101
|
+
character: (token?.column || 0) + ((token?.stop || 0) - (token?.start || 0) + 1)
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
console.log(token.text, info);
|
|
105
|
+
});
|
|
87
106
|
}
|
|
88
107
|
exports.default = validate;
|
|
89
108
|
validate();
|
package/dist/esm/export.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NoNetText } from "./globals.js";
|
|
2
2
|
import { NumericValue } from "./objects/ParamDefinition.js";
|
|
3
3
|
export function generateKiCADNetList(netlist) {
|
|
4
4
|
const componentsList = [];
|
|
@@ -47,11 +47,6 @@ export function generateKiCADNetList(netlist) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
|
-
if (instance.typeProp !== ComponentTypes.net &&
|
|
51
|
-
instance.typeProp !== ComponentTypes.graphic &&
|
|
52
|
-
instance.typeProp !== null) {
|
|
53
|
-
console.log('Skipping', instance.instanceName);
|
|
54
|
-
}
|
|
55
50
|
}
|
|
56
51
|
});
|
|
57
52
|
const netItems = [];
|
package/dist/esm/helpers.js
CHANGED
|
@@ -154,7 +154,21 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
154
154
|
errors.push(error);
|
|
155
155
|
}
|
|
156
156
|
else if (error && error instanceof RecognitionException) {
|
|
157
|
-
|
|
157
|
+
if (context !== null) {
|
|
158
|
+
errors.push(new ParseSyntaxError(message, context.start, context.stop));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
if (error.recognizer) {
|
|
162
|
+
const recognizer = error.recognizer;
|
|
163
|
+
errors.push(new ParseSyntaxError(message, {
|
|
164
|
+
line: recognizer.currentTokenStartLine,
|
|
165
|
+
column: recognizer.currentTokenColumn
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
errors.push(new ParseSyntaxError(message));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
158
172
|
}
|
|
159
173
|
else {
|
|
160
174
|
errors.push(new ParseError(message, context.start, context.stop));
|
|
@@ -214,7 +228,10 @@ export async function renderScript(scriptData, outputPath, options) {
|
|
|
214
228
|
});
|
|
215
229
|
writeFileSync(outputPath, printTree(kicadNetList));
|
|
216
230
|
console.log('Generated file', outputPath);
|
|
217
|
-
return
|
|
231
|
+
return {
|
|
232
|
+
svgOutput: null,
|
|
233
|
+
errors,
|
|
234
|
+
};
|
|
218
235
|
}
|
|
219
236
|
const layoutEngine = new LayoutEngine();
|
|
220
237
|
const layoutTimer = new SimpleStopwatch();
|
package/dist/esm/layout.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
const {
|
|
1
|
+
import graphlib, { Graph } from '@dagrejs/graphlib';
|
|
2
|
+
const { alg } = graphlib;
|
|
3
3
|
import { SymbolCustom, SymbolDrawing, SymbolCustomModule, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.js";
|
|
4
4
|
import { FrameAction, SequenceAction } from "./objects/ExecutionScope.js";
|
|
5
5
|
import { ComponentTypes, defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, ParamKeys, SymbolPinSide, WireAutoDirection } from './globals.js';
|
|
@@ -30,7 +30,7 @@ export class LayoutEngine {
|
|
|
30
30
|
return "[" + value + "]" + padding;
|
|
31
31
|
}
|
|
32
32
|
runLayout(sequence, nets) {
|
|
33
|
-
const logNodesAndEdges =
|
|
33
|
+
const logNodesAndEdges = true;
|
|
34
34
|
this.print('===== creating graph and populating with nodes =====');
|
|
35
35
|
const { graph, containerFrames } = this.generateLayoutGraph(sequence, nets);
|
|
36
36
|
this.print('===== done populating graph =====');
|
|
@@ -47,7 +47,7 @@ export class LayoutEngine {
|
|
|
47
47
|
this.print('===== graph nodes =====');
|
|
48
48
|
const nodes = graph.nodes();
|
|
49
49
|
nodes.forEach(node => {
|
|
50
|
-
this.print(node, graph.node(node));
|
|
50
|
+
this.print(`name:${node}, value:${graph.node(node)}`);
|
|
51
51
|
});
|
|
52
52
|
this.print('===== end nodes =====');
|
|
53
53
|
this.print('');
|
|
@@ -606,7 +606,7 @@ export class LayoutEngine {
|
|
|
606
606
|
let previousNode = null;
|
|
607
607
|
let previousPin = null;
|
|
608
608
|
const graph = new Graph({
|
|
609
|
-
directed:
|
|
609
|
+
directed: true,
|
|
610
610
|
compound: true,
|
|
611
611
|
});
|
|
612
612
|
this.print('sequence length:', sequence.length);
|
|
@@ -624,7 +624,7 @@ export class LayoutEngine {
|
|
|
624
624
|
const tmpInstanceName = component.instanceName;
|
|
625
625
|
if (!graph.hasNode(tmpInstanceName)) {
|
|
626
626
|
this.print('create instance', tmpInstanceName);
|
|
627
|
-
const { displayProp = null
|
|
627
|
+
const { displayProp = null } = component;
|
|
628
628
|
let tmpSymbol;
|
|
629
629
|
if (displayProp instanceof SymbolDrawing) {
|
|
630
630
|
tmpSymbol = new SymbolPlaceholder(displayProp);
|
|
@@ -640,26 +640,6 @@ export class LayoutEngine {
|
|
|
640
640
|
}
|
|
641
641
|
}
|
|
642
642
|
applyComponentParamsToSymbol(component, tmpSymbol);
|
|
643
|
-
if (component.parameters.has(ParamKeys.angle)) {
|
|
644
|
-
const value = component.parameters.get(ParamKeys.angle).toNumber();
|
|
645
|
-
tmpSymbol.angle = value;
|
|
646
|
-
}
|
|
647
|
-
if (component.parameters.has(ParamKeys.flipX)) {
|
|
648
|
-
tmpSymbol.flipX =
|
|
649
|
-
component.parameters.get(ParamKeys.flipX);
|
|
650
|
-
}
|
|
651
|
-
if (component.parameters.has(ParamKeys.flipY)) {
|
|
652
|
-
tmpSymbol.flipY =
|
|
653
|
-
component.parameters.get(ParamKeys.flipY);
|
|
654
|
-
}
|
|
655
|
-
if (tmpSymbol instanceof SymbolCustom) {
|
|
656
|
-
if (widthProp) {
|
|
657
|
-
tmpSymbol.bodyWidth = milsToMM(widthProp);
|
|
658
|
-
}
|
|
659
|
-
if (heightProp) {
|
|
660
|
-
tmpSymbol.bodyHeight = milsToMM(heightProp);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
643
|
tmpSymbol.refreshDrawing();
|
|
664
644
|
const { width: useWidth, height: useHeight } = tmpSymbol.size();
|
|
665
645
|
tmpComponent = new RenderComponent(component, useWidth, useHeight);
|
|
@@ -765,7 +745,11 @@ export class LayoutEngine {
|
|
|
765
745
|
};
|
|
766
746
|
}
|
|
767
747
|
setGraphEdge(graph, node1, node2, edgeValue) {
|
|
748
|
+
if (!graph.isDirected && graph.hasEdge(node1, node2)) {
|
|
749
|
+
this.print(`Warning: edge already exists ${node1} ${node2}`);
|
|
750
|
+
}
|
|
768
751
|
graph.setEdge(node1, node2, edgeValue);
|
|
752
|
+
this.print(`created edge: node1:${node1} node2:${node2} edgeValue:${edgeValue}`);
|
|
769
753
|
}
|
|
770
754
|
sizeSubGraphs(graph) {
|
|
771
755
|
const subGraphs = alg.components(graph);
|
|
@@ -822,7 +806,6 @@ export class LayoutEngine {
|
|
|
822
806
|
this.placeSubgraphV2(graph, firstNodeId, subgraphEdges);
|
|
823
807
|
}
|
|
824
808
|
placeSubgraphV2(graph, firstNodeId, subgraphEdges) {
|
|
825
|
-
let firstNodePlaced = false;
|
|
826
809
|
const originNodes = [];
|
|
827
810
|
const originNodeGroups = new Map();
|
|
828
811
|
function findOriginNode(node) {
|
|
@@ -848,14 +831,6 @@ export class LayoutEngine {
|
|
|
848
831
|
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
849
832
|
const [, node1] = graph.node(nodeId1);
|
|
850
833
|
const [, node2] = graph.node(nodeId2);
|
|
851
|
-
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
852
|
-
this.print('first node placed at origin');
|
|
853
|
-
this.placeNodeAtPosition(numeric(0), numeric(0), node1, pin1);
|
|
854
|
-
firstNodePlaced = true;
|
|
855
|
-
node1.isFloating = false;
|
|
856
|
-
originNodes.push(node1);
|
|
857
|
-
originNodeGroups.set(node1.toString(), [node1]);
|
|
858
|
-
}
|
|
859
834
|
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
860
835
|
if (!node1.isFloating && node2.isFloating) {
|
|
861
836
|
fixedNode = node1;
|
|
@@ -933,6 +908,7 @@ export class LayoutEngine {
|
|
|
933
908
|
this.print(`set wire auto end at: ${untilX} ${untilY}`);
|
|
934
909
|
}
|
|
935
910
|
});
|
|
911
|
+
this.print('----');
|
|
936
912
|
});
|
|
937
913
|
}
|
|
938
914
|
mergeOriginNodes(node1, pin1, node2, pin2, originNode1, originNode2, originNodes, originNodeGroups) {
|
|
@@ -1132,11 +1108,32 @@ function generateLayoutPinDefinition(component) {
|
|
|
1132
1108
|
return symbolPinDefinitions;
|
|
1133
1109
|
}
|
|
1134
1110
|
export function applyComponentParamsToSymbol(component, symbol) {
|
|
1111
|
+
const { widthProp = null, heightProp = null } = component;
|
|
1135
1112
|
const newMap = new Map(component.parameters);
|
|
1136
1113
|
if (!newMap.has('refdes')) {
|
|
1137
1114
|
newMap.set('refdes', component.assignedRefDes ?? "?");
|
|
1138
1115
|
}
|
|
1139
1116
|
symbol.drawing.variables = newMap;
|
|
1117
|
+
if (component.parameters.has(ParamKeys.angle)) {
|
|
1118
|
+
const value = component.parameters.get(ParamKeys.angle).toNumber();
|
|
1119
|
+
symbol.angle = value;
|
|
1120
|
+
}
|
|
1121
|
+
if (component.parameters.has(ParamKeys.flipX)) {
|
|
1122
|
+
symbol.flipX =
|
|
1123
|
+
component.parameters.get(ParamKeys.flipX);
|
|
1124
|
+
}
|
|
1125
|
+
if (component.parameters.has(ParamKeys.flipY)) {
|
|
1126
|
+
symbol.flipY =
|
|
1127
|
+
component.parameters.get(ParamKeys.flipY);
|
|
1128
|
+
}
|
|
1129
|
+
if (symbol instanceof SymbolCustom) {
|
|
1130
|
+
if (widthProp) {
|
|
1131
|
+
symbol.bodyWidth = milsToMM(widthProp);
|
|
1132
|
+
}
|
|
1133
|
+
if (heightProp) {
|
|
1134
|
+
symbol.bodyHeight = milsToMM(heightProp);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1140
1137
|
}
|
|
1141
1138
|
function calculateSymbolAngle(symbol, pin, direction) {
|
|
1142
1139
|
let directionVector = 0;
|
|
@@ -5,7 +5,7 @@ const mainDir = './__tests__/renderData/';
|
|
|
5
5
|
const env = new NodeScriptEnvironment();
|
|
6
6
|
NodeScriptEnvironment.setInstance(env);
|
|
7
7
|
async function regenerateTests(extra = "") {
|
|
8
|
-
env.prepareSVGEnvironment();
|
|
8
|
+
await env.prepareSVGEnvironment();
|
|
9
9
|
const cstFiles = [];
|
|
10
10
|
const files = fs.readdirSync(mainDir);
|
|
11
11
|
files.forEach(file => {
|
|
@@ -13,19 +13,20 @@ async function regenerateTests(extra = "") {
|
|
|
13
13
|
cstFiles.push(file);
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
|
-
cstFiles.
|
|
16
|
+
for (let i = 0; i < cstFiles.length; i++) {
|
|
17
|
+
const file = cstFiles[i];
|
|
17
18
|
const inputPath = mainDir + file;
|
|
18
19
|
const scriptData = fs.readFileSync(inputPath, { encoding: 'utf-8' });
|
|
19
20
|
const outputPath = mainDir + 'svgs/' + file + extra + '.svg';
|
|
20
21
|
env.setModuleDirectory(mainDir);
|
|
21
|
-
|
|
22
|
+
env.setDefaultLibsPath(mainDir + '../../libs/');
|
|
23
|
+
await renderScript(scriptData, outputPath, {
|
|
22
24
|
dumpNets: false,
|
|
23
25
|
dumpData: false,
|
|
24
26
|
showStats: false,
|
|
25
27
|
environment: env,
|
|
26
28
|
});
|
|
27
|
-
|
|
28
|
-
});
|
|
29
|
+
}
|
|
29
30
|
return cstFiles;
|
|
30
31
|
}
|
|
31
32
|
(async () => {
|
package/dist/esm/validate.js
CHANGED
|
@@ -67,6 +67,7 @@ export default async function validate() {
|
|
|
67
67
|
};
|
|
68
68
|
const visitor = await validateScript(inputFilePath, scriptData, scriptOptions);
|
|
69
69
|
const symbols = visitor.getSymbols().getSymbols();
|
|
70
|
+
const undefinedSymbols = [];
|
|
70
71
|
symbols.forEach((value, key) => {
|
|
71
72
|
if (value.type !== ParseSymbolType.Undefined) {
|
|
72
73
|
value = value;
|
|
@@ -76,11 +77,29 @@ export default async function validate() {
|
|
|
76
77
|
console.log(" " + instance.line + ":" + instance.column + " " + instance.start);
|
|
77
78
|
});
|
|
78
79
|
}
|
|
80
|
+
else {
|
|
81
|
+
undefinedSymbols.push(value);
|
|
82
|
+
}
|
|
79
83
|
});
|
|
80
84
|
const { parsedTokens } = await getSemanticTokens(scriptData, scriptOptions);
|
|
81
85
|
parsedTokens.forEach(item => {
|
|
82
86
|
const { line, column, tokenType, tokenModifiers, textValue } = item;
|
|
83
87
|
console.log(`${line}:${column} - ${textValue} - ${tokenType} | ${tokenModifiers.join(',')}`);
|
|
84
88
|
});
|
|
89
|
+
console.log('--- undefined ---');
|
|
90
|
+
undefinedSymbols.forEach(symbol => {
|
|
91
|
+
const { token } = symbol;
|
|
92
|
+
const info = {
|
|
93
|
+
start: {
|
|
94
|
+
line: (token?.line || 1),
|
|
95
|
+
character: token?.column || 0
|
|
96
|
+
},
|
|
97
|
+
end: {
|
|
98
|
+
line: (token?.line || 1),
|
|
99
|
+
character: (token?.column || 0) + ((token?.stop || 0) - (token?.start || 0) + 1)
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
console.log(token.text, info);
|
|
103
|
+
});
|
|
85
104
|
}
|
|
86
105
|
validate();
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Graph } from '@dagrejs/graphlib';
|
|
2
|
+
import { SymbolGraphic, SymbolText, SymbolDrawingCommands } from "./draw_symbols.js";
|
|
3
|
+
import { ClassComponent } from "./objects/ClassComponent.js";
|
|
4
|
+
import { SequenceItem } from "./objects/ExecutionScope.js";
|
|
5
|
+
import { WireAutoDirection } from './globals.js';
|
|
6
|
+
import { WireSegment } from './objects/Wire.js';
|
|
7
|
+
import { Net } from './objects/Net.js';
|
|
8
|
+
import { Logger } from './logger.js';
|
|
9
|
+
import { Frame, FramePlotDirection } from './objects/Frame.js';
|
|
10
|
+
import { BoundBox } from './utils.js';
|
|
11
|
+
import { NumericValue } from './objects/ParamDefinition.js';
|
|
12
|
+
export declare class LayoutEngine {
|
|
13
|
+
logger: Logger;
|
|
14
|
+
layoutWarnings: string[];
|
|
15
|
+
showBaseFrame: boolean;
|
|
16
|
+
constructor(options?: {
|
|
17
|
+
showBaseFrame: boolean;
|
|
18
|
+
});
|
|
19
|
+
protected print(...params: any[]): void;
|
|
20
|
+
protected printLevel(level: number, ...params: any[]): void;
|
|
21
|
+
protected padLevel(value: number): string;
|
|
22
|
+
runLayout(sequence: SequenceItem[], nets: [ClassComponent, pin: number, net: Net][]): SheetFrame[];
|
|
23
|
+
private flattenFrameItems;
|
|
24
|
+
private findJunctions;
|
|
25
|
+
private placeFrames;
|
|
26
|
+
collectElementFrames(frame: RenderFrame, level?: number): RenderFrame[];
|
|
27
|
+
applyFrameOffset(frame: RenderFrame, level?: number): void;
|
|
28
|
+
private placeAndSizeFrame;
|
|
29
|
+
dumpFrame(frame: RenderFrame, level?: number): void;
|
|
30
|
+
private prepareFrames;
|
|
31
|
+
private checkAddFrameTitle;
|
|
32
|
+
generateLayoutGraph(sequence: SequenceItem[], nets: [ClassComponent, pin: number, net: Net][]): {
|
|
33
|
+
graph: Graph;
|
|
34
|
+
containerFrames: RenderFrame[];
|
|
35
|
+
};
|
|
36
|
+
private setGraphEdge;
|
|
37
|
+
private sizeSubGraphs;
|
|
38
|
+
private walkAndPlaceGraph;
|
|
39
|
+
private placeSubgraphV2;
|
|
40
|
+
mergeOriginNodes(node1: RenderItem, pin1: number, node2: RenderItem, pin2: number, originNode1: string, originNode2: string, originNodes: RenderItem[], originNodeGroups: Map<string, RenderItem[]>): void;
|
|
41
|
+
translateNodeBy(offsetX: number, offsetY: number, item: RenderItem): void;
|
|
42
|
+
placeNodeAtPosition(fromX: NumericValue, fromY: NumericValue, item: RenderItem, pin: number, depth?: number): void;
|
|
43
|
+
placeFloatingItems(graph: Graph, item: RenderItem, depth?: number): void;
|
|
44
|
+
printWarnings(): void;
|
|
45
|
+
}
|
|
46
|
+
type RenderItem = RenderComponent | RenderWire | RenderText;
|
|
47
|
+
export declare function applyComponentParamsToSymbol(component: ClassComponent, symbol: SymbolGraphic): void;
|
|
48
|
+
export declare function getBounds(components: (RenderComponent | RenderText)[], wires: RenderWire[], junctions: RenderJunction[], frames: RenderFrame[]): BoundBox;
|
|
49
|
+
export declare class RenderObject {
|
|
50
|
+
x: NumericValue;
|
|
51
|
+
y: NumericValue;
|
|
52
|
+
isFloating: boolean;
|
|
53
|
+
floatingRelativeTo: [selfPin: number, nodeId: string, pin: number][];
|
|
54
|
+
}
|
|
55
|
+
export declare class RenderWire extends RenderObject {
|
|
56
|
+
id: number;
|
|
57
|
+
segments: WireSegment[];
|
|
58
|
+
points: {
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
}[];
|
|
62
|
+
netName: string;
|
|
63
|
+
constructor(x: NumericValue, y: NumericValue, segments: WireSegment[]);
|
|
64
|
+
refreshPoints(): void;
|
|
65
|
+
getAutoPoints(value: [x: NumericValue, y: NumericValue], direction: WireAutoDirection): [dx: number, dy: number][];
|
|
66
|
+
getWireEnd(): {
|
|
67
|
+
x: number;
|
|
68
|
+
y: number;
|
|
69
|
+
};
|
|
70
|
+
isEndAutoLength(): boolean;
|
|
71
|
+
getEndAuto(): [instance: ClassComponent, pin: number];
|
|
72
|
+
setEndAuto(untilX: NumericValue, untilY: NumericValue): void;
|
|
73
|
+
toString(): string;
|
|
74
|
+
}
|
|
75
|
+
export type MergedWire = {
|
|
76
|
+
netName: string;
|
|
77
|
+
segments: [x: number, y: number][][];
|
|
78
|
+
intersectPoints: [x: number, y: number, count: number][];
|
|
79
|
+
};
|
|
80
|
+
export declare class RenderComponent extends RenderObject {
|
|
81
|
+
component: ClassComponent;
|
|
82
|
+
symbol: SymbolGraphic;
|
|
83
|
+
width: number;
|
|
84
|
+
height: number;
|
|
85
|
+
displaySymbol: string | null;
|
|
86
|
+
constructor(component: ClassComponent, width: number, height: number);
|
|
87
|
+
doesOverlap(other: RenderComponent): boolean;
|
|
88
|
+
toString(): string;
|
|
89
|
+
}
|
|
90
|
+
export declare class RenderText extends RenderObject {
|
|
91
|
+
symbol: SymbolText;
|
|
92
|
+
_fontSize: NumericValue;
|
|
93
|
+
_fontWeight: string;
|
|
94
|
+
get fontSize(): NumericValue;
|
|
95
|
+
set fontSize(value: NumericValue);
|
|
96
|
+
get fontWeight(): string;
|
|
97
|
+
set fontWeight(value: string);
|
|
98
|
+
constructor(text: string);
|
|
99
|
+
}
|
|
100
|
+
export declare class RenderFrame extends RenderObject {
|
|
101
|
+
bounds: BoundBox | null;
|
|
102
|
+
frame: Frame;
|
|
103
|
+
innerItems: (RenderComponent | RenderFrame | RenderText)[];
|
|
104
|
+
translateX: number;
|
|
105
|
+
translateY: number;
|
|
106
|
+
padding: NumericValue;
|
|
107
|
+
gap: NumericValue;
|
|
108
|
+
borderWidth: NumericValue;
|
|
109
|
+
direction: FramePlotDirection;
|
|
110
|
+
width: NumericValue | null;
|
|
111
|
+
height: NumericValue | null;
|
|
112
|
+
subgraphId: string;
|
|
113
|
+
renderType: RenderFrameType;
|
|
114
|
+
containsTitle: boolean;
|
|
115
|
+
constructor(frame: Frame, type?: RenderFrameType);
|
|
116
|
+
toString(): string;
|
|
117
|
+
}
|
|
118
|
+
export declare enum RenderFrameType {
|
|
119
|
+
Container = 1,
|
|
120
|
+
Elements = 2
|
|
121
|
+
}
|
|
122
|
+
export declare class RenderJunction {
|
|
123
|
+
x: NumericValue;
|
|
124
|
+
y: NumericValue;
|
|
125
|
+
constructor(x: NumericValue, y: NumericValue);
|
|
126
|
+
}
|
|
127
|
+
export type SheetFrame = {
|
|
128
|
+
frame: RenderFrame;
|
|
129
|
+
frames: RenderFrame[];
|
|
130
|
+
components: RenderComponent[];
|
|
131
|
+
wires: RenderWire[];
|
|
132
|
+
textObjects: RenderText[];
|
|
133
|
+
junctions: RenderJunction[];
|
|
134
|
+
mergedWires: MergedWire[];
|
|
135
|
+
};
|
|
136
|
+
export declare function CalculatePinPositions(component: ClassComponent): Map<number, {
|
|
137
|
+
x: NumericValue;
|
|
138
|
+
y: NumericValue;
|
|
139
|
+
angle: NumericValue;
|
|
140
|
+
}>;
|
|
141
|
+
export declare function ExtractDrawingRects(drawing: SymbolDrawingCommands): {
|
|
142
|
+
x: NumericValue;
|
|
143
|
+
y: NumericValue;
|
|
144
|
+
width: NumericValue;
|
|
145
|
+
height: NumericValue;
|
|
146
|
+
className: string | undefined;
|
|
147
|
+
}[];
|
|
148
|
+
export { BoundBox };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circuitscript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Interpreter for the circuitscript language",
|
|
5
5
|
"homepage": "https://circuitscript.net",
|
|
6
6
|
"engines": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"boilerplate_author": "Jakub Synowiec <jsynowiec@users.noreply.github.com>",
|
|
79
79
|
"license": "MIT",
|
|
80
80
|
"dependencies": {
|
|
81
|
-
"@dagrejs/graphlib": "2.
|
|
81
|
+
"@dagrejs/graphlib": "^2.2.4",
|
|
82
82
|
"@flatten-js/core": "1.5.5",
|
|
83
83
|
"@svgdotjs/svg.js": "3.2.0",
|
|
84
84
|
"antlr4ng": "^3.0.4",
|