circuitscript 0.1.7 → 0.1.9

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.
@@ -34,6 +34,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
34
34
  ];
35
35
  this.onErrorHandler = null;
36
36
  this.importedFiles = [];
37
+ this.warnings = [];
37
38
  this.onImportFile = async (visitor, filePath, fileData, onErrorHandler) => {
38
39
  throw "Import file not implemented";
39
40
  };
@@ -329,7 +330,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
329
330
  this.setResult(ctx, returnList);
330
331
  };
331
332
  this.visitImport_expr = (ctx) => {
332
- throw new utils_js_1.RuntimeExecutionError("Cannot parse imports here", ctx.start, ctx.stop);
333
+ throw new utils_js_1.RuntimeExecutionError("Cannot parse imports here", ctx);
333
334
  };
334
335
  this.visitFunction_return_expr = (ctx) => {
335
336
  const executor = this.getExecutor();
@@ -378,7 +379,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
378
379
  this.logger = new logger_js_1.Logger();
379
380
  this.onErrorHandler = onErrorHandler;
380
381
  this.environment = environment;
381
- this.startingContext = new execute_js_1.ExecutionContext(globals_js_1.DoubleDelimiter1, `${globals_js_1.DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, null);
382
+ this.startingContext = new execute_js_1.ExecutionContext(globals_js_1.DoubleDelimiter1, `${globals_js_1.DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, this.warnings, null);
382
383
  const scope = this.startingContext.scope;
383
384
  scope.sequence.push([
384
385
  ExecutionScope_js_1.SequenceAction.At, scope.componentRoot, scope.currentPin
@@ -522,7 +523,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
522
523
  }
523
524
  catch (err) {
524
525
  if (ctx != null) {
525
- throw new utils_js_1.RuntimeExecutionError("An error occurred while importing file", ctx.start, ctx.stop);
526
+ throw new utils_js_1.RuntimeExecutionError("An error occurred while importing file", ctx);
526
527
  }
527
528
  else {
528
529
  this.log('An error occurred while importing file:', err.message);
@@ -538,7 +539,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
538
539
  }
539
540
  }
540
541
  if (errorMessage !== null && ctx) {
541
- throw new utils_js_1.RuntimeExecutionError(errorMessage, ctx.start, ctx.end);
542
+ throw new utils_js_1.RuntimeExecutionError(errorMessage, ctx);
542
543
  }
543
544
  const newImportedFile = {
544
545
  id: name.trim(),
@@ -636,7 +637,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
636
637
  const executionLevel = currentExecutionContext.executionLevel;
637
638
  const executionContextNamespace = currentExecutionContext.namespace
638
639
  + executionContextName + ".";
639
- const newExecutor = new execute_js_1.ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, parentContext);
640
+ const newExecutor = new execute_js_1.ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
640
641
  executionStack.push(newExecutor);
641
642
  this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
642
643
  return newExecutor;
@@ -653,7 +654,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
653
654
  }
654
655
  const result = validateFunction(value);
655
656
  if (!result) {
656
- throw new utils_js_1.RuntimeExecutionError(`Invalid ${expectedType}`, context.start, context.stop);
657
+ throw new utils_js_1.RuntimeExecutionError(`Invalid ${expectedType}`, context);
657
658
  }
658
659
  return result;
659
660
  }
@@ -83,6 +83,9 @@ class SymbolGraphic {
83
83
  }
84
84
  pinPosition(id) {
85
85
  const pin = this.drawing.getPinPosition(id);
86
+ if (pin === null) {
87
+ throw new utils_js_1.RuntimeExecutionError(`Could not determine pin ${id} position`);
88
+ }
86
89
  const [x, y] = pin.start;
87
90
  const useX = (0, utils_js_1.roundValue)(x);
88
91
  const useY = (0, utils_js_1.roundValue)(y);
@@ -15,7 +15,7 @@ const helpers_js_1 = require("./helpers.js");
15
15
  const draw_symbols_js_1 = require("./draw_symbols.js");
16
16
  const utils_js_1 = require("./utils.js");
17
17
  class ExecutionContext {
18
- constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, parent) {
18
+ constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, warnings, parent) {
19
19
  this.tmpPointId = 0;
20
20
  this.resolveNet = null;
21
21
  this.stopFurtherExpressions = false;
@@ -23,6 +23,7 @@ class ExecutionContext {
23
23
  this.silent = false;
24
24
  this.__functionCache = {};
25
25
  this.componentAngleFollowsWire = true;
26
+ this.warnings = [];
26
27
  this.name = name;
27
28
  this.namespace = namespace;
28
29
  this.netNamespace = netNamespace;
@@ -34,6 +35,14 @@ class ExecutionContext {
34
35
  this.silent = silent;
35
36
  this.log('create new execution context', this.namespace, this.name, this.scope.indentLevel);
36
37
  this.parentContext = parent;
38
+ this.warnings = warnings;
39
+ }
40
+ logWarning(message, context, fileName) {
41
+ this.warnings.push({
42
+ message,
43
+ ctx: context,
44
+ fileName,
45
+ });
37
46
  }
38
47
  log(...params) {
39
48
  const indentOutput = ''.padStart(this.scope.indentLevel * 4, ' ');
@@ -120,7 +129,6 @@ class ExecutionContext {
120
129
  pins.forEach((pin) => {
121
130
  component.pins.set(pin.id, pin);
122
131
  });
123
- component.arrangeProps = props.arrange ?? null;
124
132
  component.displayProp = props.display ?? null;
125
133
  component.widthProp = props.width ?? null;
126
134
  component.heightProp = props.height ?? null;
@@ -133,6 +141,33 @@ class ExecutionContext {
133
141
  useAngle += 360;
134
142
  }
135
143
  }
144
+ if (props.display === null && props.arrange === null) {
145
+ const tmpArrangeLeft = [];
146
+ const tmpArrangeRight = [];
147
+ pins.forEach((pin, index) => {
148
+ const useArray = (index % 2 === 0) ? tmpArrangeLeft : tmpArrangeRight;
149
+ useArray.push((0, ParamDefinition_js_1.numeric)(pin.id));
150
+ });
151
+ const arrangeProp = new Map([
152
+ [globals_js_1.SymbolPinSide.Left, tmpArrangeLeft],
153
+ [globals_js_1.SymbolPinSide.Right, tmpArrangeRight]
154
+ ]);
155
+ props.arrange = arrangeProp;
156
+ }
157
+ if (props.arrange !== null) {
158
+ component.arrangeProps = this.removeArrangePropDuplicates(props.arrange);
159
+ const arrangePropPins = this.getArrangePropPins(component.arrangeProps).map(item => {
160
+ return item.toNumber();
161
+ });
162
+ pins.forEach(pin => {
163
+ if (arrangePropPins.indexOf(pin.id) === -1) {
164
+ this.logWarning(`Pin ${pin.id} is not specified in arrange property`);
165
+ }
166
+ });
167
+ }
168
+ else {
169
+ component.arrangeProps = null;
170
+ }
136
171
  component.angleProp = useAngle ?? 0;
137
172
  component.followWireOrientationProp = props.followWireOrientation;
138
173
  const paramsMap = new Map();
@@ -176,6 +211,59 @@ class ExecutionContext {
176
211
  this.log('add symbol', instanceName, '[' + pinsOutput.join(', ') + ']');
177
212
  return component;
178
213
  }
214
+ removeArrangePropDuplicates(arrangeProp) {
215
+ const sides = [
216
+ globals_js_1.SymbolPinSide.Left,
217
+ globals_js_1.SymbolPinSide.Right,
218
+ globals_js_1.SymbolPinSide.Top,
219
+ globals_js_1.SymbolPinSide.Bottom
220
+ ];
221
+ const result = new Map();
222
+ const seenIds = [];
223
+ sides.forEach(side => {
224
+ let items = arrangeProp.get(side) ?? [];
225
+ if (!Array.isArray(items)) {
226
+ items = [items];
227
+ }
228
+ const uniqueItems = [];
229
+ items.forEach(item => {
230
+ if (item instanceof ParamDefinition_js_1.NumericValue) {
231
+ if (seenIds.indexOf(item.toNumber()) === -1) {
232
+ seenIds.push(item.toNumber());
233
+ uniqueItems.push(item);
234
+ }
235
+ else {
236
+ this.logWarning(`Pin ${item.toNumber()} specified more than once in arrange property`);
237
+ }
238
+ }
239
+ else {
240
+ uniqueItems.push(item);
241
+ }
242
+ });
243
+ result.set(side, uniqueItems);
244
+ });
245
+ return result;
246
+ }
247
+ getArrangePropPins(arrangeProps) {
248
+ const pins = [];
249
+ const sides = [
250
+ globals_js_1.SymbolPinSide.Left,
251
+ globals_js_1.SymbolPinSide.Right,
252
+ globals_js_1.SymbolPinSide.Top,
253
+ globals_js_1.SymbolPinSide.Bottom
254
+ ];
255
+ sides.forEach(side => {
256
+ const items = arrangeProps.get(side);
257
+ if (items) {
258
+ items.forEach(item => {
259
+ if (item instanceof ParamDefinition_js_1.NumericValue) {
260
+ pins.push(item);
261
+ }
262
+ });
263
+ }
264
+ });
265
+ return pins;
266
+ }
179
267
  printPoint(extra = '') {
180
268
  let netString = globals_js_1.NoNetText;
181
269
  if (this.scope.currentComponent === null || this.scope.currentPin === null) {
@@ -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 = [];
@@ -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
- errors.push(new utils_js_1.ParseSyntaxError(message, context.start, context.stop));
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));
@@ -181,6 +195,7 @@ async function renderScript(scriptData, outputPath, options) {
181
195
  visitor.log('reading file');
182
196
  visitor.log('done reading file');
183
197
  const { tree, parser, parserTimeTaken, lexerTimeTaken } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
198
+ (0, utils_js_1.printWarnings)(visitor.getWarnings());
184
199
  showStats && console.log('Lexing took:', lexerTimeTaken);
185
200
  showStats && console.log('Parsing took:', parserTimeTaken);
186
201
  if (dumpNets) {
@@ -224,7 +239,10 @@ async function renderScript(scriptData, outputPath, options) {
224
239
  });
225
240
  (0, fs_1.writeFileSync)(outputPath, (0, export_js_1.printTree)(kicadNetList));
226
241
  console.log('Generated file', outputPath);
227
- return null;
242
+ return {
243
+ svgOutput: null,
244
+ errors,
245
+ };
228
246
  }
229
247
  const layoutEngine = new layout_js_1.LayoutEngine();
230
248
  const layoutTimer = new utils_js_1.SimpleStopwatch();
@@ -1,11 +1,31 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
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 = __importDefault(require("@dagrejs/graphlib"));
8
- const { Graph, alg } = graphlib_1.default;
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 = false;
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: false,
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, widthProp = null, heightProp = null } = component;
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) {
@@ -1088,61 +1084,69 @@ function generateLayoutPinDefinition(component) {
1088
1084
  const pins = component.pins;
1089
1085
  const symbolPinDefinitions = [];
1090
1086
  const existingPinIds = Array.from(pins.keys());
1091
- if (component.arrangeProps === null) {
1092
- for (let i = 0; i < existingPinIds.length; i++) {
1093
- const pinPosition = Math.floor(i / 2);
1094
- const pin = pins.get(existingPinIds[i]);
1095
- symbolPinDefinitions.push({
1096
- side: (i % 2 === 0) ? globals_js_1.SymbolPinSide.Left : globals_js_1.SymbolPinSide.Right,
1097
- pinId: existingPinIds[i],
1098
- text: pin.name,
1099
- position: pinPosition,
1100
- pinType: pin.pinType,
1101
- });
1087
+ const arrangeProps = component.arrangeProps ?? [];
1088
+ const addedPins = [];
1089
+ for (const [key, items] of arrangeProps) {
1090
+ let useItems;
1091
+ if (!Array.isArray(items)) {
1092
+ useItems = [items];
1102
1093
  }
1103
- }
1104
- else {
1105
- const addedPins = [];
1106
- for (const [key, items] of component.arrangeProps) {
1107
- let useItems;
1108
- if (!Array.isArray(items)) {
1109
- useItems = [items];
1110
- }
1111
- else {
1112
- useItems = [...items];
1113
- }
1114
- useItems.forEach(pinId => {
1115
- if (pinId instanceof ParamDefinition_js_1.NumericValue) {
1116
- const pinIdValue = pinId.toNumber();
1117
- if (existingPinIds.indexOf(pinIdValue) !== -1) {
1118
- const pin = pins.get(pinIdValue);
1119
- symbolPinDefinitions.push({
1120
- side: key,
1121
- pinId: pinIdValue,
1122
- text: pin.name,
1123
- position: pin.position,
1124
- pinType: pin.pinType,
1125
- });
1126
- addedPins.push(pinIdValue);
1127
- }
1128
- }
1129
- });
1094
+ else {
1095
+ useItems = [...items];
1130
1096
  }
1131
- const unplacedPins = existingPinIds.filter(pinId => {
1132
- return addedPins.indexOf(pinId) === -1;
1097
+ useItems.forEach(pinId => {
1098
+ if (pinId instanceof ParamDefinition_js_1.NumericValue) {
1099
+ const pinIdValue = pinId.toNumber();
1100
+ if (existingPinIds.indexOf(pinIdValue) !== -1) {
1101
+ const pin = pins.get(pinIdValue);
1102
+ symbolPinDefinitions.push({
1103
+ side: key,
1104
+ pinId: pinIdValue,
1105
+ text: pin.name,
1106
+ position: pin.position,
1107
+ pinType: pin.pinType,
1108
+ });
1109
+ addedPins.push(pinIdValue);
1110
+ }
1111
+ }
1133
1112
  });
1134
- if (unplacedPins.length > 0) {
1135
- throw "'arrange' property is defined, but not all pins are specified: " + unplacedPins.join(",");
1136
- }
1113
+ }
1114
+ const unplacedPins = existingPinIds.filter(pinId => {
1115
+ return addedPins.indexOf(pinId) === -1;
1116
+ });
1117
+ if (unplacedPins.length > 0) {
1118
+ component._unplacedPins = unplacedPins;
1119
+ console.warn("Warning: There are unplaced pins: " + unplacedPins);
1137
1120
  }
1138
1121
  return symbolPinDefinitions;
1139
1122
  }
1140
1123
  function applyComponentParamsToSymbol(component, symbol) {
1124
+ const { widthProp = null, heightProp = null } = component;
1141
1125
  const newMap = new Map(component.parameters);
1142
1126
  if (!newMap.has('refdes')) {
1143
1127
  newMap.set('refdes', component.assignedRefDes ?? "?");
1144
1128
  }
1145
1129
  symbol.drawing.variables = newMap;
1130
+ if (component.parameters.has(globals_js_1.ParamKeys.angle)) {
1131
+ const value = component.parameters.get(globals_js_1.ParamKeys.angle).toNumber();
1132
+ symbol.angle = value;
1133
+ }
1134
+ if (component.parameters.has(globals_js_1.ParamKeys.flipX)) {
1135
+ symbol.flipX =
1136
+ component.parameters.get(globals_js_1.ParamKeys.flipX);
1137
+ }
1138
+ if (component.parameters.has(globals_js_1.ParamKeys.flipY)) {
1139
+ symbol.flipY =
1140
+ component.parameters.get(globals_js_1.ParamKeys.flipY);
1141
+ }
1142
+ if (symbol instanceof draw_symbols_js_1.SymbolCustom) {
1143
+ if (widthProp) {
1144
+ symbol.bodyWidth = (0, helpers_js_1.milsToMM)(widthProp);
1145
+ }
1146
+ if (heightProp) {
1147
+ symbol.bodyHeight = (0, helpers_js_1.milsToMM)(heightProp);
1148
+ }
1149
+ }
1146
1150
  }
1147
1151
  exports.applyComponentParamsToSymbol = applyComponentParamsToSymbol;
1148
1152
  function calculateSymbolAngle(symbol, pin, direction) {
@@ -1469,7 +1473,9 @@ function CalculatePinPositions(component) {
1469
1473
  tmpSymbol.refreshDrawing();
1470
1474
  const pins = component.pins;
1471
1475
  pins.forEach((value, key) => {
1472
- pinPositionMapping.set(key, tmpSymbol.pinPosition(key));
1476
+ if (component._unplacedPins.indexOf(key) === -1) {
1477
+ pinPositionMapping.set(key, tmpSymbol.pinPosition(key));
1478
+ }
1473
1479
  });
1474
1480
  return pinPositionMapping;
1475
1481
  }
@@ -14,6 +14,7 @@ class ClassComponent {
14
14
  this.pinsMaxPositions = new Map();
15
15
  this._copyID = null;
16
16
  this._copyFrom = null;
17
+ this._unplacedPins = [];
17
18
  this.arrangeProps = null;
18
19
  this.displayProp = null;
19
20
  this.widthProp = null;
@@ -132,12 +132,13 @@ class ExecutionScope {
132
132
  exitContext() {
133
133
  return this.contextStack.pop();
134
134
  }
135
- findPropertyKeyTree() {
135
+ findPropertyKeyTree(visitor) {
136
136
  const keyNames = [];
137
137
  for (let i = this.contextStack.length - 1; i >= 0; i--) {
138
138
  const ctx = this.contextStack[i];
139
139
  if (ctx instanceof CircuitScriptParser_js_1.Property_key_exprContext) {
140
- keyNames.push([ctx, ctx.getText()]);
140
+ const result = visitor.visitResult(ctx);
141
+ keyNames.push([ctx, result]);
141
142
  }
142
143
  else if (typeof ctx === 'number') {
143
144
  keyNames.push(['index', ctx]);
@@ -151,9 +152,9 @@ class ExecutionScope {
151
152
  popOnPropertyHandler() {
152
153
  return this.onPropertyHandler.pop();
153
154
  }
154
- triggerPropertyHandler(value, valueCtx) {
155
+ triggerPropertyHandler(visitor, value, valueCtx) {
155
156
  const lastHandler = this.onPropertyHandler[this.onPropertyHandler.length - 1];
156
- const propertyTree = this.findPropertyKeyTree();
157
+ const propertyTree = this.findPropertyKeyTree(visitor);
157
158
  lastHandler && lastHandler(propertyTree, value, valueCtx);
158
159
  }
159
160
  }
@@ -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.forEach(file => {
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
- (0, helpers_js_1.renderScript)(scriptData, outputPath, {
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
- console.log('generated ', outputPath);
33
- });
34
+ }
34
35
  return cstFiles;
35
36
  }
36
37
  (async () => {