circuitscript 0.1.14 → 0.1.16

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 (39) hide show
  1. package/dist/cjs/BaseVisitor.js +96 -34
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +3 -3
  3. package/dist/cjs/antlr/CircuitScriptParser.js +868 -757
  4. package/dist/cjs/builtinMethods.js +11 -1
  5. package/dist/cjs/execute.js +18 -11
  6. package/dist/cjs/geometry.js +19 -0
  7. package/dist/cjs/globals.js +6 -2
  8. package/dist/cjs/graph.js +298 -0
  9. package/dist/cjs/helpers.js +6 -2
  10. package/dist/cjs/layout.js +27 -261
  11. package/dist/cjs/objects/types.js +27 -6
  12. package/dist/cjs/render.js +20 -14
  13. package/dist/cjs/visitor.js +32 -30
  14. package/dist/esm/BaseVisitor.js +96 -34
  15. package/dist/esm/antlr/CircuitScriptLexer.js +3 -3
  16. package/dist/esm/antlr/CircuitScriptParser.js +864 -755
  17. package/dist/esm/antlr/CircuitScriptVisitor.js +2 -0
  18. package/dist/esm/builtinMethods.js +11 -1
  19. package/dist/esm/execute.js +19 -12
  20. package/dist/esm/geometry.js +19 -0
  21. package/dist/esm/globals.js +5 -1
  22. package/dist/esm/graph.js +293 -0
  23. package/dist/esm/helpers.js +6 -2
  24. package/dist/esm/layout.js +23 -237
  25. package/dist/esm/objects/types.js +27 -6
  26. package/dist/esm/render.js +20 -14
  27. package/dist/esm/visitor.js +33 -31
  28. package/dist/types/BaseVisitor.d.ts +3 -1
  29. package/dist/types/antlr/CircuitScriptParser.d.ts +42 -26
  30. package/dist/types/antlr/CircuitScriptVisitor.d.ts +4 -0
  31. package/dist/types/draw_symbols.d.ts +1 -1
  32. package/dist/types/execute.d.ts +5 -5
  33. package/dist/types/geometry.d.ts +3 -1
  34. package/dist/types/globals.d.ts +7 -3
  35. package/dist/types/graph.d.ts +28 -0
  36. package/dist/types/layout.d.ts +6 -10
  37. package/dist/types/objects/ExecutionScope.d.ts +3 -3
  38. package/dist/types/objects/types.d.ts +16 -6
  39. package/package.json +1 -1
@@ -1,21 +1,20 @@
1
- import graphlib, { Graph } from '@dagrejs/graphlib';
1
+ import graphlib from '@dagrejs/graphlib';
2
2
  const { alg } = graphlib;
