circuitscript 0.0.31 → 0.0.34

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 (51) hide show
  1. package/dist/cjs/BaseVisitor.js +187 -39
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +226 -185
  3. package/dist/cjs/antlr/CircuitScriptParser.js +1439 -902
  4. package/dist/cjs/draw_symbols.js +1 -0
  5. package/dist/cjs/execute.js +16 -12
  6. package/dist/cjs/globals.js +15 -2
  7. package/dist/cjs/helpers.js +81 -6
  8. package/dist/cjs/layout.js +120 -37
  9. package/dist/cjs/objects/ClassComponent.js +3 -0
  10. package/dist/cjs/objects/ExecutionScope.js +1 -0
  11. package/dist/cjs/objects/Frame.js +6 -1
  12. package/dist/cjs/objects/ParamDefinition.js +1 -7
  13. package/dist/cjs/objects/types.js +6 -0
  14. package/dist/cjs/regenerate-tests.js +2 -1
  15. package/dist/cjs/render.js +243 -45
  16. package/dist/cjs/visitor.js +162 -27
  17. package/dist/esm/BaseVisitor.mjs +189 -41
  18. package/dist/esm/antlr/CircuitScriptLexer.mjs +226 -185
  19. package/dist/esm/antlr/CircuitScriptParser.mjs +1428 -899
  20. package/dist/esm/antlr/CircuitScriptVisitor.mjs +9 -2
  21. package/dist/esm/draw_symbols.mjs +1 -0
  22. package/dist/esm/execute.mjs +16 -12
  23. package/dist/esm/globals.mjs +14 -1
  24. package/dist/esm/helpers.mjs +81 -8
  25. package/dist/esm/layout.mjs +120 -38
  26. package/dist/esm/objects/ClassComponent.mjs +3 -0
  27. package/dist/esm/objects/ExecutionScope.mjs +1 -0
  28. package/dist/esm/objects/Frame.mjs +7 -1
  29. package/dist/esm/objects/ParamDefinition.mjs +0 -6
  30. package/dist/esm/objects/types.mjs +6 -0
  31. package/dist/esm/regenerate-tests.mjs +2 -1
  32. package/dist/esm/render.mjs +239 -46
  33. package/dist/esm/visitor.mjs +164 -29
  34. package/dist/types/BaseVisitor.d.ts +8 -2
  35. package/dist/types/antlr/CircuitScriptLexer.d.ts +41 -30
  36. package/dist/types/antlr/CircuitScriptParser.d.ts +169 -81
  37. package/dist/types/antlr/CircuitScriptVisitor.d.ts +18 -4
  38. package/dist/types/draw_symbols.d.ts +2 -1
  39. package/dist/types/execute.d.ts +6 -3
  40. package/dist/types/globals.d.ts +12 -0
  41. package/dist/types/helpers.d.ts +12 -0
  42. package/dist/types/layout.d.ts +23 -10
  43. package/dist/types/objects/ClassComponent.d.ts +2 -1
  44. package/dist/types/objects/ExecutionScope.d.ts +2 -0
  45. package/dist/types/objects/Frame.d.ts +8 -2
  46. package/dist/types/objects/ParamDefinition.d.ts +0 -4
  47. package/dist/types/objects/types.d.ts +4 -2
  48. package/dist/types/render.d.ts +6 -10
  49. package/dist/types/visitor.d.ts +10 -2
  50. package/libs/lib.cst +283 -0
  51. package/package.json +5 -1
@@ -24,11 +24,14 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
24
24
  visitAt_block_pin_expression_simple;
25
25
  visitAt_block_pin_expression_complex;
26
26
  visitBreak_keyword;
27
+ visitContinue_keyword;
27
28
  visitAssignment_expr;
29
+ visitOperator_assignment_expr;
28
30
  visitKeyword_assignment_expr;
29
31
  visitParameters;
30
32
  visitProperty_set_expr;
31
33
  visitDouble_dot_property_set_expr;
34
+ visitArrayExpr;
32
35
  visitFunctionCallExpr;
