circuitscript 0.5.1 → 0.5.3

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.
@@ -9,6 +9,8 @@ const NumericValue_js_1 = require("./objects/NumericValue.js");
9
9
  const types_js_1 = require("./objects/types.js");
10
10
  const utils_js_1 = require("./utils.js");
11
11
  const globals_js_1 = require("./globals.js");
12
+ const ClassComponent_js_1 = require("./objects/ClassComponent.js");
13
+ const Net_js_1 = require("./objects/Net.js");
12
14
  const builtInMethods = [
13
15
  ['enumerate', enumerate],
14
16
  ['toMils', toMils],
@@ -159,6 +161,12 @@ function toString(obj) {
159
161
  else if (obj instanceof types_js_1.ImportedLibrary) {
160
162
  return `[library: ${obj.libraryName}]`;
161
163
  }
164
+ else if (obj instanceof ClassComponent_js_1.ClassComponent) {
165
+ return `[component: ${obj.instanceName}]`;
166
+ }
167
+ else if (obj instanceof Net_js_1.Net) {
168
+ return `[net: ${obj.toString()}]`;
169
+ }
162
170
  else {
163
171
  if (obj === undefined) {
164
172
  return 'undefined';
@@ -160,6 +160,7 @@ class ExecutionContext {
160
160
  const defaultPin = new PinDefinition_js_1.PinId(1);
161
161
  this.scope.setNet(component, defaultPin, tmpNet);
162
162
  this.log('set net', netName, 'component', component, defaultPin);
163
+ component.setParam('net', tmpNet);
163
164
  }
164
165
  this.scope.instances.set(instanceName, component);
165
166
  const pinsOutput = pins.map((pin) => {
@@ -729,31 +730,16 @@ class ExecutionContext {
729
730
  let rootValue;
730
731
  let useValue = item;
731
732
  if (trailers.length > 0) {
732
- rootValue = useValue;
733
- const trailersPath = trailers.join(".");
734
- switch (type) {
735
- case globals_js_1.ReferenceTypes.variable:
736
- useValue = rootValue;
737
- trailers.forEach(trailerPath => {
738
- useValue = useValue[trailerPath];
739
- });
740
- break;
741
- case globals_js_1.ReferenceTypes.instance: {
742
- const tmpComponent = rootValue;
743
- if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net) {
744
- const usedNet = this.scope.getNet(tmpComponent, new PinDefinition_js_1.PinId(1));
745
- if (usedNet) {
746
- const trailerValue = trailers.join(".");
747
- useValue = usedNet.params.get(trailerValue) ?? null;
748
- }
749
- }
750
- else {
751
- useValue = rootValue
752
- .parameters.get(trailersPath);
753
- }
754
- break;
733
+ rootValue = item;
734
+ useValue = item;
735
+ for (let i = 0; i < trailers.length; i++) {
736
+ if (useValue instanceof ClassComponent_js_1.ClassComponent) {
737
+ useValue = useValue.parameters.get(trailers[i]);
755
738
  }
756
- case globals_js_1.ReferenceTypes.library: {
739
+ else if (useValue instanceof Net_js_1.Net) {
740
+ useValue = useValue.params.get(trailers[i]);
741
+ }
742
+ else if (useValue instanceof types_js_1.ImportedLibrary) {
757
743
  const funcName = trailers[0];
758
744
  const library = rootValue;
759
745
  const functionPath = `${library.libraryNamespace}${funcName}`;
@@ -768,7 +754,9 @@ class ExecutionContext {
768
754
  value: foundFunc,
769
755
  });
770
756
  }
771
- break;
757
+ }
758
+ else {
759
+ useValue = useValue[trailers[i]];
772
760
  }
773
761
  }
774
762
  }
@@ -1016,52 +1004,6 @@ class ExecutionContext {
1016
1004
  return commands;
1017
1005
  });
1018
1006
  }
1019
- setProperty(nameWithProp, value) {
1020
- this.log('set property', nameWithProp, 'value', value);
1021
- let idName;
1022
- let paramName;
1023
- let useActive = false;
1024
- if (nameWithProp.startsWith('..')) {
1025
- useActive = true;
1026
- paramName = nameWithProp.substring(2);
1027
- }
1028
- else {
1029
- const parts = nameWithProp.split(".");
1030
- idName = parts[0];
1031
- paramName = parts[1];
1032
- }
1033
- if (useActive && this.scope.currentFrameId !== -1) {
1034
- this.scope.frames[this.scope.currentFrameId - 1]
1035
- .parameters.set(paramName, value);
1036
- }
1037
- else {
1038
- idName = this.scope.currentComponent.instanceName;
1039
- if (this.scope.instances.has(idName)) {
1040
- const component = this.scope.instances.get(idName);
1041
- component.setParam(paramName, value);
1042
- const unitModifiers = [
1043
- globals_js_1.ParamKeys.angle,
1044
- globals_js_1.ParamKeys.flip,
1045
- globals_js_1.ParamKeys.flipX,
1046
- globals_js_1.ParamKeys.flipY,
1047
- ];
1048
- if (unitModifiers.indexOf(paramName) !== -1) {
1049
- if (paramName === globals_js_1.ParamKeys.flipX || paramName == globals_js_1.ParamKeys.flipY) {
1050
- if (typeof value === "boolean") {
1051
- value = value ? (0, NumericValue_js_2.numeric)(1) : (0, NumericValue_js_2.numeric)(0);
1052
- }
1053
- }
1054
- component.getUnit().setParam(paramName, value);
1055
- }
1056
- }
1057
- else if (this.scope.variables.has(idName)) {
1058
- throw "Not implemented yet!";
1059
- }
1060
- else {
1061
- throw "Unknown identifier: " + idName;
1062
- }
1063
- }
1064
- }
1065
1007
  applyComponentAngleFromWire(component, pin, opposite = false) {
1066
1008
  const targetUnit = component.getUnitForPin(pin);
1067
1009
  if (this.componentAngleFollowsWire
@@ -25,6 +25,8 @@ var FrameParamKeys;
25
25
  FrameParamKeys["Height"] = "height";
26
26
  FrameParamKeys["PaperSize"] = "paper_size";
27
27
  FrameParamKeys["SheetType"] = "sheet_type";
28
+ FrameParamKeys["GridStyle"] = "grid_style";
29
+ FrameParamKeys["GridColor"] = "grid_color";
28
30
  FrameParamKeys["TitleAlign"] = "title_align";
29
31
  FrameParamKeys["HorizontalAlign"] = "align";
30
32
  FrameParamKeys["VerticalAlign"] = "valign";
@@ -161,8 +161,9 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
161
161
  if (errors.length === 0 && throwError === undefined) {
162
162
  const { frameComponent } = visitor.applySheetFrameComponent();
163
163
  const { sequence, nets } = visitor.getGraph();
164
+ const documentVariable = visitor.getScope()
165
+ .variables.get(globals_js_1.GlobalDocumentName);
164
166
  if (enableBom && bomOutputPath) {
165
- const documentVariable = visitor.getScope().variables.get('document');
166
167
  const bomConfig = documentVariable.bom;
167
168
  const bomData = (0, BomGeneration_js_1.generateBom)(bomConfig, visitor.getScope().getInstances());
168
169
  const bomCsvOutput = (0, BomGeneration_js_1.generateBomCSV)(bomData);
@@ -220,7 +221,7 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
220
221
  const renderLogger = new logger_js_1.Logger();
221
222
  let svgCanvas;
222
223
  try {
223
- svgCanvas = (0, render_js_1.renderSheetsToSVG)(sheetFrames, renderLogger);
224
+ svgCanvas = (0, render_js_1.renderSheetsToSVG)(sheetFrames, renderLogger, documentVariable);
224
225
  }
225
226
  catch (err) {
226
227
  throw new utils_js_1.RenderError(`Error during SVG generation: ${err}`, 'svg_generation');
@@ -25,7 +25,7 @@ function createSvgCanvas() {
25
25
  (0, sizing_js_1.applyFontsToSVG)(canvas);
26
26
  return canvas;
27
27
  }
28
- function renderSheetsToSVG(sheetFrames, logger) {
28
+ function renderSheetsToSVG(sheetFrames, logger, documentVariable) {
29
29
  const canvas = createSvgCanvas();
30
30
  sheetFrames.forEach((sheet, index) => {
31
31
  const sheetGroup = canvas.group();
@@ -82,7 +82,13 @@ function renderSheetsToSVG(sheetFrames, logger) {
82
82
  logger.add('sheet contents offset: ' + xOffset + ' ' + yOffset);
83
83
  logger.add('generating svg children in sheet');
84
84
  const sheetElements = sheetGroup.group().addClass('sheet-elements');
85
- generateSVGChild(sheetElements, components, wires, junctions, mergedWires, allFrames, textObjects, gridBounds, extendGrid, logger);
85
+ const gridProperties = {
86
+ gridBounds,
87
+ extendGrid,
88
+ style: documentVariable[Frame_js_1.FrameParamKeys.GridStyle],
89
+ color: documentVariable[Frame_js_1.FrameParamKeys.GridColor],
90
+ };
91
+ generateSVGChild(sheetElements, components, wires, junctions, mergedWires, allFrames, textObjects, gridProperties, logger);
86
92
  sheetElements.translate(xOffset, yOffset);
87
93
  sheetGroup.translate(0, sheetYOffset.toNumber());
88
94
  });
@@ -129,14 +135,15 @@ function generatePdfOutput(doc, canvas, sheetSize, sheetSizeDefined, zoomScale =
129
135
  });
130
136
  }
131
137
  exports.generatePdfOutput = generatePdfOutput;
132
- function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects, gridBounds, extendGrid, logger) {
138
+ function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects, gridProperties, logger) {
133
139
  const displayWireId = false;
134
- if (gridBounds === null) {
140
+ if (gridProperties.gridBounds === null) {
135
141
  logger.add('get grid bounds');
136
- gridBounds = (0, layout_js_1.getBounds)(components, wires, junctions, frameObjects);
142
+ gridProperties.gridBounds = (0, layout_js_1.getBounds)(components, wires, junctions, frameObjects);
137
143
  }
144
+ const { gridBounds } = gridProperties;
138
145
  logger.add('grid bounds', gridBounds.xmin, gridBounds.ymin, gridBounds.xmax, gridBounds.ymax);
139
- drawGrid(canvas.group().translate(0, 0), gridBounds, extendGrid, logger);
146
+ drawGrid(canvas.group().translate(0, 0), gridProperties, logger);
140
147
  components.forEach(item => {
141
148
  const { x, y, width, height } = item;
142
149
  const symbolGroup = canvas.group();
@@ -294,7 +301,8 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
294
301
  .translate(-originSize / 2, -originSize / 2)
295
302
  .stroke('none').fill('red');
296
303
  }
297
- function drawGrid(group, canvasSize, extendGrid, logger) {
304
+ function drawGrid(group, gridProperties, logger) {
305
+ const { gridBounds: canvasSize, extendGrid, style: gridStyle = "dots", color: gridColor = "#000" } = gridProperties;
298
306
  const gridSize = globals_js_1.defaultGridSizeUnits;
299
307
  const { xmin, ymin, xmax, ymax } = canvasSize;
300
308
  const extraValue = extendGrid ? 1 : 0;
@@ -312,6 +320,7 @@ function drawGrid(group, canvasSize, extendGrid, logger) {
312
320
  globals_js_1.RenderFlags.ShowGridOrigin && group.circle(originSize)
313
321
  .translate(-originSize / 2, -originSize / 2)
314
322
  .stroke('none').fill('blue');
323
+ const useGridColor = gridStyle !== "none" ? gridColor : "rgba(0,0,0,0)";
315
324
  const lines = [];
316
325
  const smallOffset = (0, helpers_js_1.milsToMM)(3);
317
326
  const startY = gridStartY.sub(smallOffset.half());
@@ -329,7 +338,7 @@ function drawGrid(group, canvasSize, extendGrid, logger) {
329
338
  })
330
339
  .stroke({
331
340
  width: strokeSize.toNumber(),
332
- color: '#000'
341
+ color: useGridColor
333
342
  });
334
343
  }
335
344
  function drawSheetFrameBorder(frameGroup, frame) {
@@ -125,6 +125,8 @@ class SemanticTokensVisitor extends BaseVisitor_js_1.BaseVisitor {
125
125
  });
126
126
  }
127
127
  };
128
+ this.visitTrailer = (ctx) => {
129
+ };
128
130
  this.lexer = lexer;
129
131
  this.script = script;
130
132
  }
@@ -106,6 +106,8 @@ class SymbolValidatorVisitor extends BaseVisitor_js_1.BaseVisitor {
106
106
  this.addSymbolVariable(ctxID.getSymbol(), ctxID.getText(), null);
107
107
  }
108
108
  };
109
+ this.visitTrailer = (ctx) => {
110
+ };
109
111
  }
110
112
  addSymbolVariable(token, name, value, executor = null) {
111
113
  const useExecutor = executor === null ? this.getExecutor() : executor;
@@ -809,8 +809,19 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
809
809
  };
810
810
  this.visitDouble_dot_property_set_expr = (ctx) => {
811
811
  const result = this.visitResult(ctx.data_expr());
812
- const propertyName = ctx.ID().getText();
813
- this.getExecutor().setProperty('..' + propertyName, result);
812
+ const scope = this.getScope();
813
+ const useObject = scope.currentFrameId !== -1 ?
814
+ scope.frames[scope.currentFrameId - 1] : scope.currentComponent;
815
+ const lastReference = new types_js_1.AnyReference({
816
+ found: true,
817
+ value: useObject,
818
+ type: globals_js_1.ReferenceTypes.instance,
819
+ trailerIndex: 0,
820
+ });
821
+ const firstId = ctx.ID().getText();
822
+ const referenceWithFirstID = this.getExecutor().resolveTrailers(null, lastReference.value, [firstId]);
823
+ const useReference = this.resolveTrailersForReference(referenceWithFirstID, null, ctx);
824
+ this.assignValueToReference([], useReference, ctx, result);
814
825
  };
815
826
  this.visitExpressions_block = (ctx) => {
816
827
  this.runExpressions(this.getExecutor(), ctx.expression());
@@ -4,20 +4,21 @@ import { CircuitScriptParserVisitor } from "./antlr/CircuitScriptParserVisitor.j
4
4
  import { ExecutionContext } from "./execute.js";
5
5
  import { Logger } from "./logger.js";
6
6
  import { ClassComponent } from "./objects/ClassComponent.js";
7
- import { NumberOperator, NumericValue, resolveToNumericValue } from "./objects/NumericValue.js";
7
+ import { Net } from "./objects/Net.js";
8
+ import { NumberOperator, numeric, NumericValue, resolveToNumericValue } from "./objects/NumericValue.js";
8
9
  import { PercentageValue } from "./objects/PercentageValue.js";
9
10
  import { Direction, AnyReference, UndeclaredReference, ImportedLibrary, ImportFunctionHandling as ImportFunctionHandling } from "./objects/types.js";
10
- import { BaseNamespace, ComponentTypes, DoubleDelimiter1, GlobalDocumentName, PinTypesList, ReferenceTypes, TrailerArrayIndex } from './globals.js';
11
+ import { BaseNamespace, DoubleDelimiter1, GlobalDocumentName, ParamKeys, PinTypesList, ReferenceTypes, TrailerArrayIndex } from './globals.js';
11
12
  import { isReference, unwrapValue as unwrapValue } from "./utils.js";
12
13
  import { linkBuiltInMethods } from './builtinMethods.js';
13
14
  import { RuntimeExecutionError, throwWithContext } from './utils.js';
14
15
  import { SequenceAction } from './objects/ExecutionScope.js';
15
- import { PinId } from './objects/PinDefinition.js';
16
16
  import { computeContentHash } from './cache/hash.js';
17
17
  import { readCache, writeCache } from './cache/storage.js';
18
18
  import { serializeLibraryScope } from './cache/serializer.js';
19
19
  import { deserializeLibraryScope } from './cache/deserializer.js';
20
20
  import { resolveAllImportFilepaths } from './importResolver.js';
21
+ import { Frame } from './objects/Frame.js';
21
22
  export class BaseVisitor extends CircuitScriptParserVisitor {
22
23
  startingContext;
23
24
  executionStack;
@@ -215,13 +216,24 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
215
216
  currentReference = executor.resolveVariable(this.executionStack, atomId);
216
217
  this.log('reference:', currentReference.name, 'found:', currentReference.found);
217
218
  }
218
- if (currentReference !== undefined && currentReference.found) {
219
+ currentReference = this.resolveTrailersForReference(currentReference, passedNetNamespace, ctx);
220
+ let resultValue = currentReference;
221
+ if (!keepReference) {
222
+ if (currentReference.type !== ReferenceTypes.pinType) {
223
+ resultValue = unwrapValue(resultValue);
224
+ }
225
+ }
226
+ this.setResult(ctx, resultValue);
227
+ this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
228
+ };
229
+ resolveTrailersForReference(reference, passedNetNamespace, ctx) {
230
+ if (reference !== undefined && reference.found) {
219
231
  ctx.trailer().forEach(ctxTrailer => {
220
232
  this.setResult(ctxTrailer, {
221
- reference: currentReference,
233
+ reference: reference,
222
234
  netNamespace: passedNetNamespace
223
235
  });
224
- currentReference = this.visitResult(ctxTrailer);
236
+ reference = this.visitResult(ctxTrailer);
225
237
  });
226
238
  }
227
239
  else {
@@ -229,15 +241,8 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
229
241
  this.throwWithContext(ctx, `Function not found: ${ctx.getText()}`);
230
242
  }
231
243
  }
232
- let resultValue = currentReference;
233
- if (!keepReference) {
234
- if (currentReference.type !== ReferenceTypes.pinType) {
235
- resultValue = unwrapValue(resultValue);
236
- }
237
- }
238
- this.setResult(ctx, resultValue);
239
- this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
240
- };
244
+ return reference;
245
+ }
241
246
  visitTrailer = (ctx) => {
242
247
  const { reference, netNamespace } = this.getResult(ctx);
243
248
  const ctxLParam = ctx.LParen();
@@ -276,68 +281,18 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
276
281
  this.setResult(ctx, nextReference);
277
282
  };
278
283
  visitAssignment_expr = (ctx) => {
284
+ const lhsCtx = ctx.callable_expr();
285
+ this.setResult(lhsCtx, { keepReference: true });
286
+ const leftSideReference = this.visitResult(lhsCtx);
279
287
  if (ctx.Assign()) {
280
- const lhsCtx = ctx.callable_expr();
281
- this.setResult(lhsCtx, { keepReference: true });
282
- const leftSideReference = this.visitResult(lhsCtx);
283
288
  const rhsCtx = ctx.data_expr();
284
289
  const rhsCtxResult = this.visitResult(rhsCtx);
290
+ const sequenceParts = [];
285
291
  if (isReference(rhsCtxResult) && !rhsCtxResult.found) {
286
292
  this.throwWithContext(rhsCtx, rhsCtx.getText() + ' is not defined');
287
293
  }
288
294
  const rhsValue = unwrapValue(rhsCtxResult);
289
- const { trailers = [] } = leftSideReference;
290
- const sequenceParts = [];
291
- if (trailers.length === 0) {
292
- this.getScope().setVariable(leftSideReference.name, rhsValue);
293
- let itemType = '';
294
- if (rhsValue instanceof ClassComponent) {
295
- itemType = ReferenceTypes.instance;
296
- this.log2(`assigned '${leftSideReference.name}' to ClassComponent`);
297
- }
298
- else {
299
- itemType = ReferenceTypes.variable;
300
- this.getScope().setVariable(leftSideReference.name, rhsValue);
301
- this.log2(`assigned variable ${leftSideReference.name} to ${rhsValue}`);
302
- }
303
- sequenceParts.push(...[itemType, leftSideReference.name, rhsValue]);
304
- }
305
- else {
306
- if (leftSideReference.rootValue instanceof ClassComponent) {
307
- this.setInstanceParam(leftSideReference.rootValue, trailers, rhsValue);
308
- this.log2(`assigned component param ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
309
- sequenceParts.push(...['instance', [leftSideReference.rootValue, trailers], rhsValue]);
310
- if (leftSideReference.rootValue.typeProp === ComponentTypes.net) {
311
- const net = this.getScope().getNet(leftSideReference.rootValue, new PinId(1));
312
- if (net) {
313
- const trailerValue = trailers.join(".");
314
- net.params.set(trailerValue, rhsValue);
315
- }
316
- }
317
- }
318
- else if (leftSideReference.rootValue instanceof Object) {
319
- if (Array.isArray(trailers[0]) && trailers[0][0] === TrailerArrayIndex) {
320
- if (Array.isArray(leftSideReference.rootValue)) {
321
- const arrayIndexValue = trailers[0][1];
322
- leftSideReference.rootValue[arrayIndexValue] = rhsValue;
323
- this.log2(`assigned array index ${leftSideReference.rootValue} index: ${arrayIndexValue} value: ${rhsValue}`);
324
- }
325
- else {
326
- this.throwWithContext(lhsCtx, "Invalid array");
327
- }
328
- }
329
- else {
330
- let expandedValue = leftSideReference.rootValue;
331
- trailers.slice(0, -1).forEach(trailer => {
332
- expandedValue = expandedValue[trailer];
333
- });
334
- const lastTrailer = trailers.slice(-1)[0];
335
- expandedValue[lastTrailer] = rhsValue;
336
- this.log2(`assigned object ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
337
- }
338
- sequenceParts.push(...['variable', [leftSideReference.rootValue, trailers], rhsValue]);
339
- }
340
- }
295
+ this.assignValueToReference(sequenceParts, leftSideReference, lhsCtx, rhsValue);
341
296
  if (sequenceParts.length > 0) {
342
297
  this.getScope().sequence.push([
343
298
  SequenceAction.Assign, ...sequenceParts
@@ -346,24 +301,21 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
346
301
  this.setResult(ctx, rhsValue);
347
302
  }
348
303
  else {
349
- const ctxCallable = ctx.callable_expr();
350
- this.setResult(ctxCallable, { keepReference: true });
351
- const reference = this.visitResult(ctx.callable_expr());
352
304
  const value = this.visitResult(ctx.data_expr());
353
- if (!reference.found) {
354
- this.throwWithContext(ctx, 'Undefined reference: ' + reference.name);
305
+ if (!leftSideReference.found) {
306
+ this.throwWithContext(ctx, 'Undefined reference: ' + leftSideReference.name);
355
307
  }
356
- const trailers = reference.trailers ?? [];
308
+ const trailers = leftSideReference.trailers ?? [];
357
309
  let currentValue = null;
358
310
  if (trailers.length === 0) {
359
- currentValue = this.getExecutor().scope.variables.get(reference.name);
311
+ currentValue = this.getExecutor().scope.variables.get(leftSideReference.name);
360
312
  }
361
313
  else {
362
- if (reference.value instanceof ClassComponent) {
363
- currentValue = this.getInstanceParam(reference.value, trailers);
314
+ if (leftSideReference.value instanceof ClassComponent) {
315
+ currentValue = this.getInstanceParam(leftSideReference.value, trailers);
364
316
  }
365
- else if (reference.value instanceof Object) {
366
- currentValue = reference.value[trailers.join('.')];
317
+ else if (leftSideReference.value instanceof Object) {
318
+ currentValue = leftSideReference.value[trailers.join('.')];
367
319
  }
368
320
  }
369
321
  if (currentValue === null) {
@@ -389,20 +341,59 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
389
341
  else {
390
342
  this.throwWithContext(ctx, 'Operator assignment failed: could not perform operator');
391
343
  }
392
- if (trailers.length === 0) {
393
- this.getExecutor().scope.setVariable(reference.name, newValue);
344
+ this.assignValueToReference([], leftSideReference, lhsCtx, newValue);
345
+ this.setResult(ctx, newValue);
346
+ }
347
+ };
348
+ assignValueToReference(sequenceParts, leftSideReference, lhsCtx, rhsValue) {
349
+ const { trailers = [] } = leftSideReference;
350
+ if (trailers.length === 0) {
351
+ this.getScope().setVariable(leftSideReference.name, rhsValue);
352
+ let itemType = '';
353
+ if (rhsValue instanceof ClassComponent) {
354
+ itemType = ReferenceTypes.instance;
355
+ this.log2(`assigned '${leftSideReference.name}' to ClassComponent`);
394
356
  }
395
357
  else {
396
- if (reference.value instanceof ClassComponent) {
397
- this.setInstanceParam(reference.value, trailers, newValue);
358
+ itemType = ReferenceTypes.variable;
359
+ this.getScope().setVariable(leftSideReference.name, rhsValue);
360
+ this.log2(`assigned variable ${leftSideReference.name} to ${rhsValue}`);
361
+ }
362
+ sequenceParts.push(...[itemType, leftSideReference.name, rhsValue]);
363
+ }
364
+ else {
365
+ if (leftSideReference.rootValue instanceof ClassComponent) {
366
+ this.setInstanceParam(leftSideReference.rootValue, trailers, rhsValue);
367
+ this.log2(`assigned component param ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
368
+ sequenceParts.push(...['instance', [leftSideReference.rootValue, trailers], rhsValue]);
369
+ }
370
+ else if (leftSideReference.rootValue instanceof Frame) {
371
+ leftSideReference.rootValue.parameters.set(trailers[0], rhsValue);
372
+ }
373
+ else if (leftSideReference.rootValue instanceof Object) {
374
+ if (Array.isArray(trailers[0]) && trailers[0][0] === TrailerArrayIndex) {
375
+ if (Array.isArray(leftSideReference.rootValue)) {
376
+ const arrayIndexValue = trailers[0][1];
377
+ leftSideReference.rootValue[arrayIndexValue] = rhsValue;
378
+ this.log2(`assigned array index ${leftSideReference.rootValue} index: ${arrayIndexValue} value: ${rhsValue}`);
379
+ }
380
+ else {
381
+ this.throwWithContext(lhsCtx, "Invalid array");
382
+ }
398
383
  }
399
- else if (reference.value instanceof Object) {
400
- reference.value[trailers.join('.')] = newValue;
384
+ else {
385
+ let expandedValue = leftSideReference.rootValue;
386
+ trailers.slice(0, -1).forEach(trailer => {
387
+ expandedValue = expandedValue[trailer];
388
+ });
389
+ const lastTrailer = trailers.slice(-1)[0];
390
+ expandedValue[lastTrailer] = rhsValue;
391
+ this.log2(`assigned object ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
401
392
  }
393
+ sequenceParts.push(...['variable', [leftSideReference.rootValue, trailers], rhsValue]);
402
394
  }
403
- this.setResult(ctx, newValue);
404
395
  }
405
- };
396
+ }
406
397
  getReference(ctx) {
407
398
  const atomStr = ctx.getText();
408
399
  if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
@@ -417,65 +408,6 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
417
408
  }
418
409
  return reference;
419
410
  }
420
- visitTrailer_expr2 = (ctx) => {
421
- const reference = this.getResult(ctx);
422
- const ctxID = ctx.ID();
423
- const ctxDataExpr = ctx.data_expr();
424
- const useValue = reference.value;
425
- let nextReference;
426
- if (ctxID) {
427
- reference.trailers.push(ctxID.getText());
428
- const useRootValue = reference.rootValue ?? reference.value;
429
- const useTrailerIndex = reference.trailerIndex ?? 0;
430
- nextReference = this.getExecutor().resolveTrailers(reference.type, useRootValue, reference.trailers);
431
- nextReference.name =
432
- [reference.name,
433
- ...reference.trailers.slice(useTrailerIndex)].join('.');
434
- }
435
- else if (ctxDataExpr) {
436
- const arrayIndex = this.visitResult(ctxDataExpr);
437
- if (arrayIndex instanceof NumericValue) {
438
- const arrayIndexValue = arrayIndex.toNumber();
439
- const foundValue = useValue[arrayIndexValue];
440
- const refType = foundValue instanceof ClassComponent
441
- ? ReferenceTypes.instance : ReferenceTypes.variable;
442
- nextReference = new AnyReference({
443
- found: true,
444
- type: refType,
445
- value: foundValue,
446
- trailers: [[TrailerArrayIndex, arrayIndexValue]],
447
- rootValue: useValue
448
- });
449
- }
450
- }
451
- this.setResult(ctx, nextReference);
452
- };
453
- visitAtom_expr = (ctx) => {
454
- const executor = this.getExecutor();
455
- const firstId = ctx.ID(0);
456
- const atomId = firstId.getText();
457
- let currentReference;
458
- if (PinTypesList.indexOf(atomId) !== -1) {
459
- currentReference = new AnyReference({
460
- found: true,
461
- value: atomId,
462
- type: ReferenceTypes.pinType,
463
- });
464
- }
465
- else {
466
- this.log('resolve variable ctx: ' + ctx.getText(), 'atomId', atomId);
467
- currentReference = executor.resolveVariable(this.executionStack, atomId);
468
- this.log('reference:', currentReference.name, 'found:', currentReference.found);
469
- }
470
- if (currentReference !== undefined && currentReference.found) {
471
- ctx.trailer_expr2().forEach(ctxTrailer => {
472
- this.setResult(ctxTrailer, currentReference);
473
- currentReference = this.visitResult(ctxTrailer);
474
- });
475
- }
476
- this.setResult(ctx, currentReference);
477
- this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
478
- };
479
411
  handleFunctionCall(currentReference, passedNetNamespace, ctx) {
480
412
  const executor = this.getExecutor();
481
413
  let parameters = [];
@@ -1049,9 +981,40 @@ export class BaseVisitor extends CircuitScriptParserVisitor {
1049
981
  return result;
1050
982
  }
1051
983
  setInstanceParam(object, trailers, value) {
1052
- const paramName = trailers[0];
1053
- object.setParam(paramName, value);
1054
- this.log2(`set instance ${object.instanceName} param ${paramName} to ${value}`);
984
+ if (trailers.length === 1) {
985
+ const paramName = trailers[0];
986
+ if (paramName === ParamKeys.flipX || paramName == ParamKeys.flipY) {
987
+ if (typeof value === "boolean") {
988
+ value = value ? numeric(1) : numeric(0);
989
+ }
990
+ }
991
+ object.setParam(paramName, value);
992
+ const unitModifiers = [
993
+ ParamKeys.angle,
994
+ ParamKeys.flip,
995
+ ParamKeys.flipX,
996
+ ParamKeys.flipY,
997
+ ];
998
+ if (unitModifiers.indexOf(paramName) !== -1) {
999
+ object.getUnit().setParam(paramName, value);
1000
+ }
1001
+ this.log2(`set instance ${object.instanceName} param ${paramName} to ${value}`);
1002
+ }
1003
+ else {
1004
+ let reference = null;
1005
+ for (let i = 0; i < trailers.length; i++) {
1006
+ const trailer = trailers[i];
1007
+ if (i === 0) {
1008
+ reference = object.getParam(trailer);
1009
+ }
1010
+ else {
1011
+ if (reference instanceof Net) {
1012
+ const remainingTrailers = trailers.slice(i);
1013
+ reference.params.set(remainingTrailers.join("."), value);
1014
+ }
1015
+ }
1016
+ }
1017
+ }
1055
1018
  }
1056
1019
  getInstanceParam(object, trailers) {
1057
1020
  const paramName = trailers[0];