circuitscript 0.0.32 → 0.0.35

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 +14 -12
  6. package/dist/cjs/globals.js +14 -2
  7. package/dist/cjs/helpers.js +62 -19
  8. package/dist/cjs/layout.js +88 -36
  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 +4 -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 +238 -42
  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 +14 -12
  23. package/dist/esm/globals.mjs +13 -1
  24. package/dist/esm/helpers.mjs +61 -20
  25. package/dist/esm/layout.mjs +88 -37
  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 +5 -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 +234 -43
  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 +11 -0
  41. package/dist/types/helpers.d.ts +12 -0
  42. package/dist/types/layout.d.ts +17 -9
  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 +6 -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 -14
  49. package/dist/types/visitor.d.ts +10 -2
  50. package/libs/lib.cst +283 -0
  51. package/package.json +1 -1
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateSVG2 = void 0;
6
+ exports.generatePdfOutput = exports.generateSvgOutput = exports.renderSheetsToSVG = void 0;
4
7
  const svg_js_1 = require("@svgdotjs/svg.js");
5
8
  const layout_js_1 = require("./layout.js");
6
9
  const sizing_js_1 = require("./sizing.js");
@@ -8,34 +11,115 @@ const globals_js_1 = require("./globals.js");
8
11
  const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
9
12
  const utils_js_1 = require("./utils.js");
10
13
  const helpers_js_1 = require("./helpers.js");