33
36
  visitAdditionExpr;
34
37
  visitMultiplyExpr;
@@ -51,22 +54,26 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
51
54
  visitFunction_return_expr;
52
55
  visitProperty_block_expr;
53
56
  visitCreate_component_expr;
57
+ visitGraphic_expressions_block;
54
58
  visitCreate_graphic_expr;
55
59
  visitCreate_module_expr;
56
60
  visitNested_properties_inner;
57
- visitGraphic_expr;
61
+ visitGraphicCommandExpr;
62
+ visitGraphicForExpr;
58
63
  visitProperty_expr;
59
64
  visitProperty_key_expr;
60
65
  visitNested_properties;
61
66
  visitSingle_line_property;
62
- visitBlank_expr;
63
67
  visitWire_expr_direction_value;
64
68
  visitWire_expr_direction_only;
65
69
  visitWire_expr;
70
+ visitArray_expr;
66
71
  visitPoint_expr;
67
72
  visitImport_expr;
68
73
  visitFrame_expr;
69
74
  visitIf_expr;
70
75
  visitIf_inner_expr;
71
76
  visitElse_expr;
77
+ visitWhile_expr;
78
+ visitFor_expr;
72
79
  }
@@ -599,6 +599,7 @@ export var PlaceHolderCommands;
599
599
  PlaceHolderCommands["textColor"] = "textColor";
600
600
  PlaceHolderCommands["text"] = "text";
601
601
  PlaceHolderCommands["units"] = "units";
602
+ PlaceHolderCommands["for"] = "for";
602
603
  })(PlaceHolderCommands || (PlaceHolderCommands = {}));
