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.
Files changed (41) hide show
  1. package/LICENSE +1 -1
  2. package/dist/cjs/BaseVisitor.js +9 -11
  3. package/dist/cjs/SemanticTokenVisitor.js +3 -3
  4. package/dist/cjs/antlr/CircuitScriptLexer.js +189 -166
  5. package/dist/cjs/antlr/CircuitScriptParser.js +1139 -622
  6. package/dist/cjs/draw_symbols.js +6 -0
  7. package/dist/cjs/execute.js +24 -30
  8. package/dist/cjs/export.js +91 -5
  9. package/dist/cjs/globals.js +1 -2
  10. package/dist/cjs/helpers.js +5 -2
  11. package/dist/cjs/main.js +21 -9
  12. package/dist/cjs/objects/ClassComponent.js +1 -0
  13. package/dist/cjs/render.js +1 -1
  14. package/dist/cjs/visitor.js +83 -14
  15. package/dist/esm/BaseVisitor.mjs +9 -11
  16. package/dist/esm/SemanticTokenVisitor.mjs +3 -3
  17. package/dist/esm/antlr/CircuitScriptLexer.mjs +189 -166
  18. package/dist/esm/antlr/CircuitScriptParser.mjs +1132 -619
  19. package/dist/esm/antlr/CircuitScriptVisitor.mjs +5 -1
  20. package/dist/esm/draw_symbols.mjs +7 -1
  21. package/dist/esm/execute.mjs +23 -26
  22. package/dist/esm/export.mjs +89 -6
  23. package/dist/esm/globals.mjs +1 -2
  24. package/dist/esm/helpers.mjs +6 -3
  25. package/dist/esm/main.mjs +21 -9
  26. package/dist/esm/objects/ClassComponent.mjs +1 -0
  27. package/dist/esm/render.mjs +2 -2
  28. package/dist/esm/visitor.mjs +84 -15
  29. package/dist/types/BaseVisitor.d.ts +0 -3
  30. package/dist/types/SemanticTokenVisitor.d.ts +2 -2
  31. package/dist/types/antlr/CircuitScriptLexer.d.ts +29 -22
  32. package/dist/types/antlr/CircuitScriptParser.d.ts +97 -29
  33. package/dist/types/antlr/CircuitScriptVisitor.d.ts +10 -2
  34. package/dist/types/draw_symbols.d.ts +3 -3
  35. package/dist/types/execute.d.ts +2 -4
  36. package/dist/types/export.d.ts +27 -1
  37. package/dist/types/globals.d.ts +2 -3
  38. package/dist/types/objects/ClassComponent.d.ts +1 -0
  39. package/dist/types/visitor.d.ts +5 -2
  40. package/libs/lib.cst +8 -7
  41. 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
- visitSub_expr;
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)];
@@ -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 (paramsMap.has(ParamKeys.__is_net)) {
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 { arrange = null } = props;
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
- cloneComponent(component) {
287
- let clonedComponent = null;
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
- clonedComponent = component.clone();
293
- clonedComponent._copyID = idNum;
294
- clonedComponent._copyFrom = component;
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, clonedComponent);
298
- clonedComponent.instanceName = cloneInstanceName;
299
- this.linkComponentPinNet(component, 1, clonedComponent, 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 clonedComponent;
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 (isNetComponent(tmpComponent) && tmpComponent.parameters.get(ParamKeys.net_name) === 'gnd') {
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) {
@@ -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
- console.log(instance.assignedRefDes, instance.instanceName, 'does not have footprint');
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"), "/somefile"],
71
- [Id("date"), "2023-11-19"],
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 printTree(tree);
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
+ }
@@ -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) {
@@ -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
- writeFileSync(kicadNetlistPath, kicadNetList);
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 = null;
43
- let scriptData;
44
- if (options.input) {
45
- scriptData = options.input;
42
+ let inputFilePath = "";
43
+ if (args.length > 2) {
44
+ console.log("Error: Extra arguments passed");
45
+ return;
46
46
  }
47
- else {
48
- inputFilePath = options.inputFile;
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,7 @@ export class ClassComponent {
17
17
  displayProp = null;
18
18
  widthProp = null;
19
19
  typeProp = null;
20
+ copyProp = false;
20
21
  styles = {};
21
22
  assignedRefDes = null;
22
23
  constructor(instanceName, numPins, className) {
@@ -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.parameters.has('__is_net')) {
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')) {
@@ -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.sub_expr().reduce((accum, item) => {
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
- visitSub_expr = (ctx) => {
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
- let allowClone = true;
252
- if (this.hasParam(ctx)) {
253
- const { clone } = this.getParam(ctx);
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 (this.pinTypes.indexOf(firstValue) !== -1) {
586
- pinType = firstValue;
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, Sub_exprContext, ValueAtomExprContext, Assignment_exprContext, Import_exprContext, Function_args_exprContext, Function_call_exprContext } from "./antlr/CircuitScriptParser";
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
- visitSub_expr: (ctx: Sub_exprContext) => void;
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 Not = 25;
28
- static readonly Frame = 26;
29
- static readonly Equals = 27;
30
- static readonly NotEquals = 28;
31
- static readonly Addition = 29;
32
- static readonly Minus = 30;
33
- static readonly Divide = 31;
34
- static readonly Multiply = 32;
35
- static readonly OPEN_PAREN = 33;
36
- static readonly CLOSE_PAREN = 34;
37
- static readonly NOT_CONNECTED = 35;
38
- static readonly BOOLEAN_VALUE = 36;
39
- static readonly ID = 37;
40
- static readonly INTEGER_VALUE = 38;
41
- static readonly DECIMAL_VALUE = 39;
42
- static readonly NUMERIC_VALUE = 40;
43
- static readonly STRING_VALUE = 41;
44
- static readonly PERCENTAGE_VALUE = 42;
45
- static readonly ALPHA_NUMERIC = 43;
46
- static readonly WS = 44;
47
- static readonly NEWLINE = 45;
48
- static readonly COMMENT = 46;
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)[];