11
- function generateSVG2(graph) {
14
+ const svg_to_pdfkit_1 = __importDefault(require("svg-to-pdfkit"));
15
+ const Frame_js_1 = require("./objects/Frame.js");
16
+ const draw_symbols_js_1 = require("./draw_symbols.js");
17
+ function createSvgCanvas() {
12
18
  const window = (0, sizing_js_1.getCreateSVGWindow)()();
13
19
  const document = window.document;
14
20
  (0, svg_js_1.registerWindow)(window, document);
15
21
  const canvas = (0, svg_js_1.SVG)(document.documentElement);
16
22
  (0, sizing_js_1.applyFontsToSVG)(canvas);
17
- generateSVGChild(canvas, graph.components, graph.wires, graph.junctions, graph.mergedWires, graph.frameObjects, graph.textObjects);
18
- const scale = globals_js_1.MMToPx * globals_js_1.defaultZoomScale;
23
+ return canvas;
24
+ }
25
+ function renderSheetsToSVG(sheetFrames) {
26
+ const canvas = createSvgCanvas();
27
+ sheetFrames.forEach((sheet, index) => {
28
+ const sheetGroup = canvas.group();
29
+ sheetGroup.id('sheet-' + index);
30
+ const { components, wires, junctions, mergedWires, frames, textObjects } = sheet;
31
+ const allFrames = [sheet.frame, ...frames];
32
+ let gridBounds = null;
33
+ let extendGrid = true;
34
+ let xOffset = 0;
35
+ let yOffset = 0;
36
+ let sheetYOffset = 0;
37
+ if (sheet.frame.frame) {
38
+ const frameComponent = sheet.frame.frame.parameters
39
+ .get(Frame_js_1.FrameParamKeys.SheetFrame);
40
+ if (frameComponent) {
41
+ if (frameComponent.displayProp === null) {
42
+ throw 'Invalid graphic object for sheet frame';
43
+ }
44
+ const frameRects = (0, layout_js_1.ExtractDrawingRects)(frameComponent.displayProp) ?? [];
45
+ let originalWidthMM = 0;
46
+ let originalHeightMM = 0;
47
+ let widthMM = 0;
48
+ let heightMM = 0;
49
+ if (frameRects[0]) {
50
+ originalWidthMM = (0, helpers_js_1.milsToMM)(frameRects[0].width);
51
+ originalHeightMM = (0, helpers_js_1.milsToMM)(frameRects[0].height);
52
+ }
53
+ if (frameRects[1]) {
54
+ widthMM = (0, helpers_js_1.milsToMM)(frameRects[1].width);
55
+ heightMM = (0, helpers_js_1.milsToMM)(frameRects[1].height);
56
+ }
57
+ xOffset = (originalWidthMM - widthMM) / 2;
58
+ yOffset = (originalHeightMM - heightMM) / 2;
59
+ sheetYOffset = index * (originalHeightMM + globals_js_1.defaultPageSpacingMM);
60
+ gridBounds = {
61
+ xmin: 0,
62
+ ymin: 0,
63
+ xmax: widthMM,
64
+ ymax: heightMM
65
+ };
66
+ extendGrid = false;
67
+ }
68
+ }
69
+ const sheetElements = sheetGroup.group();
70
+ generateSVGChild(sheetElements, components, wires, junctions, mergedWires, allFrames, textObjects, gridBounds, extendGrid);
71
+ sheetElements.translate(xOffset, yOffset);
72
+ sheetGroup.translate(0, sheetYOffset);
73
+ });
74
+ return canvas;
75
+ }
76
+ exports.renderSheetsToSVG = renderSheetsToSVG;
77
+ function generateSvgOutput(canvas, zoomScale = 1) {
78
+ const scale = globals_js_1.MMToPx * zoomScale;
19
79
  const { x, y, width, height } = canvas.bbox();
20
80
  const scaledWidth = width * scale;
21
81
  const scaledHeight = height * scale;
22
82
  canvas.size(scaledWidth, scaledHeight);
23
83
  canvas.viewbox(x, y, width, height);
24
- return {
25
- svg: canvas.svg(),
26
- width, height,
27
- };
84
+ return canvas.svg();
28
85
  }
29
- exports.generateSVG2 = generateSVG2;
30
- function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects) {
31
- const displayWireId = false;
32
- const bounds = (0, layout_js_1.getBounds)(components, wires, junctions, frameObjects);
33
- drawGrid(canvas.group().translate(0, 0), {
34
- x: bounds.xmin,
35
- y: bounds.ymin,
36
- x2: bounds.xmax,
37
- y2: bounds.ymax
86
+ exports.generateSvgOutput = generateSvgOutput;
87
+ function generatePdfOutput(doc, canvas, sheetSize, sheetSizeDefined, zoomScale = 1) {
88
+ const children = canvas.children();
89
+ const numChildren = children.length;
90
+ const scale = globals_js_1.MMToPx * zoomScale;
91
+ const { originalWidthMM, originalHeightMM } = (0, helpers_js_1.getPaperSize)(sheetSize);
92
+ children.forEach((child, index) => {
93
+ const sheetCanvas = createSvgCanvas();
94
+ sheetCanvas.add(child);
95
+ const { x, y, width, height } = sheetCanvas.bbox();
96
+ const sheetBorder = child.find('#sheet-border');
97
+ if (sheetBorder.length > 0) {
98
+ sheetBorder[0].remove();
99
+ }
100
+ const scaledWidth = width * scale;
101
+ const scaledHeight = height * scale;
102
+ sheetCanvas.size(scaledWidth, scaledHeight);
103
+ sheetCanvas.viewbox(x, y, width, height);
104
+ let xOffset = 0;
105
+ let yOffset = 0;
106
+ if (!sheetSizeDefined) {
107
+ xOffset = (originalWidthMM - width) / 2;
108
+ yOffset = (originalHeightMM - height) / 2;
109
+ }
110
+ (0, svg_to_pdfkit_1.default)(doc, sheetCanvas.svg(), xOffset * globals_js_1.MMToPt, yOffset * globals_js_1.MMToPt);
111
+ if (index + 1 < numChildren) {
112
+ doc.addPage();
113
+ }
38
114
  });
115
+ }
116
+ exports.generatePdfOutput = generatePdfOutput;
117
+ function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects, gridBounds, extendGrid) {
118
+ const displayWireId = false;
119
+ if (gridBounds === null) {
120
+ gridBounds = (0, layout_js_1.getBounds)(components, wires, junctions, frameObjects);
121
+ }
122
+ drawGrid(canvas.group().translate(0, 0), gridBounds, extendGrid);
39
123
  components.forEach(item => {
40
124
  const { x, y, width, height } = item;
41
125
  const symbolGroup = canvas.group();
@@ -102,25 +186,29 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
102
186
  });
103
187
  });
104
188
  const frameGroup = canvas.group();
105
- const showElementFrames = false;
106
189
  frameObjects.forEach(item => {
107
190
  const { bounds, borderWidth } = item;
108
- if (borderWidth > 0) {
109
- const { width, height } = (0, utils_js_1.getBoundsSize)(bounds);
110
- let strokeColor = '#111';
111
- if (item.type === layout_js_1.RenderFrameType.Container) {
112
- strokeColor = '#111';
113
- }
114
- else if (item.type === layout_js_1.RenderFrameType.Elements) {
115
- strokeColor = '#aaa';
116
- if (!showElementFrames) {
117
- return;
191
+ const { width, height } = (0, utils_js_1.getBoundsSize)(bounds);
192
+ let strokeColor = '#111';
193
+ if (item.frame.frameType === globals_js_1.FrameType.Sheet) {
194
+ drawSheetFrameBorder(frameGroup, item);
195
+ }
196
+ else {
197
+ if (borderWidth > 0) {
198
+ if (item.type === layout_js_1.RenderFrameType.Container) {
199
+ strokeColor = '#111';
200
+ }
201
+ else if (item.type === layout_js_1.RenderFrameType.Elements) {
202
+ strokeColor = '#aaa';
203
+ if (!globals_js_1.RenderFlags.ShowElementFrames) {
204
+ return;
205
+ }
118
206
  }
207
+ const tmpRect = frameGroup.rect(width, height)
208
+ .fill('none')
209
+ .stroke({ width: (0, helpers_js_1.milsToMM)(borderWidth), color: strokeColor });
210
+ tmpRect.translate(item.x, item.y);
119
211
  }
120
- const tmpRect = frameGroup.rect(width, height)
121
- .fill('none')
122
- .stroke({ width: (0, helpers_js_1.milsToMM)(borderWidth), color: strokeColor });
123
- tmpRect.translate(item.x, item.y);
124
212
  }
125
213
  });
126
214
  textObjects.forEach(item => {
@@ -129,26 +217,31 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
129
217
  innerGroup.translate(x, y);
130
218
  symbol.draw(innerGroup);
131
219
  });
132
- const drawOrigin = false;
133
220
  const originSize = (0, helpers_js_1.milsToMM)(10);
134
- drawOrigin && canvas.group().translate(0, 0)
221
+ globals_js_1.RenderFlags.ShowOrigin && canvas.group().translate(0, 0)
135
222
  .circle(originSize)
136
223
  .translate(-originSize / 2, -originSize / 2)
137
224
  .stroke('none').fill('red');
138
225
  }
139
- function drawGrid(group, canvasSize) {
226
+ function drawGrid(group, canvasSize, extendGrid) {
140
227
  const gridSize = globals_js_1.defaultGridSizeUnits;
141
- const { x, y, x2, y2 } = canvasSize;
142
- const gridStartX = (Math.floor(x / gridSize) - 1) * gridSize;
143
- const gridStartY = (Math.floor(y / gridSize) - 1) * gridSize;
144
- const gridEndX = (Math.ceil(x2 / gridSize) + 1) * gridSize;
145
- const gridEndY = (Math.ceil(y2 / gridSize) + 1) * gridSize;
146
- const numCols = Math.ceil((gridEndX - gridStartX) / gridSize);
228
+ const { xmin, ymin, xmax, ymax } = canvasSize;
229
+ const extraValue = extendGrid ? 1 : 0;
230
+ const gridStartX = (Math.floor(xmin / gridSize) - extraValue) * gridSize;
231
+ const gridStartY = (Math.floor(ymin / gridSize) - extraValue) * gridSize;
232
+ const gridEndX = extendGrid
233
+ ? (Math.ceil(xmax / gridSize) + extraValue) * gridSize
234
+ : (xmax - xmin);
235
+ const gridEndY = extendGrid
236
+ ? (Math.ceil(ymax / gridSize) + extraValue) * gridSize
237
+ : (ymax - ymin);
238
+ const numCols = Math.floor((gridEndX - gridStartX) / gridSize)
239
+ + (extendGrid ? 1 : 0);
147
240
  const lines = [];
148
241
  const smallOffset = (0, helpers_js_1.milsToMM)(3);
149
242
  const startY = gridStartY - smallOffset / 2;
150
243
  const endY = gridEndY + smallOffset;
151
- for (let i = 0; i <= numCols; i++) {
244
+ for (let i = 0; i < numCols; i++) {
152
245
  const startX = gridStartX + i * gridSize;
153
246
  lines.push(`M ${startX} ${startY} L ${startX} ${endY}`);
154
247
  }
@@ -162,3 +255,106 @@ function drawGrid(group, canvasSize) {
162
255
  color: '#000'
163
256
  });
164
257
  }
258
+ function drawSheetFrameBorder(frameGroup, frame) {
259
+ const frameParams = frame.frame.parameters;
260
+ if (frameParams.has(Frame_js_1.FrameParamKeys.SheetFrame)) {
261
+ const frameComponent = frameParams.get(Frame_js_1.FrameParamKeys.SheetFrame);
262
+ const { displayProp = null } = frameComponent ?? {};
263
+ if (displayProp) {
264
+ const sheetFrameGroup = frameGroup.group();
265
+ const symbol = new draw_symbols_js_1.SymbolPlaceholder(displayProp);
266
+ symbol.refreshDrawing();
267
+ symbol.draw(sheetFrameGroup);
268
+ const offsetX = (0, helpers_js_1.milsToMM)(frameComponent.getParam('offset_x'));
269
+ const offsetY = (0, helpers_js_1.milsToMM)(frameComponent.getParam('offset_y'));
270
+ sheetFrameGroup.translate(-offsetX, -offsetY);
271
+ }
272
+ }
273
+ }
274
+ function drawSheetFrameBorderDirect(frameGroup, frame, borderWidth, strokeColor, width, height) {
275
+ const commonStroke = {
276
+ width: (0, helpers_js_1.milsToMM)(borderWidth),
277
+ color: strokeColor
278
+ };
279
+ const commonFont = {
280
+ family: globals_js_1.defaultFont,
281
+ size: 50 * globals_js_1.fontDisplayScale,
282
+ 'dominant-baseline': 'middle',
283
+ 'text-anchor': 'middle',
284
+ };
285
+ let rows = 1;
286
+ let columns = 1;
287
+ let showGridReference = true;
288
+ if (helpers_js_1.PaperGridReferences[frame.size]) {
289
+ [rows, columns] = helpers_js_1.PaperGridReferences[frame.size];
290
+ }
291
+ else {
292
+ showGridReference = false;
293
+ }
294
+ if (!showGridReference) {
295
+ return;
296
+ }
297
+ const outerMargin = 2;
298
+ const outerWidth = width + outerMargin * 2;
299
+ const outerHeight = height + outerMargin * 2;
300
+ const outerRect = frameGroup.rect(outerWidth, outerHeight)
301
+ .fill('none')
302
+ .stroke(commonStroke);
303
+ outerRect.translate(frame.x - outerMargin, frame.y - outerMargin);
304
+ const gridWidth = outerWidth / columns;
305
+ const gridHeight = outerHeight / rows;
306
+ const pathPoints = [];
307
+ for (let i = 1; i < rows + 1; i++) {
308
+ const lineStartX = frame.x - outerMargin;
309
+ const lineStartX2 = frame.x - outerMargin + outerWidth - outerMargin;
310
+ const lineY = frame.y - outerMargin + (gridHeight * i);
311
+ if (i < rows) {
312
+ pathPoints.push(...[
313
+ "M", lineStartX, lineY, "L", lineStartX + outerMargin, lineY,
314
+ "M", lineStartX2, lineY, "L", lineStartX2 + outerMargin, lineY
315
+ ]);
316
+ }
317
+ const displayValue = String.fromCharCode(i + 64);
318
+ frameGroup.text(displayValue)
319
+ .font(commonFont)
320
+ .translate(lineStartX + outerMargin / 2, lineY - gridHeight / 2);
321
+ frameGroup.text(displayValue)
322
+ .font(commonFont)
323
+ .translate(lineStartX2 + outerMargin / 2, lineY - gridHeight / 2);
324
+ }
325
+ for (let i = 1; i < columns + 1; i++) {
326
+ const lineStartY = frame.y - outerMargin;
327
+ const lineStartY2 = frame.y - outerMargin + outerHeight - outerMargin;
328
+ const lineX = frame.x - outerMargin + (gridWidth * i);
329
+ if (i < columns) {
330
+ pathPoints.push(...[
331
+ "M", lineX, lineStartY, "L", lineX, lineStartY + outerMargin,
332
+ "M", lineX, lineStartY2, "L", lineX, lineStartY2 + outerMargin
333
+ ]);
334
+ }
335
+ frameGroup.text(i.toString())
336
+ .font(commonFont)
337
+ .translate(lineX - gridWidth / 2, lineStartY + outerMargin / 2 + (0, helpers_js_1.milsToMM)(10));
338
+ frameGroup.text(i.toString())
339
+ .font(commonFont)
340
+ .translate(lineX - gridWidth / 2, lineStartY2 + outerMargin / 2 + (0, helpers_js_1.milsToMM)(10));
341
+ }
342
+ frameGroup.path(pathPoints).stroke(commonStroke);
343
+ const titleWidth = (0, helpers_js_1.milsToMM)(3000);
344
+ const titleHeight = (0, helpers_js_1.milsToMM)(1000);
345
+ const rowHeight = (0, helpers_js_1.milsToMM)(200);
346
+ const points = [
347
+ "M", width - titleWidth, height,
348
+ "L", width - titleWidth, height - titleHeight,
349
+ "L", width, height - titleHeight,
350
+ "M", width - titleWidth, height - rowHeight,
351
+ "L", width, height - rowHeight,
352
+ "M", width - titleWidth, height - rowHeight * 2,
353
+ "L", width, height - rowHeight * 2,
354
+ "M", width - titleWidth, height - rowHeight * 3,
355
+ "L", width, height - rowHeight * 3
356
+ ];
357
+ frameGroup.path(points).stroke(commonStroke).fill('none');
358
+ if (frame.containsTitle) {
359
+ }
360
+ }
@@ -11,6 +11,7 @@ const draw_symbols_js_1 = require("./draw_symbols.js");
11
11
  const BaseVisitor_js_1 = require("./BaseVisitor.js");
12
12
  const utils_js_1 = require("./utils.js");
13
13
  const helpers_js_1 = require("./helpers.js");
14
+ const Frame_js_1 = require("./objects/Frame.js");
14
15
  class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
15
16
  constructor() {
16
17
  super(...arguments);
@@ -156,27 +157,38 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
156
157
  this.setResult(ctx, createdComponent);
157
158
  };
158
159
  this.visitCreate_graphic_expr = (ctx) => {
160
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
161
+ this.visit(graphicsExpressionsCtx);
162
+ const commands = this.getResult(graphicsExpressionsCtx);
163
+ const drawing = new draw_symbols_js_1.SymbolDrawingCommands(commands);
164
+ drawing.source = ctx.getText();
165
+ this.setResult(ctx, drawing);
166
+ };
167
+ this.visitGraphic_expressions_block = (ctx) => {
159
168
  const commands = ctx.graphic_expr().reduce((accum, item) => {
160
169
  this.visit(item);
161
170
  const [commandName, parameters] = this.getResult(item);
162
- const keywordParams = new Map();
163
- const positionParams = parameters.reduce((accum, [argType, name, value]) => {
164
- if (argType === 'position') {
165
- accum.push(value);
166
- }
167
- else {
168
- keywordParams.set(name, value);
169
- }
170
- return accum;
171
- }, []);
172
- accum.push([commandName, positionParams, keywordParams]);
171
+ if (commandName === draw_symbols_js_1.PlaceHolderCommands.for) {
172
+ accum = accum.concat(parameters);
173
+ }
174
+ else {
175
+ const keywordParams = new Map();
176
+ const positionParams = parameters.reduce((accum, [argType, name, value]) => {
177
+ if (argType === 'position') {
178
+ accum.push(value);
179
+ }
180
+ else {
181
+ keywordParams.set(name, value);
182
+ }
183
+ return accum;
184
+ }, []);
185
+ accum.push([commandName, positionParams, keywordParams]);
186
+ }
173
187
  return accum;
174
188
  }, []);
175
- const drawing = new draw_symbols_js_1.SymbolDrawingCommands(commands);
176
- drawing.source = ctx.getText();
177
- this.setResult(ctx, drawing);
189
+ this.setResult(ctx, commands);
178
190
  };
179
- this.visitGraphic_expr = (ctx) => {
191
+ this.visitGraphicCommandExpr = (ctx) => {
180
192
  let commandName = null;
181
193
  const command = ctx._command;
182
194
  if (command) {
@@ -213,11 +225,40 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
213
225
  }
214
226
  this.setResult(ctx, [commandName, parameters]);
215
227
  };
228
+ this.visitGraphicForExpr = (ctx) => {
229
+ const forVariableNames = ctx.ID().map(item => item.getText());
230
+ const ctxDataExpr = ctx.data_expr();
231
+ this.visit(ctxDataExpr);
232
+ const listItems = this.getResult(ctxDataExpr);
233
+ let keepLooping = true;
234
+ let counter = 0;
235
+ let allCommands = [];
236
+ while (keepLooping) {
237
+ if (counter < listItems.length) {
238
+ let useValueArray = listItems[counter];
239
+ if (!Array.isArray(useValueArray)) {
240
+ useValueArray = [useValueArray];
241
+ }
242
+ useValueArray.forEach((value, index) => {
243
+ this.getExecutor().scope.variables.set(forVariableNames[index], value);
244
+ });
245
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
246
+ this.visit(graphicsExpressionsCtx);
247
+ const commands = this.getResult(graphicsExpressionsCtx);
248
+ allCommands = allCommands.concat(commands);
249
+ counter += 1;
250
+ }
251
+ else {
252
+ keepLooping = false;
253
+ }
254
+ }
255
+ this.setResult(ctx, [draw_symbols_js_1.PlaceHolderCommands.for, allCommands]);
256
+ };
216
257
  this.visitCreate_module_expr = (ctx) => {
217
258
  const properties = this.getPropertyExprList(ctx.property_expr());
218
259
  const { left: leftPorts, right: rightPorts } = this.parseCreateModulePorts(properties.get('ports'));
219
260
  const allPorts = [...leftPorts, ...rightPorts].filter(item => {
220
- return !(item instanceof ParamDefinition_js_1.PinBlankValue);
261
+ return !(Array.isArray(item));
221
262
  });
222
263
  const nameToPinId = new Map();
223
264
  const tmpPorts = allPorts.map((portName, index) => {
@@ -225,7 +266,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
225
266
  return new PinDefinition_js_1.PinDefinition(index + 1, PinDefinition_js_1.PinIdType.Int, portName, PinTypes_js_1.PinTypes.Any);
226
267
  });
227
268
  const arrangeLeftItems = leftPorts.map(item => {
228
- if (item instanceof ParamDefinition_js_1.PinBlankValue) {
269
+ if (Array.isArray(item)) {
229
270
  return item;
230
271
  }
231
272
  else {
@@ -233,7 +274,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
233
274
  }
234
275
  });
235
276
  const arrangeRightItems = rightPorts.map(item => {
236
- if (item instanceof ParamDefinition_js_1.PinBlankValue) {
277
+ if (Array.isArray(item)) {
237
278
  return item;
238
279
  }
239
280
  else {
@@ -282,6 +323,9 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
282
323
  this.visit(ctxPropertyValueExpr);
283
324
  const keyName = this.getResult(ctxPropertyKeyExpr);
284
325
  const value = this.getResult(ctxPropertyValueExpr);
326
+ if (value instanceof types_js_1.UndeclaredReference) {
327
+ throw value.throwMessage();
328
+ }
285
329
  const map = new Map();
286
330
  map.set(keyName, value);
287
331
  this.setResult(ctx, map);
@@ -527,10 +571,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
527
571
  this.setResult(ctx, result);
528
572
  };
529
573
  this.visitMultiplyExpr = (ctx) => {
530
- this.visit(ctx.data_expr(0));
531
- this.visit(ctx.data_expr(1));
532
- const value1 = this.getResult(ctx.data_expr(0));
533
- const value2 = this.getResult(ctx.data_expr(1));
574
+ const value1 = this.resolveDataExpr(ctx.data_expr(0));
575
+ const value2 = this.resolveDataExpr(ctx.data_expr(1));
534
576
  let result = null;
535
577
  if (ctx.Multiply()) {
536
578
  result = value1 * value2;
@@ -538,13 +580,14 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
538
580
  else if (ctx.Divide()) {
539
581
  result = value1 / value2;
540
582
  }
583
+ else if (ctx.Modulus()) {
584
+ result = value1 % value2;
585
+ }
541
586
  this.setResult(ctx, result);
542
587
  };
543
588
  this.visitAdditionExpr = (ctx) => {
544
- this.visit(ctx.data_expr(0));
545
- this.visit(ctx.data_expr(1));
546
- const value1 = this.getResult(ctx.data_expr(0));
547
- const value2 = this.getResult(ctx.data_expr(1));
589
+ const value1 = this.resolveDataExpr(ctx.data_expr(0));
590
+ const value2 = this.resolveDataExpr(ctx.data_expr(1));
548
591
  let result = null;
549
592
  if (ctx.Addition()) {
550
593
  result = value1 + value2;
@@ -700,7 +743,11 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
700
743
  this.runExpressions(this.getExecutor(), ctx.expression());
701
744
  };
702
745
  this.visitFrame_expr = (ctx) => {
703
- const frameId = this.getExecutor().enterFrame();
746
+ let frameType = globals_js_1.FrameType.Frame;
747
+ if (ctx.Sheet()) {
748
+ frameType = globals_js_1.FrameType.Sheet;
749
+ }
750
+ const frameId = this.getExecutor().enterFrame(frameType);
704
751
  this.visit(ctx.expressions_block());
705
752
  this.getExecutor().exitFrame(frameId);
706
753
  };
@@ -763,6 +810,70 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
763
810
  }
764
811
  this.setResult(ctx, result);
765
812
  };
813
+ this.visitWhile_expr = (ctx) => {
814
+ const dataExpr = ctx.data_expr();
815
+ let keepLooping = true;
816
+ this.log('enter while loop');
817
+ this.getExecutor().addBreakContext(ctx);
818
+ while (keepLooping) {
819
+ this.visit(dataExpr);
820
+ const result = this.getResult(dataExpr);
821
+ if (result) {
822
+ this.visit(ctx.expressions_block());
823
+ keepLooping = true;
824
+ const currentResult = this.getResult(ctx) ?? {};
825
+ const { breakSignal = false, continueSignal = false } = currentResult;
826
+ if (breakSignal && !continueSignal) {
827
+ keepLooping = false;
828
+ }
829
+ else if (breakSignal && continueSignal) {
830
+ this.setResult(ctx, {
831
+ ...currentResult,
832
+ breakSignal: false,
833
+ continueSignal: false
834
+ });
835
+ }
836
+ }
837
+ else {
838
+ keepLooping = false;
839
+ }
840
+ }
841
+ this.getExecutor().popBreakContext();
842
+ this.log('exit while loop');
843
+ };
844
+ this.visitFor_expr = (ctx) => {
845
+ const forVariableName = ctx.ID().getText();
846
+ const ctxDataExpr = ctx.data_expr();
847
+ this.visit(ctxDataExpr);
848
+ const listItems = this.getResult(ctxDataExpr);
849
+ this.getExecutor().addBreakContext(ctx);
850
+ let keepLooping = true;
851
+ let counter = 0;
852
+ while (keepLooping) {
853
+ if (counter < listItems.length) {
854
+ this.getExecutor().scope.variables.set(forVariableName, listItems[counter]);
855
+ this.visit(ctx.expressions_block());
856
+ keepLooping = true;
857
+ const currentResult = this.getResult(ctx) ?? {};
858
+ const { breakSignal = false, continueSignal = false } = currentResult;
859
+ if (breakSignal && !continueSignal) {
860
+ keepLooping = false;
861
+ }
862
+ else if (breakSignal && continueSignal) {
863
+ this.setResult(ctx, {
864
+ ...currentResult,
865
+ breakSignal: false,
866
+ continueSignal: false
867
+ });
868
+ }
869
+ counter += 1;
870
+ }
871
+ else {
872
+ keepLooping = false;
873
+ }
874
+ }
875
+ this.getExecutor().popBreakContext();
876
+ };
766
877
  this.pinTypes = [
767
878
  PinTypes_js_1.PinTypes.Any,
768
879
  PinTypes_js_1.PinTypes.IO,
@@ -820,6 +931,14 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
820
931
  }
821
932
  }
822
933
  }
934
+ resolveDataExpr(data_expr) {
935
+ this.visit(data_expr);
936
+ const value = this.getResult(data_expr);
937
+ if (value instanceof types_js_1.UndeclaredReference) {
938
+ throw value.throwMessage();
939
+ }
940
+ return value;
941
+ }
823
942
  parseCreateComponentPins(pinData) {
824
943
  const pins = [];
825
944
  if (typeof pinData === 'number') {
@@ -1006,6 +1125,22 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1006
1125
  this.log('===== annotate done =====');
1007
1126
  this.log('');
1008
1127
  }
1128
+ applySheetFrameComponent() {
1129
+ const baseScope = this.getExecutor().scope;
1130
+ const document = baseScope.variables.get(globals_js_1.GlobalDocumentName);
1131
+ let frameComponent = null;
1132
+ if (document && document[Frame_js_1.FrameParamKeys.SheetFrame]) {
1133
+ frameComponent = document[Frame_js_1.FrameParamKeys.SheetFrame];
1134
+ baseScope.frames.forEach(item => {
1135
+ if (item.frameType === globals_js_1.FrameType.Sheet) {
1136
+ item.parameters.set(Frame_js_1.FrameParamKeys.SheetFrame, frameComponent);
1137
+ }
1138
+ });
1139
+ }
1140
+ return {
1141
+ frameComponent
1142
+ };
1143
+ }
1009
1144
  resolveNets(scope, instance) {
1010
1145
  const result = [];
1011
1146
  for (const [pinId, pin] of instance.pins) {