circuitscript 0.0.25 → 0.0.27
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/LICENSE +1 -1
- package/dist/cjs/BaseVisitor.js +16 -12
- package/dist/cjs/SemanticTokenVisitor.js +3 -3
- package/dist/cjs/antlr/CircuitScriptLexer.js +189 -166
- package/dist/cjs/antlr/CircuitScriptParser.js +1295 -719
- package/dist/cjs/draw_symbols.js +42 -14
- package/dist/cjs/execute.js +91 -30
- package/dist/cjs/export.js +91 -5
- package/dist/cjs/geometry.js +45 -26
- package/dist/cjs/globals.js +1 -2
- package/dist/cjs/helpers.js +6 -2
- package/dist/cjs/layout.js +37 -17
- package/dist/cjs/main.js +21 -9
- package/dist/cjs/objects/ClassComponent.js +8 -0
- package/dist/cjs/objects/types.js +8 -1
- package/dist/cjs/render.js +1 -1
- package/dist/cjs/visitor.js +131 -23
- package/dist/esm/BaseVisitor.mjs +17 -13
- package/dist/esm/SemanticTokenVisitor.mjs +3 -3
- package/dist/esm/antlr/CircuitScriptLexer.mjs +189 -166
- package/dist/esm/antlr/CircuitScriptParser.mjs +1287 -716
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +6 -1
- package/dist/esm/draw_symbols.mjs +44 -16
- package/dist/esm/execute.mjs +90 -26
- package/dist/esm/export.mjs +89 -6
- package/dist/esm/geometry.mjs +44 -25
- package/dist/esm/globals.mjs +1 -2
- package/dist/esm/helpers.mjs +7 -3
- package/dist/esm/layout.mjs +35 -16
- package/dist/esm/main.mjs +21 -9
- package/dist/esm/objects/ClassComponent.mjs +8 -0
- package/dist/esm/objects/types.mjs +7 -0
- package/dist/esm/render.mjs +2 -2
- package/dist/esm/visitor.mjs +133 -25
- package/dist/types/BaseVisitor.d.ts +2 -5
- package/dist/types/SemanticTokenVisitor.d.ts +2 -2
- package/dist/types/antlr/CircuitScriptLexer.d.ts +29 -22
- package/dist/types/antlr/CircuitScriptParser.d.ts +121 -44
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +12 -2
- package/dist/types/draw_symbols.d.ts +11 -6
- package/dist/types/execute.d.ts +6 -4
- package/dist/types/export.d.ts +27 -1
- package/dist/types/geometry.d.ts +12 -9
- package/dist/types/globals.d.ts +2 -3
- package/dist/types/layout.d.ts +5 -0
- package/dist/types/objects/ClassComponent.d.ts +5 -0
- package/dist/types/objects/Wire.d.ts +2 -1
- package/dist/types/objects/types.d.ts +6 -0
- package/dist/types/visitor.d.ts +7 -3
- package/libs/lib.cst +28 -10
- package/package.json +1 -1
package/dist/esm/helpers.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from "fs";
|
|
2
|
-
import { generateKiCADNetList } from "./export.mjs";
|
|
2
|
+
import { generateKiCADNetList, printTree } from "./export.mjs";
|
|
3
3
|
import { LayoutEngine } from "./layout.mjs";
|
|
4
4
|
import { SequenceAction } from "./objects/ExecutionScope.mjs";
|
|
5
5
|
import { parseFileWithVisitor } from "./parser.mjs";
|
|
@@ -177,8 +177,11 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
177
177
|
console.log('Error during annotation: ', err);
|
|
178
178
|
}
|
|
179
179
|
if (kicadNetlistPath) {
|
|
180
|
-
const kicadNetList = generateKiCADNetList(visitor.getNetList());
|
|
181
|
-
|
|
180
|
+
const { tree: kicadNetList, missingFootprints } = generateKiCADNetList(visitor.getNetList());
|
|
181
|
+
missingFootprints.forEach(entry => {
|
|
182
|
+
console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
|
|
183
|
+
});
|
|
184
|
+
writeFileSync(kicadNetlistPath, printTree(kicadNetList));
|
|
182
185
|
console.log('Generated KiCad netlist file');
|
|
183
186
|
}
|
|
184
187
|
const { sequence, nets } = visitor.getGraph();
|
|
@@ -212,6 +215,7 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
212
215
|
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
213
216
|
if (outputPath) {
|
|
214
217
|
writeFileSync(outputPath, svgOutput);
|
|
218
|
+
console.log('Generated file', outputPath);
|
|
215
219
|
}
|
|
216
220
|
}
|
|
217
221
|
catch (err) {
|
package/dist/esm/layout.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { Geometry } from './geometry.mjs';
|
|
|
7
7
|
import { Logger } from './logger.mjs';
|
|
8
8
|
import { Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.mjs';
|
|
9
9
|
import { getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, toNearestGrid } from './utils.mjs';
|
|
10
|
+
import { Direction } from './objects/types.mjs';
|
|
10
11
|
export class LayoutEngine {
|
|
11
12
|
logger;
|
|
12
13
|
placeSubgraphVersion = 2;
|
|
@@ -935,16 +936,16 @@ function applyComponentParamsToSymbol(typeProp, component, symbol) {
|
|
|
935
936
|
function calculateSymbolAngle(symbol, pin, direction) {
|
|
936
937
|
let directionVector = 0;
|
|
937
938
|
switch (direction) {
|
|
938
|
-
case
|
|
939
|
+
case Direction.Right:
|
|
939
940
|
directionVector = 0;
|
|
940
941
|
break;
|
|
941
|
-
case
|
|
942
|
+
case Direction.Down:
|
|
942
943
|
directionVector = 90;
|
|
943
944
|
break;
|
|
944
|
-
case
|
|
945
|
+
case Direction.Left:
|
|
945
946
|
directionVector = 180;
|
|
946
947
|
break;
|
|
947
|
-
case
|
|
948
|
+
case Direction.Up:
|
|
948
949
|
directionVector = 270;
|
|
949
950
|
break;
|
|
950
951
|
}
|
|
@@ -1012,16 +1013,16 @@ export class RenderWire extends RenderObject {
|
|
|
1012
1013
|
this.segments.forEach(segment => {
|
|
1013
1014
|
const { direction, value } = segment;
|
|
1014
1015
|
let didAddPoint = false;
|
|
1015
|
-
if (direction ===
|
|
1016
|
+
if (direction === Direction.Down) {
|
|
1016
1017
|
tmpY += value;
|
|
1017
1018
|
}
|
|
1018
|
-
else if (direction ===
|
|
1019
|
+
else if (direction === Direction.Up) {
|
|
1019
1020
|
tmpY -= value;
|
|
1020
1021
|
}
|
|
1021
|
-
else if (direction ===
|
|
1022
|
+
else if (direction === Direction.Left) {
|
|
1022
1023
|
tmpX -= value;
|
|
1023
1024
|
}
|
|
1024
|
-
else if (direction ===
|
|
1025
|
+
else if (direction === Direction.Right) {
|
|
1025
1026
|
tmpX += value;
|
|
1026
1027
|
}
|
|
1027
1028
|
else if (direction === 'auto' || direction === "auto_") {
|
|
@@ -1090,16 +1091,16 @@ export class RenderWire extends RenderObject {
|
|
|
1090
1091
|
let tmpY = this.y;
|
|
1091
1092
|
excludeLastSegment.forEach(segment => {
|
|
1092
1093
|
const { direction, value } = segment;
|
|
1093
|
-
if (direction ===
|
|
1094
|
+
if (direction === Direction.Down) {
|
|
1094
1095
|
tmpY += value;
|
|
1095
1096
|
}
|
|
1096
|
-
else if (direction ===
|
|
1097
|
+
else if (direction === Direction.Up) {
|
|
1097
1098
|
tmpY -= value;
|
|
1098
1099
|
}
|
|
1099
|
-
else if (direction ===
|
|
1100
|
+
else if (direction === Direction.Left) {
|
|
1100
1101
|
tmpX -= value;
|
|
1101
1102
|
}
|
|
1102
|
-
else if (direction ===
|
|
1103
|
+
else if (direction === Direction.Right) {
|
|
1103
1104
|
tmpX += value;
|
|
1104
1105
|
}
|
|
1105
1106
|
});
|
|
@@ -1107,16 +1108,16 @@ export class RenderWire extends RenderObject {
|
|
|
1107
1108
|
let valueXY = null;
|
|
1108
1109
|
const lastSegment = this.segments[this.segments.length - 1];
|
|
1109
1110
|
switch (lastSegment.direction) {
|
|
1110
|
-
case
|
|
1111
|
+
case Direction.Left:
|
|
1111
1112
|
useValue = tmpX - untilX;
|
|
1112
1113
|
break;
|
|
1113
|
-
case
|
|
1114
|
+
case Direction.Right:
|
|
1114
1115
|
useValue = untilX - tmpX;
|
|
1115
1116
|
break;
|
|
1116
|
-
case
|
|
1117
|
+
case Direction.Up:
|
|
1117
1118
|
useValue = untilY - tmpY;
|
|
1118
1119
|
break;
|
|
1119
|
-
case
|
|
1120
|
+
case Direction.Down:
|
|
1120
1121
|
useValue = tmpY - untilY;
|
|
1121
1122
|
break;
|
|
1122
1123
|
case 'auto':
|
|
@@ -1224,6 +1225,24 @@ export class RenderJunction {
|
|
|
1224
1225
|
this.y = y;
|
|
1225
1226
|
}
|
|
1226
1227
|
}
|
|
1228
|
+
export function CalculatePinPositions(component) {
|
|
1229
|
+
const pinPositionMapping = new Map();
|
|
1230
|
+
let tmpSymbol;
|
|
1231
|
+
if (component.displayProp !== null
|
|
1232
|
+
&& component.displayProp instanceof SymbolDrawing) {
|
|
1233
|
+
tmpSymbol = new SymbolPlaceholder(component.displayProp);
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
const symbolPinDefinitions = generateLayoutPinDefinition(component);
|
|
1237
|
+
tmpSymbol = new SymbolCustom(symbolPinDefinitions);
|
|
1238
|
+
}
|
|
1239
|
+
tmpSymbol.refreshDrawing();
|
|
1240
|
+
const pins = component.pins;
|
|
1241
|
+
pins.forEach((value, key) => {
|
|
1242
|
+
pinPositionMapping.set(key, tmpSymbol.pinPosition(key));
|
|
1243
|
+
});
|
|
1244
|
+
return pinPositionMapping;
|
|
1245
|
+
}
|
|
1227
1246
|
function isPointOverlap(x, y, other) {
|
|
1228
1247
|
return (x >= other.x && y >= other.y && x <= (other.x + other.width) && y <= (other.y + other.height));
|
|
1229
1248
|
}
|
package/dist/esm/main.mjs
CHANGED
|
@@ -12,9 +12,9 @@ export default async function main() {
|
|
|
12
12
|
program
|
|
13
13
|
.description('generate graphical output from circuitscript files')
|
|
14
14
|
.version(version)
|
|
15
|
+
.argument('[input path]', 'Input path')
|
|
16
|
+
.argument('[output path]', 'Output path')
|
|
15
17
|
.option('-i, --input text <input text>', 'Input text directly')
|
|
16
|
-
.option('-f, --input-file <path>', 'Input file')
|
|
17
|
-
.option('-o, --output <path>', 'Output path')
|
|
18
18
|
.option('-c, --current-directory <path>', 'Set current directory')
|
|
19
19
|
.option('-k, --kicad-netlist <filename>', 'Create KiCad netlist')
|
|
20
20
|
.option('-w, --watch', 'Watch for file changes')
|
|
@@ -29,8 +29,8 @@ export default async function main() {
|
|
|
29
29
|
}
|
|
30
30
|
program.parse();
|
|
31
31
|
const options = program.opts();
|
|
32
|
+
const args = program.args;
|
|
32
33
|
const watchFileChanges = options.watch;
|
|
33
|
-
const outputPath = options.output ?? null;
|
|
34
34
|
const dumpNets = options.dumpNets;
|
|
35
35
|
const dumpData = options.dumpData;
|
|
36
36
|
const kicadNetlist = options.kicadNetlist;
|
|
@@ -39,18 +39,26 @@ export default async function main() {
|
|
|
39
39
|
console.log('watching for file changes...');
|
|
40
40
|
}
|
|
41
41
|
await prepareSVGEnvironment(fontsPath);
|
|
42
|
-
let inputFilePath =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
let inputFilePath = "";
|
|
43
|
+
if (args.length > 2) {
|
|
44
|
+
console.log("Error: Extra arguments passed");
|
|
45
|
+
return;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
let scriptData;
|
|
48
|
+
if (args.length > 0 && args[0]) {
|
|
49
|
+
inputFilePath = args[0];
|
|
49
50
|
scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
|
|
50
51
|
if (currentDirectory === null) {
|
|
51
52
|
currentDirectory = path.dirname(inputFilePath);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
55
|
+
else if (options.input) {
|
|
56
|
+
scriptData = options.input;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.log("Error: No input provided");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
54
62
|
const scriptOptions = {
|
|
55
63
|
currentDirectory,
|
|
56
64
|
defaultLibsPath,
|
|
@@ -59,6 +67,10 @@ export default async function main() {
|
|
|
59
67
|
kicadNetlistPath: kicadNetlist,
|
|
60
68
|
showStats: options.stats,
|
|
61
69
|
};
|
|
70
|
+
let outputPath = null;
|
|
71
|
+
if (args.length > 0 && args[1]) {
|
|
72
|
+
outputPath = args[1];
|
|
73
|
+
}
|
|
62
74
|
const output = renderScript(scriptData, outputPath, scriptOptions);
|
|
63
75
|
if (outputPath === null && output) {
|
|
64
76
|
console.log(output);
|
|
@@ -17,6 +17,11 @@ export class ClassComponent {
|
|
|
17
17
|
displayProp = null;
|
|
18
18
|
widthProp = null;
|
|
19
19
|
typeProp = null;
|
|
20
|
+
copyProp = false;
|
|
21
|
+
angleProp = 0;
|
|
22
|
+
followWireOrientationProp = true;
|
|
23
|
+
wireOrientationAngle = 0;
|
|
24
|
+
useWireOrientationAngle = true;
|
|
20
25
|
styles = {};
|
|
21
26
|
assignedRefDes = null;
|
|
22
27
|
constructor(instanceName, numPins, className) {
|
|
@@ -119,6 +124,9 @@ export class ClassComponent {
|
|
|
119
124
|
component.arrangeProps = this.arrangeProps;
|
|
120
125
|
component.widthProp = this.widthProp;
|
|
121
126
|
component.typeProp = this.typeProp;
|
|
127
|
+
component.angleProp = this.angleProp;
|
|
128
|
+
component.followWireOrientationProp = this.followWireOrientationProp;
|
|
129
|
+
component.useWireOrientationAngle = this.useWireOrientationAngle;
|
|
122
130
|
if (this.displayProp) {
|
|
123
131
|
if (typeof this.displayProp === "string") {
|
|
124
132
|
component.displayProp = this.displayProp;
|
|
@@ -10,3 +10,10 @@ export var ParseSymbolType;
|
|
|
10
10
|
ParseSymbolType["Function"] = "function";
|
|
11
11
|
ParseSymbolType["Undefined"] = "undefined";
|
|
12
12
|
})(ParseSymbolType || (ParseSymbolType = {}));
|
|
13
|
+
export var Direction;
|
|
14
|
+
(function (Direction) {
|
|
15
|
+
Direction["Left"] = "left";
|
|
16
|
+
Direction["Right"] = "right";
|
|
17
|
+
Direction["Down"] = "down";
|
|
18
|
+
Direction["Up"] = "up";
|
|
19
|
+
})(Direction || (Direction = {}));
|
package/dist/esm/render.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SVG, registerWindow } from '@svgdotjs/svg.js';
|
|
2
2
|
import { RenderFrameType, getBounds } from "./layout.mjs";
|
|
3
3
|
import { applyFontsToSVG, getCreateSVGWindow } from './sizing.mjs';
|
|
4
|
-
import { ParamKeys, bodyColor, junctionColor, junctionSize, wireColor } from './globals.mjs';
|
|
4
|
+
import { ComponentTypes, ParamKeys, bodyColor, junctionColor, junctionSize, wireColor } from './globals.mjs';
|
|
5
5
|
import { NumericValue } from './objects/ParamDefinition.mjs';
|
|
6
6
|
import { getBoundsSize } from './utils.mjs';
|
|
7
7
|
export function generateSVG2(graph) {
|
|
@@ -36,7 +36,7 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
|
|
|
36
36
|
const { symbol = null } = item;
|
|
37
37
|
if (symbol !== null && symbol) {
|
|
38
38
|
const extra = {};
|
|
39
|
-
if (item.component.
|
|
39
|
+
if (item.component.typeProp === ComponentTypes.net) {
|
|
40
40
|
extra.net_name = item.component.parameters.get(ParamKeys.net_name);
|
|
41
41
|
}
|
|
42
42
|
else if (item.component.parameters.has('value')) {
|
package/dist/esm/visitor.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { isNetOnlyComponent } from './execute.mjs';
|
|
2
1
|
import { ClassComponent } from './objects/ClassComponent.mjs';
|
|
3
2
|
import { NumericValue, ParamDefinition, } from './objects/ParamDefinition.mjs';
|
|
4
3
|
import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
|
|
5
4
|
import { PinTypes } from './objects/PinTypes.mjs';
|
|
6
5
|
import { UndeclaredReference } from './objects/types.mjs';
|
|
7
|
-
import { BlockTypes, ComponentTypes, NoNetText } from './globals.mjs';
|
|
8
|
-
import { SymbolDrawingCommands } from './draw_symbols.mjs';
|
|
6
|
+
import { BlockTypes, ComponentTypes, NoNetText, ReferenceTypes } from './globals.mjs';
|
|
7
|
+
import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.mjs';
|
|
9
8
|
import { BaseVisitor } from './BaseVisitor.mjs';
|
|
10
9
|
export class ParserVisitor extends BaseVisitor {
|
|
11
10
|
visitKeyword_assignment_expr = (ctx) => {
|
|
@@ -29,10 +28,9 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
29
28
|
};
|
|
30
29
|
visitAdd_component_expr = (ctx) => {
|
|
31
30
|
const ctxDataWithAssignmentExpr = ctx.data_expr_with_assignment();
|
|
32
|
-
this.setParam(ctxDataWithAssignmentExpr, { clone: false });
|
|
33
31
|
this.visit(ctxDataWithAssignmentExpr);
|
|
34
32
|
const [component, pinValue] = this.getResult(ctxDataWithAssignmentExpr);
|
|
35
|
-
|
|
33
|
+
this.getExecutor().addComponentExisting(component, pinValue);
|
|
36
34
|
};
|
|
37
35
|
visitAt_component_expr = (ctx) => {
|
|
38
36
|
if (ctx.Point()) {
|
|
@@ -135,18 +133,22 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
135
133
|
properties.get('display') : null;
|
|
136
134
|
const type = properties.has('type') ?
|
|
137
135
|
properties.get('type') : null;
|
|
136
|
+
const copy = properties.has('copy') ?
|
|
137
|
+
properties.get('copy') : false;
|
|
138
138
|
const width = properties.has('width') ?
|
|
139
139
|
properties.get('width') : null;
|
|
140
|
+
const angle = properties.has('angle') ?
|
|
141
|
+
properties.get('angle') : null;
|
|
142
|
+
const followWireOrientation = properties.has('followWireOrientation') ?
|
|
143
|
+
properties.get('followWireOrientation') : true;
|
|
140
144
|
const props = {
|
|
141
|
-
arrange,
|
|
142
|
-
|
|
143
|
-
type,
|
|
144
|
-
width,
|
|
145
|
+
arrange, display, type, width, copy,
|
|
146
|
+
angle, followWireOrientation
|
|
145
147
|
};
|
|
146
148
|
this.setResult(ctx, this.getExecutor().createComponent(instanceName, pins, params, props));
|
|
147
149
|
};
|
|
148
150
|
visitCreate_graphic_expr = (ctx) => {
|
|
149
|
-
const commands = ctx.
|
|
151
|
+
const commands = ctx.graphic_expr().reduce((accum, item) => {
|
|
150
152
|
this.visit(item);
|
|
151
153
|
const [commandName, parameters] = this.getResult(item);
|
|
152
154
|
const keywordParams = new Map();
|
|
@@ -166,7 +168,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
166
168
|
drawing.source = ctx.getText();
|
|
167
169
|
this.setResult(ctx, drawing);
|
|
168
170
|
};
|
|
169
|
-
|
|
171
|
+
visitGraphic_expr = (ctx) => {
|
|
170
172
|
let commandName = null;
|
|
171
173
|
const command = ctx._command;
|
|
172
174
|
if (command) {
|
|
@@ -175,9 +177,20 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
175
177
|
else {
|
|
176
178
|
throw "Invalid command!";
|
|
177
179
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
let parameters = [];
|
|
181
|
+
const ctxNestedProperties = ctx.nested_properties_inner();
|
|
182
|
+
if (ctxNestedProperties) {
|
|
183
|
+
this.visit(ctxNestedProperties);
|
|
184
|
+
const nestedKeyValues = this.getResult(ctxNestedProperties);
|
|
185
|
+
nestedKeyValues.forEach((value, key) => {
|
|
186
|
+
parameters.push(['keyword', key, value]);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const ctxParameters = ctx.parameters();
|
|
191
|
+
this.visit(ctxParameters);
|
|
192
|
+
parameters = this.getResult(ctxParameters);
|
|
193
|
+
}
|
|
181
194
|
this.setResult(ctx, [commandName, parameters]);
|
|
182
195
|
};
|
|
183
196
|
visitProperty_expr = (ctx) => {
|
|
@@ -206,7 +219,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
206
219
|
}
|
|
207
220
|
this.setResult(ctx, value);
|
|
208
221
|
};
|
|
209
|
-
|
|
222
|
+
visitNested_properties_inner = (ctx) => {
|
|
210
223
|
const result = new Map();
|
|
211
224
|
ctx.property_expr().forEach((item) => {
|
|
212
225
|
this.visit(item);
|
|
@@ -217,6 +230,11 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
217
230
|
});
|
|
218
231
|
this.setResult(ctx, result);
|
|
219
232
|
};
|
|
233
|
+
visitNested_properties = (ctx) => {
|
|
234
|
+
const ctxNested = ctx.nested_properties_inner();
|
|
235
|
+
this.visit(ctxNested);
|
|
236
|
+
this.setResult(ctx, this.getResult(ctxNested));
|
|
237
|
+
};
|
|
220
238
|
visitProperty_key_expr = (ctx) => {
|
|
221
239
|
const ctxID = ctx.ID();
|
|
222
240
|
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
@@ -248,14 +266,9 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
248
266
|
this.visit(ctxAssignmentExpr);
|
|
249
267
|
component = this.getResult(ctxAssignmentExpr);
|
|
250
268
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
allowClone = clone;
|
|
255
|
-
}
|
|
256
|
-
if (allowClone && component instanceof ClassComponent
|
|
257
|
-
&& isNetOnlyComponent(component)) {
|
|
258
|
-
component = this.getExecutor().cloneComponent(component);
|
|
269
|
+
if (component instanceof ClassComponent
|
|
270
|
+
&& component.copyProp) {
|
|
271
|
+
component = this.getExecutor().copyComponent(component);
|
|
259
272
|
}
|
|
260
273
|
if (component && component instanceof ClassComponent) {
|
|
261
274
|
const modifiers = ctx.component_modifier_expr();
|
|
@@ -271,18 +284,40 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
271
284
|
else if (ctxID2) {
|
|
272
285
|
result = ctxID2.getText();
|
|
273
286
|
}
|
|
287
|
+
let shouldIgnoreWireOrientation = false;
|
|
274
288
|
if (modifierText === 'flip') {
|
|
275
289
|
const flipValue = result;
|
|
276
290
|
if (flipValue.indexOf('x') !== -1) {
|
|
277
291
|
component.setParam('flipX', 1);
|
|
292
|
+
shouldIgnoreWireOrientation = true;
|
|
278
293
|
}
|
|
279
294
|
if (flipValue.indexOf('y') !== -1) {
|
|
280
295
|
component.setParam('flipY', 1);
|
|
296
|
+
shouldIgnoreWireOrientation = true;
|
|
281
297
|
}
|
|
282
298
|
}
|
|
283
299
|
else if (modifierText === 'angle') {
|
|
284
300
|
const angleValue = Number(result);
|
|
285
301
|
component.setParam('angle', angleValue);
|
|
302
|
+
shouldIgnoreWireOrientation = true;
|
|
303
|
+
}
|
|
304
|
+
else if (modifierText === 'anchor') {
|
|
305
|
+
if (component.displayProp
|
|
306
|
+
&& component.displayProp instanceof SymbolDrawingCommands) {
|
|
307
|
+
const commands = (component.displayProp)
|
|
308
|
+
.getCommands();
|
|
309
|
+
commands.forEach(command => {
|
|
310
|
+
const positionParams = command[1];
|
|
311
|
+
const keywordParams = command[2];
|
|
312
|
+
if (command[0] === PlaceHolderCommands.label
|
|
313
|
+
&& positionParams[0] === 'value') {
|
|
314
|
+
keywordParams.set('anchor', result);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (shouldIgnoreWireOrientation) {
|
|
320
|
+
component.useWireOrientationAngle = false;
|
|
286
321
|
}
|
|
287
322
|
});
|
|
288
323
|
}
|
|
@@ -353,6 +388,41 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
353
388
|
else if (binaryOperatorType.NotEquals()) {
|
|
354
389
|
result = value1 != value2;
|
|
355
390
|
}
|
|
391
|
+
else if (binaryOperatorType.GreaterThan()) {
|
|
392
|
+
result = value1 > value2;
|
|
393
|
+
}
|
|
394
|
+
else if (binaryOperatorType.GreatOrEqualThan()) {
|
|
395
|
+
result = value1 >= value2;
|
|
396
|
+
}
|
|
397
|
+
else if (binaryOperatorType.LessThan()) {
|
|
398
|
+
result = value1 < value2;
|
|
399
|
+
}
|
|
400
|
+
else if (binaryOperatorType.LessOrEqualThan()) {
|
|
401
|
+
result = value1 <= value2;
|
|
402
|
+
}
|
|
403
|
+
this.setResult(ctx, result);
|
|
404
|
+
};
|
|
405
|
+
visitLogicalOperatorExpr = (ctx) => {
|
|
406
|
+
const ctx0 = ctx.data_expr(0);
|
|
407
|
+
const ctx1 = ctx.data_expr(1);
|
|
408
|
+
this.visit(ctx0);
|
|
409
|
+
const value1 = this.getResult(ctx0);
|
|
410
|
+
let value2 = false;
|
|
411
|
+
let skipNext = false;
|
|
412
|
+
if (ctx.LogicalOr() && value1) {
|
|
413
|
+
skipNext = true;
|
|
414
|
+
}
|
|
415
|
+
if (!skipNext) {
|
|
416
|
+
this.visit(ctx1);
|
|
417
|
+
value2 = this.getResult(ctx1);
|
|
418
|
+
}
|
|
419
|
+
let result = null;
|
|
420
|
+
if (ctx.LogicalAnd()) {
|
|
421
|
+
result = value1 && value2;
|
|
422
|
+
}
|
|
423
|
+
else if (ctx.LogicalOr()) {
|
|
424
|
+
result = value1 || value2;
|
|
425
|
+
}
|
|
356
426
|
this.setResult(ctx, result);
|
|
357
427
|
};
|
|
358
428
|
visitMultiplyExpr = (ctx) => {
|
|
@@ -555,6 +625,42 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
555
625
|
}
|
|
556
626
|
this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
|
|
557
627
|
};
|
|
628
|
+
visitIf_expr = (ctx) => {
|
|
629
|
+
const ctxDataExpr = ctx.data_expr();
|
|
630
|
+
this.visit(ctxDataExpr);
|
|
631
|
+
const result = this.getResult(ctxDataExpr);
|
|
632
|
+
if (result) {
|
|
633
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
const ctxInnerIfExprs = ctx.if_inner_expr();
|
|
637
|
+
let innerIfWasTrue = false;
|
|
638
|
+
for (let i = 0; i < ctxInnerIfExprs.length; i++) {
|
|
639
|
+
const tmpCtx = ctxInnerIfExprs[i];
|
|
640
|
+
this.visit(tmpCtx);
|
|
641
|
+
const innerResult = this.getResult(tmpCtx);
|
|
642
|
+
if (innerResult) {
|
|
643
|
+
innerIfWasTrue = true;
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (!innerIfWasTrue) {
|
|
648
|
+
const elseCtx = ctx.else_expr();
|
|
649
|
+
if (elseCtx) {
|
|
650
|
+
this.visit(elseCtx);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
visitIf_inner_expr = (ctx) => {
|
|
656
|
+
const ctxDataExpr = ctx.data_expr();
|
|
657
|
+
this.visit(ctxDataExpr);
|
|
658
|
+
const result = this.getResult(ctxDataExpr);
|
|
659
|
+
if (result) {
|
|
660
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
661
|
+
}
|
|
662
|
+
this.setResult(ctx, result);
|
|
663
|
+
};
|
|
558
664
|
pinTypes = [
|
|
559
665
|
PinTypes.Any,
|
|
560
666
|
PinTypes.IO,
|
|
@@ -582,8 +688,10 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
582
688
|
}
|
|
583
689
|
if (Array.isArray(pinDef)) {
|
|
584
690
|
const firstValue = pinDef[0];
|
|
585
|
-
if (
|
|
586
|
-
|
|
691
|
+
if (firstValue.type
|
|
692
|
+
&& firstValue.type === ReferenceTypes.pinType
|
|
693
|
+
&& this.pinTypes.indexOf(firstValue.value) !== -1) {
|
|
694
|
+
pinType = firstValue.value;
|
|
587
695
|
pinName = pinDef[1];
|
|
588
696
|
if (pinDef.length > 2) {
|
|
589
697
|
altPinNames = pinDef.slice(2);
|
|
@@ -4,7 +4,7 @@ import { ExecutionContext } from "./execute";
|
|
|
4
4
|
import { Logger } from "./logger";
|
|
5
5
|
import { ClassComponent } from "./objects/ClassComponent";
|
|
6
6
|
import { Net } from "./objects/Net";
|
|
7
|
-
import { CallableParameter, CFunctionOptions, ComplexType, FunctionDefinedParameter, ReferenceType } from "./objects/types";
|
|
7
|
+
import { CallableParameter, CFunctionOptions, ComplexType, Direction, FunctionDefinedParameter, ReferenceType } from "./objects/types";
|
|
8
8
|
import { ParserRuleContext } from 'antlr4ng';
|
|
9
9
|
export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | ReferenceType | any> {
|
|
10
10
|
indentLevel: number;
|
|
@@ -16,7 +16,7 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | Refe
|
|
|
16
16
|
defaultLibsPath: string;
|
|
17
17
|
printStream: string[];
|
|
18
18
|
printToConsole: boolean;
|
|
19
|
-
acceptedDirections:
|
|
19
|
+
acceptedDirections: Direction[];
|
|
20
20
|
acceptedFlip: string[];
|
|
21
21
|
protected resultData: Map<ParserRuleContext, any>;
|
|
22
22
|
protected paramData: Map<ParserRuleContext, any>;
|
|
@@ -50,9 +50,6 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | Refe
|
|
|
50
50
|
visitBreak_keyword: (ctx: Break_keywordContext) => void;
|
|
51
51
|
protected setResult(ctx: ParserRuleContext, value: any): void;
|
|
52
52
|
protected getResult(ctx: ParserRuleContext): any;
|
|
53
|
-
protected setParam(ctx: ParserRuleContext, value: any): void;
|
|
54
|
-
protected getParam(ctx: ParserRuleContext): any;
|
|
55
|
-
protected hasParam(ctx: ParserRuleContext): boolean;
|
|
56
53
|
protected handleImportFile(name: string, throwErrors?: boolean): {
|
|
57
54
|
hasError: boolean;
|
|
58
55
|
hasParseError: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TerminalNode, Token } from "antlr4ng";
|
|
2
2
|
import { CircuitScriptLexer } from "./antlr/CircuitScriptLexer";
|
|
3
|
-
import { Function_def_exprContext, Create_component_exprContext, Create_graphic_exprContext, Atom_exprContext, Property_key_exprContext,
|
|
3
|
+
import { Function_def_exprContext, Create_component_exprContext, Create_graphic_exprContext, Atom_exprContext, Property_key_exprContext, ValueAtomExprContext, Assignment_exprContext, Import_exprContext, Function_args_exprContext, Function_call_exprContext, Graphic_exprContext } from "./antlr/CircuitScriptParser";
|
|
4
4
|
import { BaseVisitor, OnErrorCallback } from "./BaseVisitor";
|
|
5
5
|
export declare class SemanticTokensVisitor extends BaseVisitor {
|
|
6
6
|
parsedTokens: IParsedToken[];
|
|
@@ -14,7 +14,7 @@ export declare class SemanticTokensVisitor extends BaseVisitor {
|
|
|
14
14
|
visitCreate_component_expr: (ctx: Create_component_exprContext) => void;
|
|
15
15
|
visitCreate_graphic_expr: (ctx: Create_graphic_exprContext) => void;
|
|
16
16
|
visitProperty_key_expr: (ctx: Property_key_exprContext) => void;
|
|
17
|
-
|
|
17
|
+
visitGraphic_expr: (ctx: Graphic_exprContext) => void;
|
|
18
18
|
visitValueAtomExpr: (ctx: ValueAtomExprContext) => void;
|
|
19
19
|
visitAssignment_expr: (ctx: Assignment_exprContext) => void;
|
|
20
20
|
visitAtom_expr: (ctx: Atom_exprContext) => void;
|
|
@@ -24,28 +24,35 @@ export declare class CircuitScriptLexer extends antlr.Lexer {
|
|
|
24
24
|
static readonly Define = 22;
|
|
25
25
|
static readonly Import = 23;
|
|
26
26
|
static readonly If = 24;
|
|
27
|
-
static readonly
|
|
28
|
-
static readonly
|
|
29
|
-
static readonly
|
|
30
|
-
static readonly
|
|
31
|
-
static readonly
|
|
32
|
-
static readonly
|
|
33
|
-
static readonly
|
|
34
|
-
static readonly
|
|
35
|
-
static readonly
|
|
36
|
-
static readonly
|
|
37
|
-
static readonly
|
|
38
|
-
static readonly
|
|
39
|
-
static readonly
|
|
40
|
-
static readonly
|
|
41
|
-
static readonly
|
|
42
|
-
static readonly
|
|
43
|
-
static readonly
|
|
44
|
-
static readonly
|
|
45
|
-
static readonly
|
|
46
|
-
static readonly
|
|
47
|
-
static readonly
|
|
48
|
-
static readonly
|
|
27
|
+
static readonly Else = 25;
|
|
28
|
+
static readonly Not = 26;
|
|
29
|
+
static readonly Frame = 27;
|
|
30
|
+
static readonly Equals = 28;
|
|
31
|
+
static readonly NotEquals = 29;
|
|
32
|
+
static readonly GreaterThan = 30;
|
|
33
|
+
static readonly GreatOrEqualThan = 31;
|
|
34
|
+
static readonly LessThan = 32;
|
|
35
|
+
static readonly LessOrEqualThan = 33;
|
|
36
|
+
static readonly LogicalAnd = 34;
|
|
37
|
+
static readonly LogicalOr = 35;
|
|
38
|
+
static readonly Addition = 36;
|
|
39
|
+
static readonly Minus = 37;
|
|
40
|
+
static readonly Divide = 38;
|
|
41
|
+
static readonly Multiply = 39;
|
|
42
|
+
static readonly OPEN_PAREN = 40;
|
|
43
|
+
static readonly CLOSE_PAREN = 41;
|
|
44
|
+
static readonly NOT_CONNECTED = 42;
|
|
45
|
+
static readonly BOOLEAN_VALUE = 43;
|
|
46
|
+
static readonly ID = 44;
|
|
47
|
+
static readonly INTEGER_VALUE = 45;
|
|
48
|
+
static readonly DECIMAL_VALUE = 46;
|
|
49
|
+
static readonly NUMERIC_VALUE = 47;
|
|
50
|
+
static readonly STRING_VALUE = 48;
|
|
51
|
+
static readonly PERCENTAGE_VALUE = 49;
|
|
52
|
+
static readonly ALPHA_NUMERIC = 50;
|
|
53
|
+
static readonly WS = 51;
|
|
54
|
+
static readonly NEWLINE = 52;
|
|
55
|
+
static readonly COMMENT = 53;
|
|
49
56
|
static readonly channelNames: string[];
|
|
50
57
|
static readonly literalNames: (string | null)[];
|
|
51
58
|
static readonly symbolicNames: (string | null)[];
|