603
604
  export class SymbolCustom extends SymbolGraphic {
604
605
  pinDefinition = [];
@@ -443,12 +443,16 @@ export class ExecutionContext {
443
443
  this.log('did not find block point');
444
444
  return null;
445
445
  }
446
- breakBranch() {
447
- this.log('break branch');
448
- const branchesInfo = this.scope.blockStack.get(this.scope.indentLevel - 1);
449
- const branchIndex = branchesInfo['block_index'];
450
- const branchIndexRef = branchesInfo['inner_blocks'].get(branchIndex);
451
- branchIndexRef['ignore_last_net'] = true;
446
+ addBreakContext(ctx) {
447
+ this.log('add break context');
448
+ this.scope.breakStack.push(ctx);
449
+ }
450
+ popBreakContext() {
451
+ this.log('pop break context');
452
+ return this.scope.breakStack.pop();
453
+ }
454
+ getBreakContext() {
455
+ return this.scope.breakStack[this.scope.breakStack.length - 1];
452
456
  }
453
457
  createFunction(functionName, __runFunc) {
454
458
  this.scope.functions.set(functionName, __runFunc);
@@ -780,9 +784,10 @@ export class ExecutionContext {
780
784
  }
781
785
  }
782
786
  }
783
- enterFrame() {
787
+ enterFrame(frameType) {
784
788
  const frameId = this.scope.frames.length + 1;
785
- const frameObject = new Frame(frameId);
789
+ const frameObject = new Frame(frameId, frameType);
790
+ this.log('Enter frame', frameId);
786
791
  this.scope.frames.push(frameObject);
787
792
  this.scope.sequence.push([SequenceAction.Frame,
788
793
  frameObject, FrameAction.Enter]);
@@ -794,6 +799,7 @@ export class ExecutionContext {
794
799
  const frame = this.scope.frames[frameId - 1];
795
800
  this.scope.sequence.push([SequenceAction.Frame,
796
801
  frame, FrameAction.Exit]);
802
+ this.log('Leave frame', frameId);
797
803
  }
798
804
  }
799
805
  function isWireSegmentsEndAuto(segments) {
@@ -844,10 +850,8 @@ export function getPortSide(pins, arrangeProps) {
844
850
  }
845
851
  let position = 0;
846
852
  useItems.forEach(item => {
847
- if (typeof item === 'object') {
848
- if (item.blank) {
849
- position += item.blank;
850
- }
853
+ if (typeof item === 'object' && Array.isArray(item)) {
854
+ position += item[0];
851
855
  }
852
856
  if (existingPinIds.indexOf(item) !== -1) {
853
857
  result.push({
@@ -36,6 +36,7 @@ export var WireAutoDirection;
36
36
  })(WireAutoDirection || (WireAutoDirection = {}));
37
37
  export const MilsToMM = 0.0254;
38
38
  export const MMToPx = 3.779276;
39
+ export const MMToPt = 2.8346456693;
39
40
  export const PxToMM = 0.2645833;
40
41
  export const portWidth = 20;
41
42
  export const portHeight = 2;
@@ -46,6 +47,8 @@ export const defaultSymbolLineWidth = MilsToMM * 6;
46
47
  export const defaultWireLineWidth = MilsToMM * 6;
47
48
  export const defaultPinNameTextSize = 40;
48
49
  export const defaultPinIdTextSize = 30;
50
+ export const defaultPageMarginMM = 10;
51
+ export const defaultPageSpacingMM = 10;
49
52
  export const CustomSymbolPinTextSize = defaultPinNameTextSize;
50
53
  export const CustomSymbolPinIdSize = defaultPinIdTextSize;
51
54
  export const CustomSymbolRefDesSize = 50;
@@ -61,7 +64,7 @@ export const PortPaddingHorizontal = MilsToMM * 10;
61
64
  export const PortPaddingVertical = MilsToMM * 10;
62
65
  export const ColorScheme = {
63
66
  BodyColor: 'rgb(255, 255, 194)',
64
- JunctionColor: 'rgba(0, 132, 0)',
67
+ JunctionColor: 'rgb(0, 132, 0)',
65
68
  WireColor: 'rgb(0, 132, 0)',
66
69
  PinLineColor: '#333',
67
70
  PinNameColor: '#333',
@@ -88,3 +91,13 @@ export var BlockTypes;
88
91
  BlockTypes[BlockTypes["Parallel"] = 3] = "Parallel";
89
92
  BlockTypes[BlockTypes["Point"] = 4] = "Point";
90
93
  })(BlockTypes || (BlockTypes = {}));
94
+ export var FrameType;
95
+ (function (FrameType) {
96
+ FrameType[FrameType["Frame"] = 1] = "Frame";
97
+ FrameType[FrameType["Sheet"] = 2] = "Sheet";
98
+ })(FrameType || (FrameType = {}));
99
+ export const GlobalDocumentName = 'document';
100
+ export const RenderFlags = {
101
+ ShowElementFrames: false,
102
+ ShowOrigin: false,
103
+ };
@@ -1,9 +1,11 @@
1
- import { readFileSync, writeFileSync } from "fs";
1
+ import { readFileSync, writeFileSync, createWriteStream } from "fs";
2
+ import path from "path";
3
+ import PDFDocument from "pdfkit";
2
4
  import { generateKiCADNetList, printTree } from "./export.mjs";
3
5
  import { LayoutEngine } from "./layout.mjs";
4
6
  import { SequenceAction } from "./objects/ExecutionScope.mjs";
5
7
  import { parseFileWithVisitor } from "./parser.mjs";
6
- import { generateSVG2 } from "./render.mjs";
8
+ import { generatePdfOutput, generateSvgOutput, renderSheetsToSVG } from "./render.mjs";
7
9
  import { SimpleStopwatch } from "./utils.mjs";
8
10
  import { ParserVisitor, VisitorExecutionException } from "./visitor.mjs";
9
11
  import { createContext } from "this-file";
@@ -12,8 +14,8 @@ import { BaseErrorListener, CharStream, CommonTokenStream, DefaultErrorStrategy
12
14
  import { MainLexer } from "./lexer.mjs";
13
15
  import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
14
16
  import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.mjs";
15
- import path from "path";
16
- import { LengthUnit, MilsToMM, PxToMM } from "./globals.mjs";
17
+ import { defaultPageMarginMM, defaultZoomScale, LengthUnit, MilsToMM, PxToMM } from "./globals.mjs";
18
+ import { FrameParamKeys } from "./objects/Frame.mjs";
17
19
  export var JSModuleType;
18
20
  (function (JSModuleType) {
19
21
  JSModuleType["CommonJs"] = "cjs";
@@ -174,6 +176,7 @@ export function renderScript(scriptData, outputPath, options) {
174
176
  console.log('Error while parsing');
175
177
  return null;
176
178
  }
179
+ const { frameComponent } = visitor.applySheetFrameComponent();
177
180
  try {
178
181
  visitor.annotateComponents();
179
182
  }
@@ -206,19 +209,49 @@ export function renderScript(scriptData, outputPath, options) {
206
209
  return tmp.join(" | ");
207
210
  });
208
211
  dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
209
- let svgOutput = null;
212
+ let svgOutput = "";
210
213
  try {
214
+ let fileExtension = null;
215
+ let outputDefaultZoom = defaultZoomScale;
216
+ if (outputPath) {
217
+ fileExtension = path.extname(outputPath).substring(1);
218
+ if (fileExtension === "pdf") {
219
+ outputDefaultZoom = 1;
220
+ }
221
+ }
211
222
  const layoutEngine = new LayoutEngine();
212
223
  const layoutTimer = new SimpleStopwatch();
213
- const graph = layoutEngine.runLayout(sequence, nets);
224
+ const sheetFrames = layoutEngine.runLayout(sequence, nets);
214
225
  layoutEngine.printWarnings();
215
226
  showStats && console.log('Layout took:', layoutTimer.lap());
216
227
  dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
217
228
  const generateSvgTimer = new SimpleStopwatch();
218
- svgOutput = generateSVG2(graph);
229
+ const svgCanvas = renderSheetsToSVG(sheetFrames);
219
230
  showStats && console.log('Render took:', generateSvgTimer.lap());
231
+ svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
220
232
  if (outputPath) {
221
- writeFileSync(outputPath, svgOutput);
233
+ if (fileExtension === 'svg') {
234
+ writeFileSync(outputPath, svgOutput);
235
+ }
236
+ else if (fileExtension === 'pdf') {
237
+ let sheetSize = "A4";
238
+ let sheetSizeDefined = false;
239
+ if (frameComponent) {
240
+ sheetSize = frameComponent.getParam(FrameParamKeys.PaperSize);
241
+ sheetSizeDefined = true;
242
+ }
243
+ const doc = new PDFDocument({
244
+ layout: 'landscape',
245
+ size: sheetSize
246
+ });
247
+ const outputStream = createWriteStream(outputPath);
248
+ generatePdfOutput(doc, svgCanvas, sheetSize, sheetSizeDefined, outputDefaultZoom);
249
+ doc.pipe(outputStream);
250
+ doc.end();
251
+ }
252
+ else {
253
+ throw "Invalid output format";
254
+ }
222
255
  console.log('Generated file', outputPath);
223
256
  }
224
257
  }
@@ -291,3 +324,43 @@ export function milsToMM(value) {
291
324
  export function pxToMM(value) {
292
325
  return value * PxToMM;
293
326
  }
327
+ const PaperSizes = {
328
+ 'A0': [1189, 841],
329
+ 'A1': [841, 594],
330
+ 'A2': [594, 420],
331
+ 'A3': [420, 297],
332
+ 'A4': [297, 210],
333
+ 'A5': [210, 148],
334
+ 'A6': [148, 105],
335
+ };
336
+ export const PaperGridReferences = {
337
+ 'A0': [16, 24],
338
+ 'A1': [12, 16],
339
+ 'A2': [8, 12],
340
+ 'A3': [6, 8],
341
+ 'A4': [4, 6],
342
+ };
343
+ export function isSupportedPaperSize(type) {
344
+ if (PaperSizes[type]) {
345
+ return true;
346
+ }
347
+ return false;
348
+ }
349
+ export function getPaperSize(type, margin = defaultPageMarginMM) {
350
+ if (PaperSizes[type]) {
351
+ const [width, height] = PaperSizes[type];
352
+ const useWidth = width - margin * 2;
353
+ const useHeight = height - margin * 2;
354
+ return {
355
+ width: Math.floor(useWidth * (1 / MilsToMM)),
356
+ height: Math.floor(useHeight * (1 / MilsToMM)),
357
+ widthMM: useWidth,
358
+ heightMM: useHeight,
359
+ originalWidthMM: width,
360
+ originalHeightMM: height,
361
+ };
362
+ }
363
+ else {
364
+ return getPaperSize('A4');
365
+ }
366
+ }
@@ -1,7 +1,7 @@
1
1
  import { Graph, alg } from '@dagrejs/graphlib';
2
- import { SymbolCustom, SymbolDrawing, SymbolFactory, SymbolCustomModule, SymbolPlaceholder, SymbolText } from "./draw_symbols.mjs";
2
+ import { SymbolCustom, SymbolDrawing, SymbolFactory, SymbolCustomModule, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.mjs";
3
3
  import { FrameAction, SequenceAction } from "./objects/ExecutionScope.mjs";
4
- import { defaultFrameTitleTextSize, defaultGridSizeUnits, GlobalNames, ParamKeys, WireAutoDirection } from './globals.mjs';
4
+ import { defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, GlobalNames, ParamKeys, WireAutoDirection } from './globals.mjs';
5
5
  import { NumericValue } from './objects/ParamDefinition.mjs';
6
6
  import { Geometry } from './geometry.mjs';
7
7
  import { Logger } from './logger.mjs';
@@ -13,8 +13,11 @@ export class LayoutEngine {
13
13
  logger;
14
14
  placeSubgraphVersion = 2;
15
15
  layoutWarnings = [];
16
- constructor() {
16
+ showBaseFrame = false;
17
+ constructor(options = { showBaseFrame: false }) {
17
18
  this.logger = new Logger();
19
+ const { showBaseFrame = false } = options ?? {};
20
+ this.showBaseFrame = showBaseFrame;
18
21
  }
19
22
  print(...params) {
20
23
  this.logger.add(params.join(' '));
@@ -58,38 +61,51 @@ export class LayoutEngine {
58
61
  this.print('-- items:', item.components);
59
62
  });
60
63
  }
61
- const { textObjects, elementFrames } = this.placeFrames(graph, subgraphInfo, containerFrames);
64
+ const { elementFrames } = this.placeFrames(graph, subgraphInfo, containerFrames);
62
65
  const frameObjects = [...elementFrames, ...containerFrames];
63
- const placedComponents = [];
64
- const placedWires = [];
65
- const tmpNodes = graph.nodes();
66
- tmpNodes.forEach(item => {
67
- const nodeValue = graph.node(item);
68
- const [nodeType, nodeItem] = nodeValue;
69
- if (nodeType === RenderItemType.Component) {
70
- placedComponents.push(nodeItem);
71
- }
72
- else if (nodeType === RenderItemType.Wire) {
73
- placedWires.push(nodeItem);
74
- }
66
+ const sheetFrames = frameObjects.filter(item => {
67
+ return item.frame.frameType === FrameType.Sheet;
68
+ });
69
+ if (sheetFrames.length === 0) {
70
+ sheetFrames.push(containerFrames[0]);
71
+ }
72
+ const sheetFrameObjects = sheetFrames.map(sheet => {
73
+ const items = this.flattenFrameItems(sheet);
74
+ const components = items.filter(item => item instanceof RenderComponent);
75
+ const wires = items.filter(item => item instanceof RenderWire);
76
+ const textObjects = items.filter(item => item instanceof RenderText);
77
+ const frames = items.filter(item => item instanceof RenderFrame);
78
+ const wireGroups = new Map();
79
+ wires.forEach(wire => {
80
+ const { netName } = wire;
81
+ if (!wireGroups.has(netName)) {
82
+ wireGroups.set(netName, []);
83
+ }
84
+ wireGroups.get(netName).push(wire);
85
+ });
86
+ const { junctions, mergedWires } = this.findJunctions(wireGroups);
87
+ return {
88
+ frame: sheet,
89
+ frames,
90
+ components,
91
+ wires,
92
+ textObjects,
93
+ junctions,
94
+ mergedWires,
95
+ };
75
96
  });
76
- const wireGroups = new Map();
77
- placedWires.forEach(wire => {
78
- const { netName } = wire;
79
- if (!wireGroups.has(netName)) {
80
- wireGroups.set(netName, []);
97
+ return sheetFrameObjects;
98
+ }
99
+ flattenFrameItems(frame) {
100
+ const items = [];
101
+ frame.innerItems.forEach(item => {
102
+ items.push(item);
103
+ if (item instanceof RenderFrame) {
104
+ const inner = this.flattenFrameItems(item);
105
+ items.push(...inner);
81
106
  }
82
- wireGroups.get(netName).push(wire);
83
107
  });
84
- const { junctions, mergedWires } = this.findJunctions(wireGroups);
85
- return {
86
- components: placedComponents,
87
- wires: placedWires,
88
- mergedWires,
89
- junctions,
90
- frameObjects,
91
- textObjects,
92
- };
108
+ return items;
93
109
  }
94
110
  findJunctions(wireGroups) {
95
111
  const junctions = [];
@@ -122,6 +138,11 @@ export class LayoutEngine {
122
138
  const baseFrame = frameObjects[0];
123
139
  baseFrame.padding = 0;
124
140
  baseFrame.borderWidth = 0;
141
+ if (this.showBaseFrame) {
142
+ baseFrame.borderWidth = 5;
143
+ baseFrame.width = 11692 - 400 * 2;
144
+ baseFrame.height = 8267 - 400 * 2;
145
+ }
125
146
  baseFrame.x = 0;
126
147
  baseFrame.y = 0;
127
148
  let textObjects = [];
@@ -134,7 +155,7 @@ export class LayoutEngine {
134
155
  const result = this.prepareFrames(graph, subgraphInfo, baseFrame);
135
156
  textObjects = result.textObjects;
136
157
  elementFrames = result.elementFrames;
137
- const logFrames = false;
158
+ const logFrames = true;
138
159
  if (logFrames) {
139
160
  this.print('===== dump frames =====');
140
161
  this.dumpFrame(baseFrame);
@@ -168,8 +189,14 @@ export class LayoutEngine {
168
189
  this.print(level, "".padStart(level * 4), 'frame', frame.x, frame.y);
169
190
  const innerItems = frame.innerItems;
170
191
  innerItems.forEach(innerFrame => {
171
- innerFrame.x += frame.x;
172
- innerFrame.y += frame.y;
192
+ if (innerFrame.frame.frameType === FrameType.Sheet) {
193
+ innerFrame.x = 0;
194
+ innerFrame.y = 0;
195
+ }
196
+ else {
197
+ innerFrame.x += frame.x;
198
+ innerFrame.y += frame.y;
199
+ }
173
200
  if (innerFrame.type === RenderFrameType.Elements) {
174
201
  this.print(level, "".padStart(level * 4), 'element frame', innerFrame.x, innerFrame.y);
175
202
  innerFrame.innerItems.forEach(item2 => {
@@ -257,7 +284,34 @@ export class LayoutEngine {
257
284
  }
258
285
  boundPoints.push([innerFrame.x, innerFrame.y], [innerFrame.x + frameWidth, innerFrame.y + frameHeight]);
259
286
  });
260
- frame.bounds = resizeBounds(getBoundsFromPoints(boundPoints), frame.padding);
287
+ const contentsBounds = resizeBounds(getBoundsFromPoints(boundPoints), frame.padding);
288
+ if (frame.frame.parameters.has(FrameParamKeys.SheetFrame)) {
289
+ const frameComponent = frame.frame.parameters.get(FrameParamKeys.SheetFrame);
290
+ const rects = ExtractDrawingRects(frameComponent.displayProp);
291
+ let frameWidth = 0;
292
+ let frameHeight = 0;
293
+ if (rects[1]) {
294
+ frameWidth = milsToMM(rects[1].width);
295
+ frameHeight = milsToMM(rects[1].height);
296
+ }
297
+ const contentsWidth = contentsBounds.xmax - contentsBounds.xmin;
298
+ const contentsHeight = contentsBounds.ymax - contentsBounds.ymin;
299
+ const frameOffsetX = toNearestGrid((frameWidth - contentsWidth) / 2, gridSize);
300
+ const frameOffsetY = toNearestGrid((frameHeight - contentsHeight) / 2, gridSize);
301
+ innerFrames.forEach(innerFrame => {
302
+ innerFrame.x += frameOffsetX;
303
+ innerFrame.y += frameOffsetY;
304
+ });
305
+ frame.bounds = {
306
+ xmin: 0,
307
+ ymin: 0,
308
+ xmax: frameWidth,
309
+ ymax: frameHeight
310
+ };
311
+ }
312
+ else {
313
+ frame.bounds = contentsBounds;
314
+ }
261
315
  }
262
316
  dumpFrame(frame, level = 0) {
263
317
  this.print(level, "".padStart(level * 4), 'frame, items:', frame.innerItems.length);
@@ -495,6 +549,14 @@ export class LayoutEngine {
495
549
  newFrame.borderWidth =
496
550
  frameObject.parameters.get(FrameParamKeys.Border);
497
551
  }
552
+ if (frameObject.parameters.has(FrameParamKeys.Width)) {
553
+ newFrame.width =
554
+ frameObject.parameters.get(FrameParamKeys.Width);
555
+ }
556
+ if (frameObject.parameters.has(FrameParamKeys.Height)) {
557
+ newFrame.height =
558
+ frameObject.parameters.get(FrameParamKeys.Height);
559
+ }
498
560
  containerFrames.push(newFrame);
499
561
  frameStack.push(newFrame);
500
562
  prevFrame && prevFrame.innerItems.push(newFrame);
@@ -656,14 +718,20 @@ export class LayoutEngine {
656
718
  floatingNode.isFloating = false;
657
719
  this.print('set node as not floating:', floatingNode);
658
720
  const originNode = findOriginNode(fixedNode);
659
- originNodeGroups.get(originNode).push(floatingNode);
660
- this.print('linking node', floatingNode, 'to origin node', originNode);
721
+ const itemsArray = originNodeGroups.get(originNode);
722
+ if (itemsArray.indexOf(floatingNode) === -1) {
723
+ itemsArray.push(floatingNode);
724
+ this.print('linking node', floatingNode, 'to origin node', originNode);
725
+ }
726
+ else {
727
+ this.print('node is alread linked', floatingNode, 'to origin node', originNode);
728
+ }
661
729
  }
662
730
  [node1, node2].forEach(item => {
663
731
  if (item instanceof RenderWire && item.isEndAutoLength()) {
664
732
  const [instance, pin] = item.getEndAuto();
665
733
  const [, targetNode] = graph.node(instance.instanceName);
666
- this.print('wire auto length to target:', instance, pin);
734
+ this.print('wire', item, 'auto length to target:', instance, pin);
667
735
  if (targetNode.isFloating) {
668
736
  throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin " + pin;
669
737
  }
@@ -674,6 +742,7 @@ export class LayoutEngine {
674
742
  }
675
743
  const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
676
744
  item.setEndAuto(untilX, untilY);
745
+ this.print(`set wire auto end at: ${untilX} ${untilY}`);
677
746
  }
678
747
  });
679
748
  });
@@ -1226,6 +1295,9 @@ export class RenderFrame extends RenderObject {
1226
1295
  gap = milsToMM(100);
1227
1296
  direction = FramePlotDirection.Column;
1228
1297
  borderWidth = 5;
1298
+ width = null;
1299
+ height = null;
1300
+ size = null;
1229
1301
  subgraphId = "";
1230
1302
  type;
1231
1303
  containsTitle = false;
@@ -1276,6 +1348,16 @@ export function CalculatePinPositions(component) {
1276
1348
  });
1277
1349
  return pinPositionMapping;
1278
1350
  }
1351
+ export function ExtractDrawingRects(drawing) {
1352
+ return drawing.getCommands().filter(item => {
1353
+ return (item[0] === PlaceHolderCommands.rect);
1354
+ }).map(item => {
1355
+ return {
1356
+ width: item[1][2],
1357
+ height: item[1][3],
1358
+ };
1359
+ });
1360
+ }
1279
1361
  function isPointOverlap(x, y, other) {
1280
1362
  return (x >= other.x && y >= other.y && x <= (other.x + other.width) && y <= (other.y + other.height));
1281
1363
  }
@@ -85,6 +85,9 @@ export class ClassComponent {
85
85
  this.parameters.set(key, value);
86
86
  this.refreshParamCache();
87
87
  }
88
+ hasParam(key) {
89
+ return this.parameters.has(key);
90
+ }
88
91
  refreshParamCache() {
89
92
  this._cachedParams =
90
93
  JSON.stringify(Object.fromEntries(this.parameters));
@@ -6,6 +6,7 @@ export class ExecutionScope {
6
6
  variables = new Map();
7
7
  symbols = new Map();
8
8
  blockStack = new Map();
9
+ breakStack = [];
9
10
  wires = [];
10
11
  frames = [];
11
12
  indentLevel = 0;
@@ -1,8 +1,10 @@
1
1
  export class Frame {
2
2
  parameters = new Map();
3
3
  frameId;
4
- constructor(frameId) {
4
+ frameType;
5
+ constructor(frameId, frameType) {
5
6
  this.frameId = frameId;
7
+ this.frameType = frameType;
6
8
  }
7
9
  }
8
10
  export var FrameParamKeys;
@@ -11,6 +13,10 @@ export var FrameParamKeys;
11
13
  FrameParamKeys["Direction"] = "direction";
12
14
  FrameParamKeys["Padding"] = "padding";
13
15
  FrameParamKeys["Border"] = "border";
16
+ FrameParamKeys["Width"] = "width";
17
+ FrameParamKeys["Height"] = "height";
18
+ FrameParamKeys["PaperSize"] = "paper_size";
19
+ FrameParamKeys["SheetFrame"] = "sheet_frame";
14
20
  })(FrameParamKeys || (FrameParamKeys = {}));
15
21
  export var FramePlotDirection;
16
22
  (function (FramePlotDirection) {
@@ -32,9 +32,3 @@ export class PercentageValue {
32
32
  return this.value.toString();
33
33
  }
34
34
  }
35
- export class PinBlankValue {
36
- blank;
37
- constructor(value) {
38
- this.blank = value;
39
- }
40
- }
@@ -3,6 +3,9 @@ export class UndeclaredReference {
3
3
  constructor(reference) {
4
4
  this.reference = reference;
5
5
  }
6
+ throwMessage() {
7
+ return `Unknown symbol: ${this.reference.name}`;
8
+ }
6
9
  }
7
10
  export class DeclaredReference {
8
11
  found;
@@ -17,6 +20,9 @@ export class DeclaredReference {
17
20
  this.type = refType.type;
18
21
  this.value = refType.value;
19
22
  }
23
+ toString() {
24
+ return `[DeclaredReference name: ${this.name} trailers:${this.trailers} found: ${this.found}]`;
25
+ }
20
26
  }
21
27
  export var ParseSymbolType;
22
28
  (function (ParseSymbolType) {
@@ -26,7 +26,8 @@ async function regenerateTests(extra = "") {
26
26
  return cstFiles;
27
27
  }
28
28
  (async () => {
29
- const generateDiff = false;
29
+ const generateDiff = (process.argv.indexOf('-diff') !== -1);
30
+ console.log('diff flag: ', generateDiff);
30
31
  const nextExtra = generateDiff ? '.next' : '';
31
32
  const cstFiles = await regenerateTests(nextExtra);
32
33
  const allFiles = [];