3
- import { SymbolCustom, SymbolDrawing, SymbolCustomModule, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.js";
4
- import { FrameAction, SequenceAction } from "./objects/ExecutionScope.js";
5
- import { ComponentTypes, defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, NetGraphicsParams, ParamKeys, WireAutoDirection } from './globals.js';
3
+ import { SymbolCustom, SymbolDrawing, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.js";
4
+ import { defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, NetGraphicsParams, ParamKeys, WireAutoDirection } from './globals.js';
6
5
  import { Geometry, HorizontalAlign, VerticalAlign } from './geometry.js';
7
- import { Logger } from './logger.js';
8
6
  import { FixedFrameIds, Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.js';
9
7
  import { areasOverlap, combineMaps, getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.js';
10
8
  import { Direction } from './objects/types.js';
11
9
  import { milsToMM, UnitDimension } from './helpers.js';
12
- import { numeric, NumericValue } from './objects/ParamDefinition.js';
10
+ import { numeric } from './objects/ParamDefinition.js';
11
+ import { generateLayoutPinDefinition, getWireName, RenderItemType } from './graph.js';
13
12
  export class LayoutEngine {
14
13
  logger;
15
14
  layoutWarnings = [];
16
15
  showBaseFrame = false;
17
- constructor(options = { showBaseFrame: false }) {
18
- this.logger = new Logger();
16
+ constructor(logger, options = { showBaseFrame: false }) {
17
+ this.logger = logger;
19
18
  const { showBaseFrame = false } = options ?? {};
20
19
  this.showBaseFrame = showBaseFrame;
21
20
  }
@@ -29,30 +28,8 @@ export class LayoutEngine {
29
28
  const padding = ''.padStart(value * 4, ' ');
30
29
  return "[" + value + "]" + padding;
31
30
  }
32
- runLayout(sequence, nets) {
33
- const logNodesAndEdges = true;
31
+ runLayout(graph, containerFrames, nets) {
34
32
  const renderNets = this.collectRenderNets(nets);
35
- this.print('===== creating graph and populating with nodes =====');
36
- const { graph, containerFrames } = this.generateLayoutGraph(sequence, nets);
37
- this.print('===== done populating graph =====');
38
- this.print('');
39
- if (logNodesAndEdges) {
40
- this.print('===== graph edges =====');
41
- const allEdges = graph.edges();
42
- allEdges.forEach(edge => {
43
- const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
44
- this.print(nodeId1, 'pin', pin1, '-----', nodeId2, 'pin', pin2);
45
- });
46
- this.print('===== end edges =====');
47
- this.print();
48
- this.print('===== graph nodes =====');
49
- const nodes = graph.nodes();
50
- nodes.forEach(node => {
51
- this.print(`name:${node}, value:${graph.node(node)}`);
52
- });
53
- this.print('===== end nodes =====');
54
- this.print('');
55
- }
56
33
  const subgraphInfo = this.sizeSubGraphs(graph);
57
34
  const dumpSubgraphInfo = true;
58
35
  if (dumpSubgraphInfo) {
@@ -112,8 +89,19 @@ export class LayoutEngine {
112
89
  const value = net.params.get(NetGraphicsParams.LineWidth);
113
90
  renderNet.lineWidth = milsToMM(value).toNumber();
114
91
  }
115
- if (net.params.has(NetGraphicsParams.Highight)) {
116
- renderNet.highlight = net.params.get(NetGraphicsParams.Highight);
92
+ if (net.params.has(NetGraphicsParams.Highlight)) {
93
+ renderNet.highlight =
94
+ net.params.get(NetGraphicsParams.Highlight);
95
+ }
96
+ if (net.params.has(NetGraphicsParams.HighlightWidth)) {
97
+ renderNet.highlightWidth =
98
+ milsToMM(net.params.get(NetGraphicsParams.HighlightWidth))
99
+ .toNumber();
100
+ }
101
+ if (net.params.has(NetGraphicsParams.HighlightOpacity)) {
102
+ renderNet.highlightOpacity =
103
+ net.params.get(NetGraphicsParams.HighlightOpacity)
104
+ .toNumber();
117
105
  }
118
106
  renderNets.set(net.toString(), renderNet);
119
107
  });
@@ -167,12 +155,13 @@ export class LayoutEngine {
167
155
  });
168
156
  }
169
157
  else {
170
- const { intersectPoints, segments } = Geometry.mergeWires(allLines);
158
+ const { intersectPoints, segments, lines } = Geometry.mergeWires(allLines);
171
159
  mergedWires.push({
172
160
  netName: netName,
173
161
  segments,
174
162
  intersectPoints,
175
163
  net: renderNet,
164
+ lines,
176
165
  });
177
166
  intersectPoints.forEach(([x, y]) => {
178
167
  junctions.push(new RenderJunction(numeric(x), numeric(y), renderNet));
@@ -631,158 +620,6 @@ export class LayoutEngine {
631
620
  }
632
621
  }
633
622
  }
634
- generateLayoutGraph(sequence, nets) {
635
- let previousNode = null;
636
- let previousPin = null;
637
- const graph = new Graph({
638
- directed: true,
639
- compound: true,
640
- });
641
- this.print('sequence length:', sequence.length);
642
- const baseFrame = new RenderFrame(new Frame(FixedFrameIds.BaseFrame));
643
- const frameStack = [baseFrame];
644
- const containerFrames = [baseFrame];
645
- sequence.forEach((sequenceStep, index) => {
646
- const action = sequenceStep[0];
647
- let tmpComponent;
648
- switch (action) {
649
- case SequenceAction.To:
650
- case SequenceAction.At: {
651
- this.print(...sequenceStep);
652
- const [, component, pin] = sequenceStep;
653
- const tmpInstanceName = component.instanceName;
654
- if (!graph.hasNode(tmpInstanceName)) {
655
- this.print('create instance', tmpInstanceName);
656
- const { displayProp = null } = component;
657
- let tmpSymbol;
658
- if (displayProp instanceof SymbolDrawing) {
659
- tmpSymbol = new SymbolPlaceholder(displayProp);
660
- tmpSymbol.drawing.logger = this.logger;
661
- }
662
- else {
663
- const symbolPinDefinitions = generateLayoutPinDefinition(component);
664
- if (component.typeProp === ComponentTypes.module) {
665
- tmpSymbol = new SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
666
- }
667
- else {
668
- tmpSymbol = new SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
669
- }
670
- }
671
- applyComponentParamsToSymbol(component, tmpSymbol);
672
- tmpSymbol.refreshDrawing();
673
- const { width: useWidth, height: useHeight } = tmpSymbol.size();
674
- tmpComponent = new RenderComponent(component, useWidth, useHeight);
675
- tmpComponent.symbol = tmpSymbol;
676
- graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, index]);
677
- const currentFrame = frameStack[frameStack.length - 1];
678
- currentFrame && currentFrame.innerItems.push(tmpComponent);
679
- }
680
- if (action === SequenceAction.To && previousNode && previousPin) {
681
- this.setGraphEdge(graph, previousNode, tmpInstanceName, makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, index));
682
- }
683
- previousNode = tmpInstanceName;
684
- previousPin = pin;
685
- break;
686
- }
687
- case SequenceAction.Wire: {
688
- const [, wireId, wireSegments] = sequenceStep;
689
- let useNet;
690
- if (previousNode !== null) {
691
- const [prevNodeType, prevNodeItem] = graph.node(previousNode);
692
- if (prevNodeType === RenderItemType.Component) {
693
- const matchingItem = nets.find(([comp, pin]) => {
694
- return comp.instanceName === previousNode
695
- && pin === previousPin;
696
- });
697
- if (matchingItem !== undefined) {
698
- useNet = matchingItem[2];
699
- }
700
- }
701
- else if (prevNodeType === RenderItemType.Wire) {
702
- useNet = prevNodeItem.net;
703
- }
704
- }
705
- const wire = new RenderWire(useNet, numeric(0), numeric(0), wireSegments);
706
- wire.id = wireId;
707
- wire.netName = useNet.toString();
708
- const wireName = getWireName(wire.id);
709
- graph.setNode(wireName, [RenderItemType.Wire, wire, index]);
710
- this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, index));
711
- previousNode = wireName;
712
- previousPin = 1;
713
- const wireSegmentsInfo = wireSegments.map(item => {
714
- const tmp = {
715
- direction: item.direction,
716
- value: item.value,
717
- };
718
- if (item.valueXY) {
719
- tmp.valueXY = item.valueXY;
720
- }
721
- if (item.until) {
722
- tmp.until = [item.until[0].toString(), item.until[1]];
723
- }
724
- return tmp;
725
- });
726
- this.print(SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
727
- break;
728
- }
729
- case SequenceAction.WireJump: {
730
- this.print(...sequenceStep);
731
- const wireId = sequenceStep[1];
732
- const wireName = getWireName(wireId);
733
- let wirePin = 1;
734
- if (sequenceStep.length === 3) {
735
- wirePin = sequenceStep[2];
736
- }
737
- previousNode = wireName;
738
- previousPin = wirePin;
739
- break;
740
- }
741
- case SequenceAction.Frame: {
742
- const [, frameObject, frameAction] = sequenceStep;
743
- if (frameAction === FrameAction.Enter) {
744
- const prevFrame = frameStack[frameStack.length - 1];
745
- const newFrame = new RenderFrame(frameObject);
746
- if (frameObject.parameters.has(FrameParamKeys.Direction)) {
747
- newFrame.direction =
748
- frameObject.parameters.get(FrameParamKeys.Direction);
749
- }
750
- if (frameObject.parameters.has(FrameParamKeys.Padding)) {
751
- newFrame.padding = milsToMM(frameObject.parameters.get(FrameParamKeys.Padding));
752
- }
753
- if (frameObject.parameters.has(FrameParamKeys.Border)) {
754
- newFrame.borderWidth =
755
- frameObject.parameters.get(FrameParamKeys.Border);
756
- }
757
- if (frameObject.parameters.has(FrameParamKeys.Width)) {
758
- newFrame.width = milsToMM(frameObject.parameters.get(FrameParamKeys.Width));
759
- }
760
- if (frameObject.parameters.has(FrameParamKeys.Height)) {
761
- newFrame.height = milsToMM(frameObject.parameters.get(FrameParamKeys.Height));
762
- }
763
- containerFrames.push(newFrame);
764
- frameStack.push(newFrame);
765
- prevFrame && prevFrame.innerItems.push(newFrame);
766
- }
767
- else if (frameAction === FrameAction.Exit) {
768
- frameStack.pop();
769
- }
770
- break;
771
- }
772
- }
773
- });
774
- return {
775
- graph,
776
- containerFrames,
777
- };
778
- }
779
- setGraphEdge(graph, node1, node2, edgeValue) {
780
- if (!graph.isDirected && graph.hasEdge(node1, node2)) {
781
- this.print(`Warning: edge already exists ${node1} ${node2}`);
782
- }
783
- graph.setEdge(node1, node2, edgeValue);
784
- this.print(`created edge: node1:${node1} node2:${node2} edgeValue:${edgeValue}`);
785
- }
786
623
  sizeSubGraphs(graph) {
787
624
  const subGraphs = alg.components(graph);
788
625
  const subGraphsStarts = [];
@@ -1080,52 +917,6 @@ function getNeighbours(graph, nodeIds) {
1080
917
  return accum;
1081
918
  }, []);
1082
919
  }
1083
- function makeEdgeValue(instanceName1, instancePin1, instanceName2, instancePin2, priority) {
1084
- return [instanceName1, instancePin1, instanceName2, instancePin2, priority];
1085
- }
1086
- function getWireName(wireId) {
1087
- return 'wire:' + wireId;
1088
- }
1089
- function generateLayoutPinDefinition(component) {
1090
- const pins = component.pins;
1091
- const symbolPinDefinitions = [];
1092
- const existingPinIds = Array.from(pins.keys());
1093
- const arrangeProps = component.arrangeProps ?? [];
1094
- const addedPins = [];
1095
- for (const [key, items] of arrangeProps) {
1096
- let useItems;
1097
- if (!Array.isArray(items)) {
1098
- useItems = [items];
1099
- }
1100
- else {
1101
- useItems = [...items];
1102
- }
1103
- useItems.forEach(pinId => {
1104
- if (pinId instanceof NumericValue) {
1105
- const pinIdValue = pinId.toNumber();
1106
- if (existingPinIds.indexOf(pinIdValue) !== -1) {
1107
- const pin = pins.get(pinIdValue);
1108
- symbolPinDefinitions.push({
1109
- side: key,
1110
- pinId: pinIdValue,
1111
- text: pin.name,
1112
- position: pin.position,
1113
- pinType: pin.pinType,
1114
- });
1115
- addedPins.push(pinIdValue);
1116
- }
1117
- }
1118
- });
1119
- }
1120
- const unplacedPins = existingPinIds.filter(pinId => {
1121
- return addedPins.indexOf(pinId) === -1;
1122
- });
1123
- if (unplacedPins.length > 0) {
1124
- component._unplacedPins = unplacedPins;
1125
- console.warn("Warning: There are unplaced pins: " + unplacedPins);
1126
- }
1127
- return symbolPinDefinitions;
1128
- }
1129
920
  export function applyComponentParamsToSymbol(component, symbol) {
1130
921
  const { widthProp = null, heightProp = null } = component;
1131
922
  const newMap = new Map(component.parameters);
@@ -1511,8 +1302,3 @@ export function ExtractDrawingRects(drawing) {
1511
1302
  function isPointOverlap(x, y, other) {
1512
1303
  return (x >= other.x && y >= other.y && x <= (other.x + other.width) && y <= (other.y + other.height));
1513
1304
  }
1514
- var RenderItemType;
1515
- (function (RenderItemType) {
1516
- RenderItemType["Wire"] = "wire";
1517
- RenderItemType["Component"] = "component";
1518
- })(RenderItemType || (RenderItemType = {}));
@@ -1,4 +1,21 @@
1
+ import { ReferenceTypes } from '../globals.js';
1
2
  import { RuntimeExecutionError } from '../utils.js';
3
+ export class CFunctionEntry {
4
+ name;
5
+ execute;
6
+ uniqueId;
7
+ source;
8
+ constructor(name, execute, source, uniqueId) {
9
+ this.name = name;
10
+ this.execute = execute;
11
+ this.uniqueId = uniqueId;
12
+ this.source = source;
13
+ }
14
+ toString() {
15
+ return `[Function: ${this.name}]`;
16
+ }
17
+ }
18
+ ;
2
19
  export class AnyReference {
3
20
  found = false;
4
21
  name;
@@ -6,21 +23,27 @@ export class AnyReference {
6
23
  type;
7
24
  value;
8
25
  parentValue;
26
+ referenceName = 'AnyReference';
9
27
  constructor(refType) {
10
- if (refType.value instanceof AnyReference) {
28
+ if (refType.value instanceof AnyReference
29
+ && refType.value.type !== ReferenceTypes.function) {
11
30
  throw new RuntimeExecutionError("Nested reference types!");
12
31
  }
13
32
  this.found = refType.found;
14
33
  this.name = refType.name;
15
34
  this.trailers = refType.trailers;
16
- this.type = refType.type;
35
+ this.type = refType.type ?? ReferenceTypes.unknown;
17
36
  this.value = refType.value;
18
37
  this.parentValue = refType.parentValue;
19
38
  }
39
+ toString() {
40
+ return `[${this.referenceName} name: ${this.name} trailers:${this.trailers} found: ${this.found}]`;
41
+ }
20
42
  }
21
- export class UndeclaredReference {
43
+ export class UndeclaredReference extends AnyReference {
22
44
  reference;
23
45
  constructor(reference) {
46
+ super(reference);
24
47
  this.reference = reference;
25
48
  }
26
49
  throwMessage() {
@@ -39,9 +62,7 @@ export class UndeclaredReference {
39
62
  }
40
63
  }
41
64
  export class DeclaredReference extends AnyReference {
42
- toString() {
43
- return `[DeclaredReference name: ${this.name} trailers:${this.trailers} found: ${this.found}]`;
44
- }
65
+ referenceName = 'DeclaredReference';
45
66
  toDisplayString() {
46
67
  let returnValue = undefined;
47
68
  if (this.parentValue) {
@@ -172,12 +172,14 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
172
172
  const mergedWireHighlightGroup = canvas.group();
173
173
  const mergedWireGroup = canvas.group();
174
174
  mergedWires.forEach(tmpItem => {
175
- const { segments, intersectPoints, net = null } = tmpItem;
175
+ const { intersectPoints, net = null, lines = null } = tmpItem;
176
176
  let useJunctionColor = ColorScheme.JunctionColor;
177
177
  let useColor = ColorScheme.WireColor;
178
178
  let useLineWidth = defaultWireLineWidth;
179
179
  let displayHighlight = false;
180
180
  let displayHighlightColor = null;
181
+ let displayHighlightOpacity = 0.3;
182
+ let displayHighlightWidth = 5 * MilsToMM;
181
183
  if (net !== null) {
182
184
  useColor = net.color ?? ColorScheme.WireColor;
183
185
  useJunctionColor = net.color ?? ColorScheme.JunctionColor;
@@ -185,25 +187,29 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
185
187
  if (net.highlight !== null) {
186
188
  displayHighlight = true;
187
189
  displayHighlightColor = net.highlight ?? null;
190
+ if (net.highlightOpacity !== undefined) {
191
+ displayHighlightOpacity = net.highlightOpacity;
192
+ }
193
+ if (net.highlightWidth !== undefined) {
194
+ displayHighlightWidth = net.highlightWidth;
195
+ }
188
196
  }
189
197
  }
190
198
  const pathItems = [];
191
- const highlightExtraSize = 5 * MilsToMM;
192
- segments.forEach(segment => {
193
- const pt1 = segment[0];
194
- const pt2 = segment[1];
195
- pathItems.push(...[
196
- 'M', pt1[0], pt1[1],
197
- 'L', pt2[0], pt2[1]
198
- ]);
199
+ const useLines = lines ?? [];
200
+ useLines.forEach(line => {
201
+ line.forEach((point, index) => {
202
+ const commandType = (index === 0) ? 'M' : 'L';
203
+ pathItems.push(...[commandType, point[0], point[1]]);
204
+ });
199
205
  });
200
206
  if (displayHighlight) {
201
207
  mergedWireHighlightGroup.path(pathItems)
202
208
  .stroke({
203
- width: useLineWidth + highlightExtraSize,
209
+ width: useLineWidth + displayHighlightWidth,
204
210
  color: displayHighlightColor,
205
- opacity: 0.3,
206
- linecap: 'square'
211
+ opacity: displayHighlightOpacity,
212
+ linecap: 'butt'
207
213
  })
208
214
  .fill('none');
209
215
  }
@@ -211,11 +217,11 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
211
217
  .stroke({
212
218
  width: useLineWidth,
213
219
  color: useColor,
214
- linecap: 'square'
220
+ linecap: 'butt'
215
221
  })
216
222
  .fill('none');
217
223
  const halfJunctionSize = junctionSize.half();
218
- const highlightJunctionSize = numeric(junctionSize.toNumber() + highlightExtraSize);
224
+ const highlightJunctionSize = numeric(junctionSize.toNumber() + displayHighlightWidth);
219
225
  const tmpHighlightExtraSize = highlightJunctionSize.half();
220
226
  intersectPoints.forEach(point => {
221
227
  const [x, y,] = point;
@@ -2,7 +2,7 @@ import { ClassComponent } from './objects/ClassComponent.js';
2
2
  import { NumberOperator, numeric, NumericValue, ParamDefinition } from './objects/ParamDefinition.js';
3
3
  import { PinDefinition, PinIdType } from './objects/PinDefinition.js';
4
4
  import { PinTypes } from './objects/PinTypes.js';
5
- import { DeclaredReference, UndeclaredReference } from './objects/types.js';
5
+ import { AnyReference, DeclaredReference, UndeclaredReference } from './objects/types.js';
6
6
  import { BlockTypes, ComponentTypes, Delimiter1, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide, ValidPinSides, WireAutoDirection } from './globals.js';
7
7
  import { unwrapValue } from "./utils.js";
8
8
  import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.js';
@@ -376,7 +376,7 @@ export class ParserVisitor extends BaseVisitor {
376
376
  if (ctxNestedProperties) {
377
377
  const nestedKeyValues = this.visitResult(ctxNestedProperties);
378
378
  nestedKeyValues.forEach((value, key) => {
379
- parameters.push(['keyword', key, value]);
379
+ parameters.push(['keyword', key, unwrapValue(value)]);
380
380
  });
381
381
  }
382
382
  else {
@@ -534,36 +534,36 @@ export class ParserVisitor extends BaseVisitor {
534
534
  this.setResult(ctx, result);
535
535
  };
536
536
  visitData_expr_with_assignment = (ctx) => {
537
- let component = null;
538
- let componentCtx = null;
537
+ let dataResult = null;
538
+ let componentCtx;
539
539
  const ctxDataExpr = ctx.data_expr();
540
540
  const ctxAssignmentExpr = ctx.assignment_expr();
541
541
  if (ctxDataExpr) {
542
- component = this.visitResult(ctxDataExpr);
543
- component = unwrapValue(component);
542
+ dataResult = this.visitResult(ctxDataExpr);
544
543
  componentCtx = ctxDataExpr;
545
- if (component === null || component === undefined) {
546
- this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
547
- }
548
544
  }
549
545
  else if (ctxAssignmentExpr) {
550
- component = this.visitResult(ctxAssignmentExpr);
546
+ dataResult = this.visitResult(ctxAssignmentExpr);
551
547
  componentCtx = ctxAssignmentExpr;
552
548
  }
553
- if (component instanceof ClassComponent
554
- && component.copyProp) {
555
- component = this.getExecutor().copyComponent(component);
556
- }
557
- if (component instanceof UndeclaredReference) {
558
- const { reference: { trailers = [], parentValue = null } } = component;
549
+ if (dataResult instanceof AnyReference) {
550
+ const { trailers = [], parentValue = null } = dataResult;
559
551
  if (parentValue instanceof ClassComponent
560
552
  && trailers.length > 0
561
553
  && trailers[0] === ModuleContainsKeyword) {
562
- component = parentValue;
563
- this.placeModuleContains(component);
554
+ dataResult = parentValue;
555
+ this.placeModuleContains(dataResult);
564
556
  }
565
557
  }
566
- if (component && component instanceof ClassComponent) {
558
+ dataResult = unwrapValue(dataResult);
559
+ if (dataResult === null || dataResult === undefined) {
560
+ this.throwWithContext(componentCtx, "Could not find component: " + componentCtx.getText());
561
+ }
562
+ if (dataResult instanceof ClassComponent
563
+ && dataResult.copyProp) {
564
+ dataResult = this.getExecutor().copyComponent(dataResult);
565
+ }
566
+ if (dataResult && dataResult instanceof ClassComponent) {
567
567
  const modifiers = ctx.component_modifier_expr();
568
568
  modifiers.forEach(modifier => {
569
569
  const modifierText = modifier.ID(0).getText();
@@ -580,23 +580,23 @@ export class ParserVisitor extends BaseVisitor {
580
580
  if (modifierText === ParamKeys.flip) {
581
581
  const flipValue = result;
582
582
  if (flipValue.indexOf('x') !== -1) {
583
- component.setParam(ParamKeys.flipX, 1);
583
+ dataResult.setParam(ParamKeys.flipX, 1);
584
584
  shouldIgnoreWireOrientation = true;
585
585
  }
586
586
  if (flipValue.indexOf('y') !== -1) {
587
- component.setParam(ParamKeys.flipY, 1);
587
+ dataResult.setParam(ParamKeys.flipY, 1);
588
588
  shouldIgnoreWireOrientation = true;
589
589
  }
590
590
  }
591
591
  else if (modifierText === ParamKeys.angle) {
592
- component.setParam(ParamKeys.angle, result);
592
+ dataResult.setParam(ParamKeys.angle, result);
593
593
  shouldIgnoreWireOrientation = true;
594
594
  }
595
595
  else if (modifierText === 'anchor') {
596
- component.setParam('anchor', result);
596
+ dataResult.setParam('anchor', result);
597
597
  }
598
598
  if (shouldIgnoreWireOrientation) {
599
- component.useWireOrientationAngle = false;
599
+ dataResult.useWireOrientationAngle = false;
600
600
  }
601
601
  });
602
602
  }
@@ -606,15 +606,15 @@ export class ParserVisitor extends BaseVisitor {
606
606
  pinValue = this.visitResult(ctxPinSelectExpr);
607
607
  }
608
608
  else {
609
- if (component instanceof ClassComponent) {
610
- pinValue = component.getDefaultPin();
609
+ if (dataResult instanceof ClassComponent) {
610
+ pinValue = dataResult.getDefaultPin();
611
611
  }
612
612
  else {
613
- const undeclaredRef = component;
613
+ const undeclaredRef = dataResult;
614
614
  this.throwWithContext(componentCtx, 'Invalid component: ' + undeclaredRef.reference.name);
615
615
  }
616
616
  }
617
- this.setResult(ctx, [component, pinValue]);
617
+ this.setResult(ctx, [dataResult, pinValue]);
618
618
  };
619
619
  expandModuleContains(component, netNamespace) {
620
620
  this.getExecutor().log('expanding module `contains`');
@@ -794,8 +794,8 @@ export class ParserVisitor extends BaseVisitor {
794
794
  this.setResult(ctx, result);
795
795
  };
796
796
  visitAdditionExpr = (ctx) => {
797
- const value1 = this.resolveDataExpr(ctx.data_expr(0));
798
- const value2 = this.resolveDataExpr(ctx.data_expr(1));
797
+ const value1 = unwrapValue(this.resolveDataExpr(ctx.data_expr(0)));
798
+ const value2 = unwrapValue(this.resolveDataExpr(ctx.data_expr(1)));
799
799
  if (ctx.Addition() && (typeof value1 === 'string' || typeof value2 === 'string')) {
800
800
  let tmpValue1 = value1;
801
801
  if (value1 instanceof NumericValue) {
@@ -824,6 +824,8 @@ export class ParserVisitor extends BaseVisitor {
824
824
  };
825
825
  visitFunction_def_expr = (ctx) => {
826
826
  const functionName = ctx.ID().getText();
827
+ const uniqueFunctionID = '__._' + ctx.start.line + '_'
828
+ + ctx.start.column + '_' + functionName + '_' + ctx.getText();
827
829
  let funcDefinedParameters = [];
828
830
  const ctxFunctionArgsExpr = ctx.function_args_expr();
829
831
  if (ctxFunctionArgsExpr) {
@@ -845,7 +847,7 @@ export class ParserVisitor extends BaseVisitor {
845
847
  nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
846
848
  return [lastExecution, returnValue];
847
849
  };
848
- this.getExecutor().createFunction(functionName, __runFunc);
850
+ this.getExecutor().createFunction(functionName, __runFunc, ctx, uniqueFunctionID);
849
851
  };
850
852
  visitPin_select_expr2 = (ctx) => {
851
853
  const ctxStringValue = ctx.STRING_VALUE();
@@ -1,4 +1,4 @@
1
- import { Array_exprContext, ArrayExprContext, Assignment_exprContext, Atom_exprContext, ExpressionContext, Flow_expressionsContext, Function_args_exprContext, Function_call_exprContext, Function_exprContext, Function_return_exprContext, FunctionCallExprContext, Import_exprContext, Operator_assignment_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, Value_exprContext, ValueAtomExprContext } from "./antlr/CircuitScriptParser.js";
1
+ import { Array_exprContext, ArrayExprContext, ArrayIndexExprContext, Assignment_exprContext, Atom_exprContext, ExpressionContext, Flow_expressionsContext, Function_args_exprContext, Function_call_exprContext, Function_exprContext, Function_return_exprContext, FunctionCallExprContext, Import_exprContext, Operator_assignment_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, Trailer_expr2Context, Value_exprContext, ValueAtomExprContext } from "./antlr/CircuitScriptParser.js";
2
2
  import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor.js";
3
3
  import { ExecutionContext } from "./execute.js";
4
4
  import { Logger } from "./logger.js";
@@ -46,6 +46,7 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
46
46
  visitAssignment_expr: (ctx: Assignment_exprContext) => void;
47
47
  visitOperator_assignment_expr: (ctx: Operator_assignment_exprContext) => void;
48
48
  private getReference;
49
+ visitTrailer_expr2: (ctx: Trailer_expr2Context) => void;
49
50
  visitAtom_expr: (ctx: Atom_exprContext) => void;
50
51
  visitFunctionCallExpr: (ctx: FunctionCallExprContext) => void;
51
52
  visitFunction_call_expr: (ctx: Function_call_exprContext) => void;
@@ -59,6 +60,7 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
59
60
  visitFlow_expressions: (ctx: Flow_expressionsContext) => void;
60
61
  visitArray_expr: (ctx: Array_exprContext) => void;
61
62
  visitArrayExpr: (ctx: ArrayExprContext) => void;
63
+ visitArrayIndexExpr: (ctx: ArrayIndexExprContext) => void;
62
64
  protected setResult(ctx: ParserRuleContext, value: any): void;
63
65
  protected getResult(ctx: ParserRuleContext): any;
64
66
  visitResult(ctx: ParserRuleContext): any;