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,37 +1,116 @@
1
1
  import { SVG, registerWindow } from '@svgdotjs/svg.js';
2
- import { RenderFrameType, getBounds } from "./layout.mjs";
2
+ import { ExtractDrawingRects, RenderFrameType, getBounds } from "./layout.mjs";
3
3
  import { applyFontsToSVG, getCreateSVGWindow } from './sizing.mjs';
4
- import { ColorScheme, ComponentTypes, MMToPx, ParamKeys, defaultGridSizeUnits, defaultWireLineWidth, defaultZoomScale, fontDisplayScale, junctionSize } from './globals.mjs';
4
+ import { ColorScheme, ComponentTypes, FrameType, MMToPt, MMToPx, ParamKeys, RenderFlags, defaultFont, defaultGridSizeUnits, defaultPageSpacingMM, defaultWireLineWidth, fontDisplayScale, junctionSize } from './globals.mjs';
5
5
  import { NumericValue } from './objects/ParamDefinition.mjs';
6
6
  import { getBoundsSize } from './utils.mjs';
7
- import { milsToMM } from './helpers.mjs';
8
- export function generateSVG2(graph) {
7
+ import { getPaperSize, milsToMM, PaperGridReferences } from './helpers.mjs';
8
+ import SVGtoPDF from 'svg-to-pdfkit';
9
+ import { FrameParamKeys } from './objects/Frame.mjs';
10
+ import { SymbolPlaceholder } from './draw_symbols.mjs';
11
+ function createSvgCanvas() {
9
12
  const window = getCreateSVGWindow()();
10
13
  const document = window.document;
11
14
  registerWindow(window, document);
12
15
  const canvas = SVG(document.documentElement);
13
16
  applyFontsToSVG(canvas);
14
- generateSVGChild(canvas, graph.components, graph.wires, graph.junctions, graph.mergedWires, graph.frameObjects, graph.textObjects);
15
- const scale = MMToPx * defaultZoomScale;
17
+ return canvas;
18
+ }
19
+ export function renderSheetsToSVG(sheetFrames) {
20
+ const canvas = createSvgCanvas();
21
+ sheetFrames.forEach((sheet, index) => {
22
+ const sheetGroup = canvas.group();
23
+ sheetGroup.id('sheet-' + index);
24
+ const { components, wires, junctions, mergedWires, frames, textObjects } = sheet;
25
+ const allFrames = [sheet.frame, ...frames];
26
+ let gridBounds = null;
27
+ let extendGrid = true;
28
+ let xOffset = 0;
29
+ let yOffset = 0;
30
+ let sheetYOffset = 0;
31
+ if (sheet.frame.frame) {
32
+ const frameComponent = sheet.frame.frame.parameters
33
+ .get(FrameParamKeys.SheetFrame);
34
+ if (frameComponent) {
35
+ if (frameComponent.displayProp === null) {
36
+ throw 'Invalid graphic object for sheet frame';
37
+ }
38
+ const frameRects = ExtractDrawingRects(frameComponent.displayProp) ?? [];
39
+ let originalWidthMM = 0;
40
+ let originalHeightMM = 0;
41
+ let widthMM = 0;
42
+ let heightMM = 0;
43
+ if (frameRects[0]) {
44
+ originalWidthMM = milsToMM(frameRects[0].width);
45
+ originalHeightMM = milsToMM(frameRects[0].height);
46
+ }
47
+ if (frameRects[1]) {
48
+ widthMM = milsToMM(frameRects[1].width);
49
+ heightMM = milsToMM(frameRects[1].height);
50
+ }
51
+ xOffset = (originalWidthMM - widthMM) / 2;
52
+ yOffset = (originalHeightMM - heightMM) / 2;
53
+ sheetYOffset = index * (originalHeightMM + defaultPageSpacingMM);
54
+ gridBounds = {
55
+ xmin: 0,
56
+ ymin: 0,
57
+ xmax: widthMM,
58
+ ymax: heightMM
59
+ };
60
+ extendGrid = false;
61
+ }
62
+ }
63
+ const sheetElements = sheetGroup.group();
64
+ generateSVGChild(sheetElements, components, wires, junctions, mergedWires, allFrames, textObjects, gridBounds, extendGrid);
65
+ sheetElements.translate(xOffset, yOffset);
66
+ sheetGroup.translate(0, sheetYOffset);
67
+ });
68
+ return canvas;
69
+ }
70
+ export function generateSvgOutput(canvas, zoomScale = 1) {
71
+ const scale = MMToPx * zoomScale;
16
72
  const { x, y, width, height } = canvas.bbox();
17
73
  const scaledWidth = width * scale;
18
74
  const scaledHeight = height * scale;
19
75
  canvas.size(scaledWidth, scaledHeight);
20
76
  canvas.viewbox(x, y, width, height);
21
- return {
22
- svg: canvas.svg(),
23
- width, height,
24
- };
77
+ return canvas.svg();
25
78
  }
26
- function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects) {
27
- const displayWireId = false;
28
- const bounds = getBounds(components, wires, junctions, frameObjects);
29
- drawGrid(canvas.group().translate(0, 0), {
30
- x: bounds.xmin,
31
- y: bounds.ymin,
32
- x2: bounds.xmax,
33
- y2: bounds.ymax
79
+ export function generatePdfOutput(doc, canvas, sheetSize, sheetSizeDefined, zoomScale = 1) {
80
+ const children = canvas.children();
81
+ const numChildren = children.length;
82
+ const scale = MMToPx * zoomScale;
83
+ const { originalWidthMM, originalHeightMM } = getPaperSize(sheetSize);
84
+ children.forEach((child, index) => {
85
+ const sheetCanvas = createSvgCanvas();
86
+ sheetCanvas.add(child);
87
+ const { x, y, width, height } = sheetCanvas.bbox();
88
+ const sheetBorder = child.find('#sheet-border');
89
+ if (sheetBorder.length > 0) {
90
+ sheetBorder[0].remove();
91
+ }
92
+ const scaledWidth = width * scale;
93
+ const scaledHeight = height * scale;
94
+ sheetCanvas.size(scaledWidth, scaledHeight);
95
+ sheetCanvas.viewbox(x, y, width, height);
96
+ let xOffset = 0;
97
+ let yOffset = 0;
98
+ if (!sheetSizeDefined) {
99
+ xOffset = (originalWidthMM - width) / 2;
100
+ yOffset = (originalHeightMM - height) / 2;
101
+ }
102
+ SVGtoPDF(doc, sheetCanvas.svg(), xOffset * MMToPt, yOffset * MMToPt);
103
+ if (index + 1 < numChildren) {
104
+ doc.addPage();
105
+ }
34
106
  });
107
+ }
108
+ function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects, gridBounds, extendGrid) {
109
+ const displayWireId = false;
110
+ if (gridBounds === null) {
111
+ gridBounds = getBounds(components, wires, junctions, frameObjects);
112
+ }
113
+ drawGrid(canvas.group().translate(0, 0), gridBounds, extendGrid);
35
114
  components.forEach(item => {
36
115
  const { x, y, width, height } = item;
37
116
  const symbolGroup = canvas.group();
@@ -98,25 +177,29 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
98
177
  });
99
178
  });
100
179
  const frameGroup = canvas.group();
101
- const showElementFrames = false;
102
180
  frameObjects.forEach(item => {
103
181
  const { bounds, borderWidth } = item;
104
- if (borderWidth > 0) {
105
- const { width, height } = getBoundsSize(bounds);
106
- let strokeColor = '#111';
107
- if (item.type === RenderFrameType.Container) {
108
- strokeColor = '#111';
109
- }
110
- else if (item.type === RenderFrameType.Elements) {
111
- strokeColor = '#aaa';
112
- if (!showElementFrames) {
113
- return;
182
+ const { width, height } = getBoundsSize(bounds);
183
+ let strokeColor = '#111';
184
+ if (item.frame.frameType === FrameType.Sheet) {
185
+ drawSheetFrameBorder(frameGroup, item);
186
+ }
187
+ else {
188
+ if (borderWidth > 0) {
189
+ if (item.type === RenderFrameType.Container) {
190
+ strokeColor = '#111';
191
+ }
192
+ else if (item.type === RenderFrameType.Elements) {
193
+ strokeColor = '#aaa';
194
+ if (!RenderFlags.ShowElementFrames) {
195
+ return;
196
+ }
114
197
  }
198
+ const tmpRect = frameGroup.rect(width, height)
199
+ .fill('none')
200
+ .stroke({ width: milsToMM(borderWidth), color: strokeColor });
201
+ tmpRect.translate(item.x, item.y);
115
202
  }
116
- const tmpRect = frameGroup.rect(width, height)
117
- .fill('none')
118
- .stroke({ width: milsToMM(borderWidth), color: strokeColor });
119
- tmpRect.translate(item.x, item.y);
120
203
  }
121
204
  });
122
205
  textObjects.forEach(item => {
@@ -125,26 +208,31 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
125
208
  innerGroup.translate(x, y);
126
209
  symbol.draw(innerGroup);
127
210
  });
128
- const drawOrigin = false;
129
211
  const originSize = milsToMM(10);
130
- drawOrigin && canvas.group().translate(0, 0)
212
+ RenderFlags.ShowOrigin && canvas.group().translate(0, 0)
131
213
  .circle(originSize)
132
214
  .translate(-originSize / 2, -originSize / 2)
133
215
  .stroke('none').fill('red');
134
216
  }
135
- function drawGrid(group, canvasSize) {
217
+ function drawGrid(group, canvasSize, extendGrid) {
136
218
  const gridSize = defaultGridSizeUnits;
137
- const { x, y, x2, y2 } = canvasSize;
138
- const gridStartX = (Math.floor(x / gridSize) - 1) * gridSize;
139
- const gridStartY = (Math.floor(y / gridSize) - 1) * gridSize;
140
- const gridEndX = (Math.ceil(x2 / gridSize) + 1) * gridSize;
141
- const gridEndY = (Math.ceil(y2 / gridSize) + 1) * gridSize;
142
- const numCols = Math.ceil((gridEndX - gridStartX) / gridSize);
219
+ const { xmin, ymin, xmax, ymax } = canvasSize;
220
+ const extraValue = extendGrid ? 1 : 0;
221
+ const gridStartX = (Math.floor(xmin / gridSize) - extraValue) * gridSize;
222
+ const gridStartY = (Math.floor(ymin / gridSize) - extraValue) * gridSize;
223
+ const gridEndX = extendGrid
224
+ ? (Math.ceil(xmax / gridSize) + extraValue) * gridSize
225
+ : (xmax - xmin);
226
+ const gridEndY = extendGrid
227
+ ? (Math.ceil(ymax / gridSize) + extraValue) * gridSize
228
+ : (ymax - ymin);
229
+ const numCols = Math.floor((gridEndX - gridStartX) / gridSize)
230
+ + (extendGrid ? 1 : 0);
143
231
  const lines = [];
144
232
  const smallOffset = milsToMM(3);
145
233
  const startY = gridStartY - smallOffset / 2;
146
234
  const endY = gridEndY + smallOffset;
147
- for (let i = 0; i <= numCols; i++) {
235
+ for (let i = 0; i < numCols; i++) {
148
236
  const startX = gridStartX + i * gridSize;
149
237
  lines.push(`M ${startX} ${startY} L ${startX} ${endY}`);
150
238
  }
@@ -158,3 +246,106 @@ function drawGrid(group, canvasSize) {
158
246
  color: '#000'
159
247
  });
160
248
  }
249
+ function drawSheetFrameBorder(frameGroup, frame) {
250
+ const frameParams = frame.frame.parameters;
251
+ if (frameParams.has(FrameParamKeys.SheetFrame)) {
252
+ const frameComponent = frameParams.get(FrameParamKeys.SheetFrame);
253
+ const { displayProp = null } = frameComponent ?? {};
254
+ if (displayProp) {
255
+ const sheetFrameGroup = frameGroup.group();
256
+ const symbol = new SymbolPlaceholder(displayProp);
257
+ symbol.refreshDrawing();
258
+ symbol.draw(sheetFrameGroup);
259
+ const offsetX = milsToMM(frameComponent.getParam('offset_x'));
260
+ const offsetY = milsToMM(frameComponent.getParam('offset_y'));
261
+ sheetFrameGroup.translate(-offsetX, -offsetY);
262
+ }
263
+ }
264
+ }
265
+ function drawSheetFrameBorderDirect(frameGroup, frame, borderWidth, strokeColor, width, height) {
266
+ const commonStroke = {
267
+ width: milsToMM(borderWidth),
268
+ color: strokeColor
269
+ };
270
+ const commonFont = {
271
+ family: defaultFont,
272
+ size: 50 * fontDisplayScale,
273
+ 'dominant-baseline': 'middle',
274
+ 'text-anchor': 'middle',
275
+ };
276
+ let rows = 1;
277
+ let columns = 1;
278
+ let showGridReference = true;
279
+ if (PaperGridReferences[frame.size]) {
280
+ [rows, columns] = PaperGridReferences[frame.size];
281
+ }
282
+ else {
283
+ showGridReference = false;
284
+ }
285
+ if (!showGridReference) {
286
+ return;
287
+ }
288
+ const outerMargin = 2;
289
+ const outerWidth = width + outerMargin * 2;
290
+ const outerHeight = height + outerMargin * 2;
291
+ const outerRect = frameGroup.rect(outerWidth, outerHeight)
292
+ .fill('none')
293
+ .stroke(commonStroke);
294
+ outerRect.translate(frame.x - outerMargin, frame.y - outerMargin);
295
+ const gridWidth = outerWidth / columns;
296
+ const gridHeight = outerHeight / rows;
297
+ const pathPoints = [];
298
+ for (let i = 1; i < rows + 1; i++) {
299
+ const lineStartX = frame.x - outerMargin;
300
+ const lineStartX2 = frame.x - outerMargin + outerWidth - outerMargin;
301
+ const lineY = frame.y - outerMargin + (gridHeight * i);
302
+ if (i < rows) {
303
+ pathPoints.push(...[
304
+ "M", lineStartX, lineY, "L", lineStartX + outerMargin, lineY,
305
+ "M", lineStartX2, lineY, "L", lineStartX2 + outerMargin, lineY
306
+ ]);
307
+ }
308
+ const displayValue = String.fromCharCode(i + 64);
309
+ frameGroup.text(displayValue)
310
+ .font(commonFont)
311
+ .translate(lineStartX + outerMargin / 2, lineY - gridHeight / 2);
312
+ frameGroup.text(displayValue)
313
+ .font(commonFont)
314
+ .translate(lineStartX2 + outerMargin / 2, lineY - gridHeight / 2);
315
+ }
316
+ for (let i = 1; i < columns + 1; i++) {
317
+ const lineStartY = frame.y - outerMargin;
318
+ const lineStartY2 = frame.y - outerMargin + outerHeight - outerMargin;
319
+ const lineX = frame.x - outerMargin + (gridWidth * i);
320
+ if (i < columns) {
321
+ pathPoints.push(...[
322
+ "M", lineX, lineStartY, "L", lineX, lineStartY + outerMargin,
323
+ "M", lineX, lineStartY2, "L", lineX, lineStartY2 + outerMargin
324
+ ]);
325
+ }
326
+ frameGroup.text(i.toString())
327
+ .font(commonFont)
328
+ .translate(lineX - gridWidth / 2, lineStartY + outerMargin / 2 + milsToMM(10));
329
+ frameGroup.text(i.toString())
330
+ .font(commonFont)
331
+ .translate(lineX - gridWidth / 2, lineStartY2 + outerMargin / 2 + milsToMM(10));
332
+ }
333
+ frameGroup.path(pathPoints).stroke(commonStroke);
334
+ const titleWidth = milsToMM(3000);
335
+ const titleHeight = milsToMM(1000);
336
+ const rowHeight = milsToMM(200);
337
+ const points = [
338
+ "M", width - titleWidth, height,
339
+ "L", width - titleWidth, height - titleHeight,
340
+ "L", width, height - titleHeight,
341
+ "M", width - titleWidth, height - rowHeight,
342
+ "L", width, height - rowHeight,
343
+ "M", width - titleWidth, height - rowHeight * 2,
344
+ "L", width, height - rowHeight * 2,
345
+ "M", width - titleWidth, height - rowHeight * 3,
346
+ "L", width, height - rowHeight * 3
347
+ ];
348
+ frameGroup.path(points).stroke(commonStroke).fill('none');
349
+ if (frame.containsTitle) {
350
+ }
351
+ }
@@ -1,13 +1,14 @@
1
1
  import { ClassComponent } from './objects/ClassComponent.mjs';
2
- import { NumericValue, ParamDefinition, PinBlankValue, } from './objects/ParamDefinition.mjs';
2
+ import { NumericValue, ParamDefinition } from './objects/ParamDefinition.mjs';
3
3
  import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
4
4
  import { PinTypes } from './objects/PinTypes.mjs';
5
5
  import { DeclaredReference, UndeclaredReference } from './objects/types.mjs';
6
- import { BlockTypes, ComponentTypes, NoNetText, ReferenceTypes, WireAutoDirection } from './globals.mjs';
6
+ import { BlockTypes, ComponentTypes, FrameType, GlobalDocumentName, NoNetText, ReferenceTypes, WireAutoDirection } from './globals.mjs';
7
7
  import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.mjs';
8
8
  import { BaseVisitor } from './BaseVisitor.mjs';
9
9
  import { getPortType } from './utils.mjs';
10
10
  import { UnitDimension } from './helpers.mjs';
11
+ import { FrameParamKeys } from './objects/Frame.mjs';
11
12
  export class ParserVisitor extends BaseVisitor {
12
13
  visitKeyword_assignment_expr = (ctx) => {
13
14
  const id = ctx.ID().getText();
@@ -151,27 +152,38 @@ export class ParserVisitor extends BaseVisitor {
151
152
  this.setResult(ctx, createdComponent);
152
153
  };
153
154
  visitCreate_graphic_expr = (ctx) => {
155
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
156
+ this.visit(graphicsExpressionsCtx);
157
+ const commands = this.getResult(graphicsExpressionsCtx);
158
+ const drawing = new SymbolDrawingCommands(commands);
159
+ drawing.source = ctx.getText();
160
+ this.setResult(ctx, drawing);
161
+ };
162
+ visitGraphic_expressions_block = (ctx) => {
154
163
  const commands = ctx.graphic_expr().reduce((accum, item) => {
155
164
  this.visit(item);
156
165
  const [commandName, parameters] = this.getResult(item);
157
- const keywordParams = new Map();
158
- const positionParams = parameters.reduce((accum, [argType, name, value]) => {
159
- if (argType === 'position') {
160
- accum.push(value);
161
- }
162
- else {
163
- keywordParams.set(name, value);
164
- }
165
- return accum;
166
- }, []);
167
- accum.push([commandName, positionParams, keywordParams]);
166
+ if (commandName === PlaceHolderCommands.for) {
167
+ accum = accum.concat(parameters);
168
+ }
169
+ else {
170
+ const keywordParams = new Map();
171
+ const positionParams = parameters.reduce((accum, [argType, name, value]) => {
172
+ if (argType === 'position') {
173
+ accum.push(value);
174
+ }
175
+ else {
176
+ keywordParams.set(name, value);
177
+ }
178
+ return accum;
179
+ }, []);
180
+ accum.push([commandName, positionParams, keywordParams]);
181
+ }
168
182
  return accum;
169
183
  }, []);
170
- const drawing = new SymbolDrawingCommands(commands);
171
- drawing.source = ctx.getText();
172
- this.setResult(ctx, drawing);
184
+ this.setResult(ctx, commands);
173
185
  };
174
- visitGraphic_expr = (ctx) => {
186
+ visitGraphicCommandExpr = (ctx) => {
175
187
  let commandName = null;
176
188
  const command = ctx._command;
177
189
  if (command) {
@@ -208,11 +220,40 @@ export class ParserVisitor extends BaseVisitor {
208
220
  }
209
221
  this.setResult(ctx, [commandName, parameters]);
210
222
  };
223
+ visitGraphicForExpr = (ctx) => {
224
+ const forVariableNames = ctx.ID().map(item => item.getText());
225
+ const ctxDataExpr = ctx.data_expr();
226
+ this.visit(ctxDataExpr);
227
+ const listItems = this.getResult(ctxDataExpr);
228
+ let keepLooping = true;
229
+ let counter = 0;
230
+ let allCommands = [];
231
+ while (keepLooping) {
232
+ if (counter < listItems.length) {
233
+ let useValueArray = listItems[counter];
234
+ if (!Array.isArray(useValueArray)) {
235
+ useValueArray = [useValueArray];
236
+ }
237
+ useValueArray.forEach((value, index) => {
238
+ this.getExecutor().scope.variables.set(forVariableNames[index], value);
239
+ });
240
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
241
+ this.visit(graphicsExpressionsCtx);
242
+ const commands = this.getResult(graphicsExpressionsCtx);
243
+ allCommands = allCommands.concat(commands);
244
+ counter += 1;
245
+ }
246
+ else {
247
+ keepLooping = false;
248
+ }
249
+ }
250
+ this.setResult(ctx, [PlaceHolderCommands.for, allCommands]);
251
+ };
211
252
  visitCreate_module_expr = (ctx) => {
212
253
  const properties = this.getPropertyExprList(ctx.property_expr());
213
254
  const { left: leftPorts, right: rightPorts } = this.parseCreateModulePorts(properties.get('ports'));
214
255
  const allPorts = [...leftPorts, ...rightPorts].filter(item => {
215
- return !(item instanceof PinBlankValue);
256
+ return !(Array.isArray(item));
216
257
  });
217
258
  const nameToPinId = new Map();
218
259
  const tmpPorts = allPorts.map((portName, index) => {
@@ -220,7 +261,7 @@ export class ParserVisitor extends BaseVisitor {
220
261
  return new PinDefinition(index + 1, PinIdType.Int, portName, PinTypes.Any);
221
262
  });
222
263
  const arrangeLeftItems = leftPorts.map(item => {
223
- if (item instanceof PinBlankValue) {
264
+ if (Array.isArray(item)) {
224
265
  return item;
225
266
  }
226
267
  else {
@@ -228,7 +269,7 @@ export class ParserVisitor extends BaseVisitor {
228
269
  }
229
270
  });
230
271
  const arrangeRightItems = rightPorts.map(item => {
231
- if (item instanceof PinBlankValue) {
272
+ if (Array.isArray(item)) {
232
273
  return item;
233
274
  }
234
275
  else {
@@ -277,6 +318,9 @@ export class ParserVisitor extends BaseVisitor {
277
318
  this.visit(ctxPropertyValueExpr);
278
319
  const keyName = this.getResult(ctxPropertyKeyExpr);
279
320
  const value = this.getResult(ctxPropertyValueExpr);
321
+ if (value instanceof UndeclaredReference) {
322
+ throw value.throwMessage();
323
+ }
280
324
  const map = new Map();
281
325
  map.set(keyName, value);
282
326
  this.setResult(ctx, map);
@@ -571,10 +615,8 @@ export class ParserVisitor extends BaseVisitor {
571
615
  this.setResult(ctx, result);
572
616
  };
573
617
  visitMultiplyExpr = (ctx) => {
574
- this.visit(ctx.data_expr(0));
575
- this.visit(ctx.data_expr(1));
576
- const value1 = this.getResult(ctx.data_expr(0));
577
- const value2 = this.getResult(ctx.data_expr(1));
618
+ const value1 = this.resolveDataExpr(ctx.data_expr(0));
619
+ const value2 = this.resolveDataExpr(ctx.data_expr(1));
578
620
  let result = null;
579
621
  if (ctx.Multiply()) {
580
622
  result = value1 * value2;
@@ -582,13 +624,14 @@ export class ParserVisitor extends BaseVisitor {
582
624
  else if (ctx.Divide()) {
583
625
  result = value1 / value2;
584
626
  }
627
+ else if (ctx.Modulus()) {
628
+ result = value1 % value2;
629
+ }
585
630
  this.setResult(ctx, result);
586
631
  };
587
632
  visitAdditionExpr = (ctx) => {
588
- this.visit(ctx.data_expr(0));
589
- this.visit(ctx.data_expr(1));
590
- const value1 = this.getResult(ctx.data_expr(0));
591
- const value2 = this.getResult(ctx.data_expr(1));
633
+ const value1 = this.resolveDataExpr(ctx.data_expr(0));
634
+ const value2 = this.resolveDataExpr(ctx.data_expr(1));
592
635
  let result = null;
593
636
  if (ctx.Addition()) {
594
637
  result = value1 + value2;
@@ -744,7 +787,11 @@ export class ParserVisitor extends BaseVisitor {
744
787
  this.runExpressions(this.getExecutor(), ctx.expression());
745
788
  };
746
789
  visitFrame_expr = (ctx) => {
747
- const frameId = this.getExecutor().enterFrame();
790
+ let frameType = FrameType.Frame;
791
+ if (ctx.Sheet()) {
792
+ frameType = FrameType.Sheet;
793
+ }
794
+ const frameId = this.getExecutor().enterFrame(frameType);
748
795
  this.visit(ctx.expressions_block());
749
796
  this.getExecutor().exitFrame(frameId);
750
797
  };
@@ -807,6 +854,78 @@ export class ParserVisitor extends BaseVisitor {
807
854
  }
808
855
  this.setResult(ctx, result);
809
856
  };
857
+ visitWhile_expr = (ctx) => {
858
+ const dataExpr = ctx.data_expr();
859
+ let keepLooping = true;
860
+ this.log('enter while loop');
861
+ this.getExecutor().addBreakContext(ctx);
862
+ while (keepLooping) {
863
+ this.visit(dataExpr);
864
+ const result = this.getResult(dataExpr);
865
+ if (result) {
866
+ this.visit(ctx.expressions_block());
867
+ keepLooping = true;
868
+ const currentResult = this.getResult(ctx) ?? {};
869
+ const { breakSignal = false, continueSignal = false } = currentResult;
870
+ if (breakSignal && !continueSignal) {
871
+ keepLooping = false;
872
+ }
873
+ else if (breakSignal && continueSignal) {
874
+ this.setResult(ctx, {
875
+ ...currentResult,
876
+ breakSignal: false,
877
+ continueSignal: false
878
+ });
879
+ }
880
+ }
881
+ else {
882
+ keepLooping = false;
883
+ }
884
+ }
885
+ this.getExecutor().popBreakContext();
886
+ this.log('exit while loop');
887
+ };
888
+ visitFor_expr = (ctx) => {
889
+ const forVariableName = ctx.ID().getText();
890
+ const ctxDataExpr = ctx.data_expr();
891
+ this.visit(ctxDataExpr);
892
+ const listItems = this.getResult(ctxDataExpr);
893
+ this.getExecutor().addBreakContext(ctx);
894
+ let keepLooping = true;
895
+ let counter = 0;
896
+ while (keepLooping) {
897
+ if (counter < listItems.length) {
898
+ this.getExecutor().scope.variables.set(forVariableName, listItems[counter]);
899
+ this.visit(ctx.expressions_block());
900
+ keepLooping = true;
901
+ const currentResult = this.getResult(ctx) ?? {};
902
+ const { breakSignal = false, continueSignal = false } = currentResult;
903
+ if (breakSignal && !continueSignal) {
904
+ keepLooping = false;
905
+ }
906
+ else if (breakSignal && continueSignal) {
907
+ this.setResult(ctx, {
908
+ ...currentResult,
909
+ breakSignal: false,
910
+ continueSignal: false
911
+ });
912
+ }
913
+ counter += 1;
914
+ }
915
+ else {
916
+ keepLooping = false;
917
+ }
918
+ }
919
+ this.getExecutor().popBreakContext();
920
+ };
921
+ resolveDataExpr(data_expr) {
922
+ this.visit(data_expr);
923
+ const value = this.getResult(data_expr);
924
+ if (value instanceof UndeclaredReference) {
925
+ throw value.throwMessage();
926
+ }
927
+ return value;
928
+ }
810
929
  pinTypes = [
811
930
  PinTypes.Any,
812
931
  PinTypes.IO,
@@ -1000,6 +1119,22 @@ export class ParserVisitor extends BaseVisitor {
1000
1119
  this.log('===== annotate done =====');
1001
1120
  this.log('');
1002
1121
  }
1122
+ applySheetFrameComponent() {
1123
+ const baseScope = this.getExecutor().scope;
1124
+ const document = baseScope.variables.get(GlobalDocumentName);
1125
+ let frameComponent = null;
1126
+ if (document && document[FrameParamKeys.SheetFrame]) {
1127
+ frameComponent = document[FrameParamKeys.SheetFrame];
1128
+ baseScope.frames.forEach(item => {
1129
+ if (item.frameType === FrameType.Sheet) {
1130
+ item.parameters.set(FrameParamKeys.SheetFrame, frameComponent);
1131
+ }
1132
+ });
1133
+ }
1134
+ return {
1135
+ frameComponent
1136
+ };
1137
+ }
1003
1138
  resolveNets(scope, instance) {
1004
1139
  const result = [];
1005
1140
  for (const [pinId, pin] of instance.pins) {
@@ -1,4 +1,4 @@
1
- import { Assignment_exprContext, Atom_exprContext, Blank_exprContext, Break_keywordContext, ExpressionContext, Function_args_exprContext, Function_call_exprContext, Function_exprContext, Function_return_exprContext, FunctionCallExprContext, Import_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, Value_exprContext, ValueAtomExprContext } from "./antlr/CircuitScriptParser";
1
+ import { Array_exprContext, ArrayExprContext, Assignment_exprContext, Atom_exprContext, Break_keywordContext, Continue_keywordContext, ExpressionContext, Function_args_exprContext, Function_call_exprContext, Function_exprContext, Function_return_exprContext, FunctionCallExprContext, Import_exprContext, Operator_assignment_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, Value_exprContext, ValueAtomExprContext } from "./antlr/CircuitScriptParser";
2
2
  import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor";
3
3
  import { ExecutionContext } from "./execute";
4
4
  import { Logger } from "./logger";
@@ -28,6 +28,7 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | Refe
28
28
  };
29
29
  constructor(silent: boolean | undefined, onErrorHandler: OnErrorCallback | null | undefined, currentDirectory: string | null, defaultLibsPath: string);
30
30
  getExecutor(): ExecutionContext;
31
+ protected toString(obj: any): string;
31
32
  protected setupPrintFunction(context: ExecutionContext): void;
32
33
  createNetResolver(executionStack: ExecutionContext[]): (netName: string, netNamespace: string) => {
33
34
  found: boolean;
@@ -37,17 +38,21 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | Refe
37
38
  log2(message: string): void;
38
39
  visitScript: (ctx: ScriptContext) => void;
39
40
  visitAssignment_expr: (ctx: Assignment_exprContext) => void;
41
+ visitOperator_assignment_expr: (ctx: Operator_assignment_exprContext) => void;
42
+ private getReference;
40
43
  visitAtom_expr: (ctx: Atom_exprContext) => void;
41
44
  visitFunctionCallExpr: (ctx: FunctionCallExprContext) => void;
42
45
  visitFunction_call_expr: (ctx: Function_call_exprContext) => void;
43
46
  visitValue_expr: (ctx: Value_exprContext) => void;
44
- visitBlank_expr: (ctx: Blank_exprContext) => void;
45
47
  visitValueAtomExpr: (ctx: ValueAtomExprContext) => void;
46
48
  visitFunction_args_expr: (ctx: Function_args_exprContext) => void;
47
49
  visitParameters: (ctx: ParametersContext) => void;
48
50
  visitImport_expr: (ctx: Import_exprContext) => void;
49
51
  visitFunction_return_expr: (ctx: Function_return_exprContext) => void;
50
52
  visitBreak_keyword: (ctx: Break_keywordContext) => void;
53
+ visitContinue_keyword: (ctx: Continue_keywordContext) => void;
54
+ visitArray_expr: (ctx: Array_exprContext) => void;
55
+ visitArrayExpr: (ctx: ArrayExprContext) => void;
51
56
  protected setResult(ctx: ParserRuleContext, value: any): void;
52
57
  protected getResult(ctx: ParserRuleContext): any;
53
58
  protected handleImportFile(name: string, throwErrors?: boolean): {
@@ -60,6 +65,7 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | Refe
60
65
  protected runExpressions(executor: ExecutionContext, expressions: ExpressionContext[] | Function_exprContext[]): ComplexType;
61
66
  protected getNetNamespace(executorNetNamespace: string, passedNetNamespace: string | null): string;
62
67
  protected setInstanceParam(object: ClassComponent, trailers: string[], value: any): void;
68
+ protected getInstanceParam<T>(object: ClassComponent, trailers: string[]): T;
63
69
  protected enterNewChildContext(executionStack: ExecutionContext[], parentContext: ExecutionContext, executionContextName: string, options: CFunctionOptions, funcDefinedParameters: FunctionDefinedParameter[], passedInParameters: CallableParameter[]): ExecutionContext;
64
70
  protected prepareStringValue(value: string): string;
65
71
  }