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.
- package/dist/cjs/BaseVisitor.js +187 -39
- package/dist/cjs/antlr/CircuitScriptLexer.js +226 -185
- package/dist/cjs/antlr/CircuitScriptParser.js +1439 -902
- package/dist/cjs/draw_symbols.js +1 -0
- package/dist/cjs/execute.js +14 -12
- package/dist/cjs/globals.js +14 -2
- package/dist/cjs/helpers.js +62 -19
- package/dist/cjs/layout.js +88 -36
- package/dist/cjs/objects/ClassComponent.js +3 -0
- package/dist/cjs/objects/ExecutionScope.js +1 -0
- package/dist/cjs/objects/Frame.js +4 -1
- package/dist/cjs/objects/ParamDefinition.js +1 -7
- package/dist/cjs/objects/types.js +6 -0
- package/dist/cjs/regenerate-tests.js +2 -1
- package/dist/cjs/render.js +238 -42
- package/dist/cjs/visitor.js +162 -27
- package/dist/esm/BaseVisitor.mjs +189 -41
- package/dist/esm/antlr/CircuitScriptLexer.mjs +226 -185
- package/dist/esm/antlr/CircuitScriptParser.mjs +1428 -899
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +9 -2
- package/dist/esm/draw_symbols.mjs +1 -0
- package/dist/esm/execute.mjs +14 -12
- package/dist/esm/globals.mjs +13 -1
- package/dist/esm/helpers.mjs +61 -20
- package/dist/esm/layout.mjs +88 -37
- package/dist/esm/objects/ClassComponent.mjs +3 -0
- package/dist/esm/objects/ExecutionScope.mjs +1 -0
- package/dist/esm/objects/Frame.mjs +5 -1
- package/dist/esm/objects/ParamDefinition.mjs +0 -6
- package/dist/esm/objects/types.mjs +6 -0
- package/dist/esm/regenerate-tests.mjs +2 -1
- package/dist/esm/render.mjs +234 -43
- package/dist/esm/visitor.mjs +164 -29
- package/dist/types/BaseVisitor.d.ts +8 -2
- package/dist/types/antlr/CircuitScriptLexer.d.ts +41 -30
- package/dist/types/antlr/CircuitScriptParser.d.ts +169 -81
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +18 -4
- package/dist/types/draw_symbols.d.ts +2 -1
- package/dist/types/execute.d.ts +6 -3
- package/dist/types/globals.d.ts +11 -0
- package/dist/types/helpers.d.ts +12 -0
- package/dist/types/layout.d.ts +17 -9
- package/dist/types/objects/ClassComponent.d.ts +2 -1
- package/dist/types/objects/ExecutionScope.d.ts +2 -0
- package/dist/types/objects/Frame.d.ts +6 -2
- package/dist/types/objects/ParamDefinition.d.ts +0 -4
- package/dist/types/objects/types.d.ts +4 -2
- package/dist/types/render.d.ts +6 -14
- package/dist/types/visitor.d.ts +10 -2
- package/libs/lib.cst +283 -0
- package/package.json +1 -1
package/dist/esm/render.mjs
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
15
|
-
|
|
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
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
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 {
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
|
|
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
|
|
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
|
+
}
|
package/dist/esm/visitor.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ClassComponent } from './objects/ClassComponent.mjs';
|
|
2
|
-
import { NumericValue, ParamDefinition
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
171
|
-
drawing.source = ctx.getText();
|
|
172
|
-
this.setResult(ctx, drawing);
|
|
184
|
+
this.setResult(ctx, commands);
|
|
173
185
|
};
|
|
174
|
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
575
|
-
this.
|
|
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.
|
|
589
|
-
this.
|
|
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
|
-
|
|
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,
|
|
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
|
}
|