circuitscript 0.0.25 → 0.0.26
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 +9 -11
- package/dist/cjs/SemanticTokenVisitor.js +3 -3
- package/dist/cjs/antlr/CircuitScriptLexer.js +189 -166
- package/dist/cjs/antlr/CircuitScriptParser.js +1139 -622
- package/dist/cjs/draw_symbols.js +6 -0
- package/dist/cjs/execute.js +24 -30
- package/dist/cjs/export.js +91 -5
- package/dist/cjs/globals.js +1 -2
- package/dist/cjs/helpers.js +5 -2
- package/dist/cjs/main.js +21 -9
- package/dist/cjs/objects/ClassComponent.js +1 -0
- package/dist/cjs/render.js +1 -1
- package/dist/cjs/visitor.js +83 -14
- package/dist/esm/BaseVisitor.mjs +9 -11
- package/dist/esm/SemanticTokenVisitor.mjs +3 -3
- package/dist/esm/antlr/CircuitScriptLexer.mjs +189 -166
- package/dist/esm/antlr/CircuitScriptParser.mjs +1132 -619
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +5 -1
- package/dist/esm/draw_symbols.mjs +7 -1
- package/dist/esm/execute.mjs +23 -26
- package/dist/esm/export.mjs +89 -6
- package/dist/esm/globals.mjs +1 -2
- package/dist/esm/helpers.mjs +6 -3
- package/dist/esm/main.mjs +21 -9
- package/dist/esm/objects/ClassComponent.mjs +1 -0
- package/dist/esm/render.mjs +2 -2
- package/dist/esm/visitor.mjs +84 -15
- package/dist/types/BaseVisitor.d.ts +0 -3
- package/dist/types/SemanticTokenVisitor.d.ts +2 -2
- package/dist/types/antlr/CircuitScriptLexer.d.ts +29 -22
- package/dist/types/antlr/CircuitScriptParser.d.ts +97 -29
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +10 -2
- package/dist/types/draw_symbols.d.ts +3 -3
- package/dist/types/execute.d.ts +2 -4
- package/dist/types/export.d.ts +27 -1
- package/dist/types/globals.d.ts +2 -3
- package/dist/types/objects/ClassComponent.d.ts +1 -0
- package/dist/types/visitor.d.ts +5 -2
- package/libs/lib.cst +8 -7
- package/package.json +1 -1
|
@@ -31,6 +31,7 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
|
|
|
31
31
|
visitFunctionCallExpr;
|
|
32
32
|
visitAdditionExpr;
|
|
33
33
|
visitMultiplyExpr;
|
|
34
|
+
visitLogicalOperatorExpr;
|
|
34
35
|
visitDataExpr;
|
|
35
36
|
visitUnaryOperatorExpr;
|
|
36
37
|
visitValueAtomExpr;
|
|
@@ -49,7 +50,7 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
|
|
|
49
50
|
visitFunction_return_expr;
|
|
50
51
|
visitCreate_component_expr;
|
|
51
52
|
visitCreate_graphic_expr;
|
|
52
|
-
|
|
53
|
+
visitGraphic_expr;
|
|
53
54
|
visitProperty_expr;
|
|
54
55
|
visitProperty_key_expr;
|
|
55
56
|
visitNested_properties;
|
|
@@ -61,4 +62,7 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
|
|
|
61
62
|
visitPoint_expr;
|
|
62
63
|
visitImport_expr;
|
|
63
64
|
visitFrame_expr;
|
|
65
|
+
visitIf_expr;
|
|
66
|
+
visitIf_inner_expr;
|
|
67
|
+
visitElse_expr;
|
|
64
68
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { SymbolPinSide, defaultFont } from "./globals.mjs";
|
|
1
|
+
import { ReferenceTypes, SymbolPinSide, defaultFont } from "./globals.mjs";
|
|
2
2
|
import { Geometry, GeometryProp, HorizontalAlign, Label, VerticalAlign } from "./geometry.mjs";
|
|
3
|
+
import { PinTypes } from "./objects/PinTypes.mjs";
|
|
3
4
|
const defaultSymbolLineWidth = 2;
|
|
4
5
|
export class SymbolGraphic {
|
|
5
6
|
drawPortsName = true;
|
|
@@ -348,6 +349,11 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
348
349
|
displayPinId = false;
|
|
349
350
|
}
|
|
350
351
|
let pinNameParam = null;
|
|
352
|
+
let pinType = PinTypes.Any;
|
|
353
|
+
if (positionParams[1].type && positionParams[1].type === ReferenceTypes.pinType) {
|
|
354
|
+
pinType = positionParams[1].value;
|
|
355
|
+
positionParams = [positionParams[0], ...positionParams.slice(2)];
|
|
356
|
+
}
|
|
351
357
|
if (typeof positionParams[1] === 'string') {
|
|
352
358
|
pinNameParam = positionParams[1];
|
|
353
359
|
positionParams = [positionParams[0], ...positionParams.slice(2)];
|
package/dist/esm/execute.mjs
CHANGED
|
@@ -144,12 +144,18 @@ export class ExecutionContext {
|
|
|
144
144
|
pins.forEach((pin) => {
|
|
145
145
|
component.pins.set(pin.id, pin);
|
|
146
146
|
});
|
|
147
|
+
component.arrangeProps = props.arrange ?? null;
|
|
148
|
+
component.displayProp = props.display ?? null;
|
|
149
|
+
component.widthProp = props.width ?? null;
|
|
150
|
+
component.typeProp = props.type ?? null;
|
|
151
|
+
component.copyProp = props.copy ?? false;
|
|
147
152
|
const paramsMap = new Map();
|
|
148
153
|
params.forEach((param) => {
|
|
149
154
|
component.parameters.set(param.paramName, param.paramValue);
|
|
150
155
|
paramsMap.set(param.paramName, param.paramValue);
|
|
151
156
|
});
|
|
152
|
-
if (
|
|
157
|
+
if (component.typeProp === ComponentTypes.net
|
|
158
|
+
|| component.typeProp === ComponentTypes.label) {
|
|
153
159
|
const netName = paramsMap.get(ParamKeys.net_name);
|
|
154
160
|
const priority = paramsMap.get(ParamKeys.priority);
|
|
155
161
|
const result = this.resolveNet(netName, this.netNamespace);
|
|
@@ -165,12 +171,7 @@ export class ExecutionContext {
|
|
|
165
171
|
this.scope.setNet(component, 1, tmpNet);
|
|
166
172
|
this.log('set net', netName, 'component', component);
|
|
167
173
|
}
|
|
168
|
-
const
|
|
169
|
-
component.arrangeProps = arrange;
|
|
170
|
-
component.displayProp = props.display ?? null;
|
|
171
|
-
component.widthProp = props.width ?? null;
|
|
172
|
-
component.typeProp = props.type ?? null;
|
|
173
|
-
const portSides = getPortSide(component.pins, arrange);
|
|
174
|
+
const portSides = getPortSide(component.pins, component.arrangeProps);
|
|
174
175
|
portSides.forEach(({ pinId, side, position }) => {
|
|
175
176
|
if (component.pins.has(pinId)) {
|
|
176
177
|
const tmpPin = component.pins.get(pinId);
|
|
@@ -187,6 +188,10 @@ export class ExecutionContext {
|
|
|
187
188
|
}
|
|
188
189
|
printPoint(extra = '') {
|
|
189
190
|
let netName = NoNetText;
|
|
191
|
+
if (this.scope.currentComponent === null || this.scope.currentPin === null) {
|
|
192
|
+
this.log((extra !== '' ? (extra + ' ') : '') + 'point is null');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
190
195
|
if (this.scope.hasNet(this.scope.currentComponent, this.scope.currentPin)) {
|
|
191
196
|
netName = this.scope
|
|
192
197
|
.getNet(this.scope.currentComponent, this.scope.currentPin)
|
|
@@ -283,22 +288,22 @@ export class ExecutionContext {
|
|
|
283
288
|
this.printPoint();
|
|
284
289
|
return this.getCurrentPoint();
|
|
285
290
|
}
|
|
286
|
-
|
|
287
|
-
let
|
|
291
|
+
copyComponent(component) {
|
|
292
|
+
let componentCopy = null;
|
|
288
293
|
if (!this.scope.copyIDs.has(component.instanceName)) {
|
|
289
294
|
this.scope.copyIDs.set(component.instanceName, 0);
|
|
290
295
|
}
|
|
291
296
|
const idNum = this.scope.copyIDs.get(component.instanceName);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
297
|
+
componentCopy = component.clone();
|
|
298
|
+
componentCopy._copyID = idNum;
|
|
299
|
+
componentCopy._copyFrom = component;
|
|
295
300
|
this.scope.copyIDs.set(component.instanceName, idNum + 1);
|
|
296
301
|
const cloneInstanceName = component.instanceName + ':' + idNum;
|
|
297
|
-
this.scope.instances.set(cloneInstanceName,
|
|
298
|
-
|
|
299
|
-
this.linkComponentPinNet(component, 1,
|
|
302
|
+
this.scope.instances.set(cloneInstanceName, componentCopy);
|
|
303
|
+
componentCopy.instanceName = cloneInstanceName;
|
|
304
|
+
this.linkComponentPinNet(component, 1, componentCopy, 1);
|
|
300
305
|
this.log('created clone of net component:', cloneInstanceName);
|
|
301
|
-
return
|
|
306
|
+
return componentCopy;
|
|
302
307
|
}
|
|
303
308
|
enterBlocks(blockType) {
|
|
304
309
|
if (blockType === BlockTypes.Point) {
|
|
@@ -565,7 +570,8 @@ export class ExecutionContext {
|
|
|
565
570
|
}
|
|
566
571
|
else if (action === SequenceAction.At || action === SequenceAction.To) {
|
|
567
572
|
const tmpComponent = sequenceAction[1];
|
|
568
|
-
if (
|
|
573
|
+
if (tmpComponent.typeProp === ComponentTypes.net
|
|
574
|
+
&& tmpComponent.parameters.get(ParamKeys.net_name) === 'gnd') {
|
|
569
575
|
tmpComponent._copyID = gndCopyIdOffset + incrementGndLinkId;
|
|
570
576
|
incrementGndLinkId += 1;
|
|
571
577
|
}
|
|
@@ -706,15 +712,6 @@ function isWireSegmentsEndAuto(segments) {
|
|
|
706
712
|
}
|
|
707
713
|
return false;
|
|
708
714
|
}
|
|
709
|
-
export function isNetComponent(component) {
|
|
710
|
-
return component.parameters.has(ParamKeys.__is_net);
|
|
711
|
-
}
|
|
712
|
-
export function isLabelComponent(component) {
|
|
713
|
-
return component.parameters.has(ParamKeys.__is_label);
|
|
714
|
-
}
|
|
715
|
-
export function isNetOnlyComponent(component) {
|
|
716
|
-
return isNetComponent(component) && !isLabelComponent(component);
|
|
717
|
-
}
|
|
718
715
|
export function getPortSide(pins, arrangeProps) {
|
|
719
716
|
const result = [];
|
|
720
717
|
if (arrangeProps === null) {
|
package/dist/esm/export.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { NumericValue } from "./objects/ParamDefinition.mjs";
|
|
|
3
3
|
export function generateKiCADNetList(netlist) {
|
|
4
4
|
const componentsList = [];
|
|
5
5
|
const nets = {};
|
|
6
|
+
const missingFootprints = [];
|
|
6
7
|
netlist.forEach(entry => {
|
|
7
8
|
const { instance, pins } = entry;
|
|
8
9
|
if (instance.assignedRefDes !== null) {
|
|
@@ -22,7 +23,10 @@ export function generateKiCADNetList(netlist) {
|
|
|
22
23
|
instance.parameters.get('footprint')]);
|
|
23
24
|
}
|
|
24
25
|
else {
|
|
25
|
-
|
|
26
|
+
missingFootprints.push({
|
|
27
|
+
refdes: instance.assignedRefDes,
|
|
28
|
+
instanceName: instance.instanceName
|
|
29
|
+
});
|
|
26
30
|
}
|
|
27
31
|
componentsList.push(instanceDetails);
|
|
28
32
|
for (const key in pins) {
|
|
@@ -63,20 +67,24 @@ export function generateKiCADNetList(netlist) {
|
|
|
63
67
|
]);
|
|
64
68
|
counter++;
|
|
65
69
|
}
|
|
70
|
+
const dateString = new Date().toISOString().slice(0, 10);
|
|
66
71
|
const tree = [
|
|
67
72
|
Id("export"),
|
|
68
73
|
[Id("version"), "E"],
|
|
69
74
|
[Id("design"),
|
|
70
|
-
[Id("source"), "/
|
|
71
|
-
[Id("date"),
|
|
75
|
+
[Id("source"), "/unknown-file"],
|
|
76
|
+
[Id("date"), dateString],
|
|
72
77
|
[Id("tool"), "circuitscript-to-kicad"]
|
|
73
78
|
],
|
|
74
79
|
[Id('components'), ...componentsList],
|
|
75
80
|
[Id('nets'), ...netItems]
|
|
76
81
|
];
|
|
77
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
tree,
|
|
84
|
+
missingFootprints
|
|
85
|
+
};
|
|
78
86
|
}
|
|
79
|
-
function printTree(tree, level = 0) {
|
|
87
|
+
export function printTree(tree, level = 0) {
|
|
80
88
|
const output = [];
|
|
81
89
|
if (!Array.isArray(tree)) {
|
|
82
90
|
return "\"" + tree + "\"";
|
|
@@ -98,9 +106,84 @@ function printTree(tree, level = 0) {
|
|
|
98
106
|
function Id(name) {
|
|
99
107
|
return new IdObject(name);
|
|
100
108
|
}
|
|
101
|
-
class IdObject {
|
|
109
|
+
export class IdObject {
|
|
102
110
|
keyName;
|
|
103
111
|
constructor(keyName) {
|
|
104
112
|
this.keyName = keyName;
|
|
105
113
|
}
|
|
106
114
|
}
|
|
115
|
+
export function _id(key) {
|
|
116
|
+
return new IdObject(key);
|
|
117
|
+
}
|
|
118
|
+
export class SExpObject {
|
|
119
|
+
object;
|
|
120
|
+
constructor(object) {
|
|
121
|
+
this.object = object;
|
|
122
|
+
}
|
|
123
|
+
getKey(object = null) {
|
|
124
|
+
object = object ?? this.object;
|
|
125
|
+
return object[0];
|
|
126
|
+
}
|
|
127
|
+
getValue(object = null) {
|
|
128
|
+
object = object ?? this.object;
|
|
129
|
+
return object.slice(1);
|
|
130
|
+
}
|
|
131
|
+
getJSON(object = null) {
|
|
132
|
+
object = object ?? this.object;
|
|
133
|
+
if (!Array.isArray(object)) {
|
|
134
|
+
return object;
|
|
135
|
+
}
|
|
136
|
+
const properties = {};
|
|
137
|
+
const keyName = object[0].keyName;
|
|
138
|
+
if (object.length === 2) {
|
|
139
|
+
properties[keyName] = this.getJSON(object[1]);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const innerProps = {};
|
|
143
|
+
this.getValue(object).forEach(item => {
|
|
144
|
+
const tmpValue = this.getJSON(item);
|
|
145
|
+
if (typeof tmpValue === "object") {
|
|
146
|
+
for (const key in tmpValue) {
|
|
147
|
+
if (innerProps[key]) {
|
|
148
|
+
if (!Array.isArray(innerProps[key])) {
|
|
149
|
+
innerProps[key] = [innerProps[key]];
|
|
150
|
+
}
|
|
151
|
+
innerProps[key].push(tmpValue[key]);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
innerProps[key] = tmpValue[key];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
innerProps[item[0].keyName] = tmpValue;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
properties[keyName] = innerProps;
|
|
163
|
+
}
|
|
164
|
+
return properties;
|
|
165
|
+
}
|
|
166
|
+
getWithId(id, object = null) {
|
|
167
|
+
object = object ?? this.object;
|
|
168
|
+
let result = null;
|
|
169
|
+
const key = object[0];
|
|
170
|
+
if (key.keyName === id) {
|
|
171
|
+
return object;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
this.getValue(object).some(item => {
|
|
175
|
+
if (Array.isArray(item)) {
|
|
176
|
+
result = this.getWithId(id, item);
|
|
177
|
+
if (result !== null) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
print() {
|
|
187
|
+
console.log(printTree(this.object));
|
|
188
|
+
}
|
|
189
|
+
}
|
package/dist/esm/globals.mjs
CHANGED
|
@@ -10,8 +10,6 @@ export var GlobalNames;
|
|
|
10
10
|
export const NoNetText = 'NO_NET';
|
|
11
11
|
export var ParamKeys;
|
|
12
12
|
(function (ParamKeys) {
|
|
13
|
-
ParamKeys["__is_net"] = "__is_net";
|
|
14
|
-
ParamKeys["__is_label"] = "__is_label";
|
|
15
13
|
ParamKeys["priority"] = "priority";
|
|
16
14
|
ParamKeys["net_name"] = "net_name";
|
|
17
15
|
})(ParamKeys || (ParamKeys = {}));
|
|
@@ -47,6 +45,7 @@ export var ReferenceTypes;
|
|
|
47
45
|
ReferenceTypes["value"] = "value";
|
|
48
46
|
ReferenceTypes["variable"] = "variable";
|
|
49
47
|
ReferenceTypes["instance"] = "instance";
|
|
48
|
+
ReferenceTypes["pinType"] = "pinType";
|
|
50
49
|
})(ReferenceTypes || (ReferenceTypes = {}));
|
|
51
50
|
export var BlockTypes;
|
|
52
51
|
(function (BlockTypes) {
|
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();
|
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);
|
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,10 +1,9 @@
|
|
|
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';
|
|
6
|
+
import { BlockTypes, ComponentTypes, NoNetText, ReferenceTypes } from './globals.mjs';
|
|
8
7
|
import { SymbolDrawingCommands } from './draw_symbols.mjs';
|
|
9
8
|
import { BaseVisitor } from './BaseVisitor.mjs';
|
|
10
9
|
export class ParserVisitor extends BaseVisitor {
|
|
@@ -29,7 +28,6 @@ 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
|
return this.getExecutor().addComponentExisting(component, pinValue);
|
|
@@ -135,6 +133,8 @@ 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
140
|
const props = {
|
|
@@ -142,11 +142,12 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
142
142
|
display,
|
|
143
143
|
type,
|
|
144
144
|
width,
|
|
145
|
+
copy
|
|
145
146
|
};
|
|
146
147
|
this.setResult(ctx, this.getExecutor().createComponent(instanceName, pins, params, props));
|
|
147
148
|
};
|
|
148
149
|
visitCreate_graphic_expr = (ctx) => {
|
|
149
|
-
const commands = ctx.
|
|
150
|
+
const commands = ctx.graphic_expr().reduce((accum, item) => {
|
|
150
151
|
this.visit(item);
|
|
151
152
|
const [commandName, parameters] = this.getResult(item);
|
|
152
153
|
const keywordParams = new Map();
|
|
@@ -166,7 +167,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
166
167
|
drawing.source = ctx.getText();
|
|
167
168
|
this.setResult(ctx, drawing);
|
|
168
169
|
};
|
|
169
|
-
|
|
170
|
+
visitGraphic_expr = (ctx) => {
|
|
170
171
|
let commandName = null;
|
|
171
172
|
const command = ctx._command;
|
|
172
173
|
if (command) {
|
|
@@ -248,14 +249,9 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
248
249
|
this.visit(ctxAssignmentExpr);
|
|
249
250
|
component = this.getResult(ctxAssignmentExpr);
|
|
250
251
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
allowClone = clone;
|
|
255
|
-
}
|
|
256
|
-
if (allowClone && component instanceof ClassComponent
|
|
257
|
-
&& isNetOnlyComponent(component)) {
|
|
258
|
-
component = this.getExecutor().cloneComponent(component);
|
|
252
|
+
if (component instanceof ClassComponent
|
|
253
|
+
&& component.copyProp) {
|
|
254
|
+
component = this.getExecutor().copyComponent(component);
|
|
259
255
|
}
|
|
260
256
|
if (component && component instanceof ClassComponent) {
|
|
261
257
|
const modifiers = ctx.component_modifier_expr();
|
|
@@ -353,6 +349,41 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
353
349
|
else if (binaryOperatorType.NotEquals()) {
|
|
354
350
|
result = value1 != value2;
|
|
355
351
|
}
|
|
352
|
+
else if (binaryOperatorType.GreaterThan()) {
|
|
353
|
+
result = value1 > value2;
|
|
354
|
+
}
|
|
355
|
+
else if (binaryOperatorType.GreatOrEqualThan()) {
|
|
356
|
+
result = value1 >= value2;
|
|
357
|
+
}
|
|
358
|
+
else if (binaryOperatorType.LessThan()) {
|
|
359
|
+
result = value1 < value2;
|
|
360
|
+
}
|
|
361
|
+
else if (binaryOperatorType.LessOrEqualThan()) {
|
|
362
|
+
result = value1 <= value2;
|
|
363
|
+
}
|
|
364
|
+
this.setResult(ctx, result);
|
|
365
|
+
};
|
|
366
|
+
visitLogicalOperatorExpr = (ctx) => {
|
|
367
|
+
const ctx0 = ctx.data_expr(0);
|
|
368
|
+
const ctx1 = ctx.data_expr(1);
|
|
369
|
+
this.visit(ctx0);
|
|
370
|
+
const value1 = this.getResult(ctx0);
|
|
371
|
+
let value2 = false;
|
|
372
|
+
let skipNext = false;
|
|
373
|
+
if (ctx.LogicalOr() && value1) {
|
|
374
|
+
skipNext = true;
|
|
375
|
+
}
|
|
376
|
+
if (!skipNext) {
|
|
377
|
+
this.visit(ctx1);
|
|
378
|
+
value2 = this.getResult(ctx1);
|
|
379
|
+
}
|
|
380
|
+
let result = null;
|
|
381
|
+
if (ctx.LogicalAnd()) {
|
|
382
|
+
result = value1 && value2;
|
|
383
|
+
}
|
|
384
|
+
else if (ctx.LogicalOr()) {
|
|
385
|
+
result = value1 || value2;
|
|
386
|
+
}
|
|
356
387
|
this.setResult(ctx, result);
|
|
357
388
|
};
|
|
358
389
|
visitMultiplyExpr = (ctx) => {
|
|
@@ -555,6 +586,42 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
555
586
|
}
|
|
556
587
|
this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
|
|
557
588
|
};
|
|
589
|
+
visitIf_expr = (ctx) => {
|
|
590
|
+
const ctxDataExpr = ctx.data_expr();
|
|
591
|
+
this.visit(ctxDataExpr);
|
|
592
|
+
const result = this.getResult(ctxDataExpr);
|
|
593
|
+
if (result) {
|
|
594
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
const ctxInnerIfExprs = ctx.if_inner_expr();
|
|
598
|
+
let innerIfWasTrue = false;
|
|
599
|
+
for (let i = 0; i < ctxInnerIfExprs.length; i++) {
|
|
600
|
+
const tmpCtx = ctxInnerIfExprs[i];
|
|
601
|
+
this.visit(tmpCtx);
|
|
602
|
+
const innerResult = this.getResult(tmpCtx);
|
|
603
|
+
if (innerResult) {
|
|
604
|
+
innerIfWasTrue = true;
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (!innerIfWasTrue) {
|
|
609
|
+
const elseCtx = ctx.else_expr();
|
|
610
|
+
if (elseCtx) {
|
|
611
|
+
this.visit(elseCtx);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
visitIf_inner_expr = (ctx) => {
|
|
617
|
+
const ctxDataExpr = ctx.data_expr();
|
|
618
|
+
this.visit(ctxDataExpr);
|
|
619
|
+
const result = this.getResult(ctxDataExpr);
|
|
620
|
+
if (result) {
|
|
621
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
622
|
+
}
|
|
623
|
+
this.setResult(ctx, result);
|
|
624
|
+
};
|
|
558
625
|
pinTypes = [
|
|
559
626
|
PinTypes.Any,
|
|
560
627
|
PinTypes.IO,
|
|
@@ -582,8 +649,10 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
582
649
|
}
|
|
583
650
|
if (Array.isArray(pinDef)) {
|
|
584
651
|
const firstValue = pinDef[0];
|
|
585
|
-
if (
|
|
586
|
-
|
|
652
|
+
if (firstValue.type
|
|
653
|
+
&& firstValue.type === ReferenceTypes.pinType
|
|
654
|
+
&& this.pinTypes.indexOf(firstValue.value) !== -1) {
|
|
655
|
+
pinType = firstValue.value;
|
|
587
656
|
pinName = pinDef[1];
|
|
588
657
|
if (pinDef.length > 2) {
|
|
589
658
|
altPinNames = pinDef.slice(2);
|
|
@@ -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)[];
|