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.
Files changed (51) hide show
  1. package/LICENSE +1 -1
  2. package/dist/cjs/BaseVisitor.js +16 -12
  3. package/dist/cjs/SemanticTokenVisitor.js +3 -3
  4. package/dist/cjs/antlr/CircuitScriptLexer.js +189 -166
  5. package/dist/cjs/antlr/CircuitScriptParser.js +1295 -719
  6. package/dist/cjs/draw_symbols.js +42 -14
  7. package/dist/cjs/execute.js +91 -30
  8. package/dist/cjs/export.js +91 -5
  9. package/dist/cjs/geometry.js +45 -26
  10. package/dist/cjs/globals.js +1 -2
  11. package/dist/cjs/helpers.js +6 -2
  12. package/dist/cjs/layout.js +37 -17
  13. package/dist/cjs/main.js +21 -9
  14. package/dist/cjs/objects/ClassComponent.js +8 -0
  15. package/dist/cjs/objects/types.js +8 -1
  16. package/dist/cjs/render.js +1 -1
  17. package/dist/cjs/visitor.js +131 -23
  18. package/dist/esm/BaseVisitor.mjs +17 -13
  19. package/dist/esm/SemanticTokenVisitor.mjs +3 -3
  20. package/dist/esm/antlr/CircuitScriptLexer.mjs +189 -166
  21. package/dist/esm/antlr/CircuitScriptParser.mjs +1287 -716
  22. package/dist/esm/antlr/CircuitScriptVisitor.mjs +6 -1
  23. package/dist/esm/draw_symbols.mjs +44 -16
  24. package/dist/esm/execute.mjs +90 -26
  25. package/dist/esm/export.mjs +89 -6
  26. package/dist/esm/geometry.mjs +44 -25
  27. package/dist/esm/globals.mjs +1 -2
  28. package/dist/esm/helpers.mjs +7 -3
  29. package/dist/esm/layout.mjs +35 -16
  30. package/dist/esm/main.mjs +21 -9
  31. package/dist/esm/objects/ClassComponent.mjs +8 -0
  32. package/dist/esm/objects/types.mjs +7 -0
  33. package/dist/esm/render.mjs +2 -2
  34. package/dist/esm/visitor.mjs +133 -25
  35. package/dist/types/BaseVisitor.d.ts +2 -5
  36. package/dist/types/SemanticTokenVisitor.d.ts +2 -2
  37. package/dist/types/antlr/CircuitScriptLexer.d.ts +29 -22
  38. package/dist/types/antlr/CircuitScriptParser.d.ts +121 -44
  39. package/dist/types/antlr/CircuitScriptVisitor.d.ts +12 -2
  40. package/dist/types/draw_symbols.d.ts +11 -6
  41. package/dist/types/execute.d.ts +6 -4
  42. package/dist/types/export.d.ts +27 -1
  43. package/dist/types/geometry.d.ts +12 -9
  44. package/dist/types/globals.d.ts +2 -3
  45. package/dist/types/layout.d.ts +5 -0
  46. package/dist/types/objects/ClassComponent.d.ts +5 -0
  47. package/dist/types/objects/Wire.d.ts +2 -1
  48. package/dist/types/objects/types.d.ts +6 -0
  49. package/dist/types/visitor.d.ts +7 -3
  50. package/libs/lib.cst +28 -10
  51. package/package.json +1 -1
@@ -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();
@@ -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) {
@@ -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 'right':
939
+ case Direction.Right:
939
940
  directionVector = 0;
940
941
  break;
941
- case 'down':
942
+ case Direction.Down:
942
943
  directionVector = 90;
943
944
  break;
944
- case 'left':
945
+ case Direction.Left:
945
946
  directionVector = 180;
946
947
  break;
947
- case 'up':
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 === 'down') {
1016
+ if (direction === Direction.Down) {
1016
1017
  tmpY += value;
1017
1018
  }
1018
- else if (direction === 'up') {
1019
+ else if (direction === Direction.Up) {
1019
1020
  tmpY -= value;
1020
1021
  }
1021
- else if (direction === 'left') {
1022
+ else if (direction === Direction.Left) {
1022
1023
  tmpX -= value;
1023
1024
  }
1024
- else if (direction === 'right') {
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 === 'down') {
1094
+ if (direction === Direction.Down) {
1094
1095
  tmpY += value;
1095
1096
  }
1096
- else if (direction === 'up') {
1097
+ else if (direction === Direction.Up) {
1097
1098
  tmpY -= value;
1098
1099
  }
1099
- else if (direction === 'left') {
1100
+ else if (direction === Direction.Left) {
1100
1101
  tmpX -= value;
1101
1102
  }
1102
- else if (direction === 'right') {
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 'left':
1111
+ case Direction.Left:
1111
1112
  useValue = tmpX - untilX;
1112
1113
  break;
1113
- case 'right':
1114
+ case Direction.Right:
1114
1115
  useValue = untilX - tmpX;
1115
1116
  break;
1116
- case 'up':
1117
+ case Direction.Up:
1117
1118
  useValue = untilY - tmpY;
1118
1119
  break;
1119
- case 'down':
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 = 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,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 = {}));
@@ -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,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
- return this.getExecutor().addComponentExisting(component, pinValue);
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
- display,
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.sub_expr().reduce((accum, item) => {
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
- visitSub_expr = (ctx) => {
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
- const ctxParameters = ctx.parameters();
179
- this.visit(ctxParameters);
180
- const parameters = this.getResult(ctxParameters);
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
- visitNested_properties = (ctx) => {
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
- 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);
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 (this.pinTypes.indexOf(firstValue) !== -1) {
586
- pinType = firstValue;
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: string[];
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, 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)[];