circuitscript 0.1.12 → 0.1.14

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.
@@ -22,8 +22,7 @@ function linkBuiltInMethods(context, visitor) {
22
22
  context.createFunction('print', (params) => {
23
23
  const args = getPositionParams(params);
24
24
  const items = args.map(item => {
25
- const value = (0, utils_js_1.prepareValue)(item);
26
- return toString(value);
25
+ return toString((0, utils_js_1.unwrapValue)(item));
27
26
  });
28
27
  if (visitor.printToConsole) {
29
28
  console.log('::', ...items);
@@ -85,7 +84,7 @@ function toMils(value) {
85
84
  return (0, utils_js_1.resolveToNumericValue)(bigValue);
86
85
  }
87
86
  function objectLength(obj) {
88
- obj = (0, utils_js_1.prepareValue)(obj);
87
+ obj = (0, utils_js_1.unwrapValue)(obj);
89
88
  if (Array.isArray(obj)) {
90
89
  return (0, ParamDefinition_js_1.numeric)(obj.length);
91
90
  }
@@ -116,6 +115,9 @@ function arrayGet(arrayObject, index) {
116
115
  else {
117
116
  useValue = index;
118
117
  }
118
+ if (isNaN(useValue)) {
119
+ throw new utils_js_1.RuntimeExecutionError("Invalid index for arrayGet");
120
+ }
119
121
  return arrayObject[useValue];
120
122
  }
121
123
  function arraySet(arrayObject, index, setValue) {
@@ -15,7 +15,7 @@ const helpers_js_1 = require("./helpers.js");
15
15
  const draw_symbols_js_1 = require("./draw_symbols.js");
16
16
  const utils_js_1 = require("./utils.js");
17
17
  class ExecutionContext {
18
- constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, warnings, parent) {
18
+ constructor(name, namespace, netNamespace, executionLevel = 0, scopeLevel = 0, silent = false, logger, warnings, parent) {
19
19
  this.tmpPointId = 0;
20
20
  this.resolveNet = null;
21
21
  this.stopFurtherExpressions = false;
@@ -30,10 +30,10 @@ class ExecutionContext {
30
30
  this.executionLevel = executionLevel;
31
31
  this.logger = logger;
32
32
  this.scope = ExecutionScope_js_1.ExecutionScope.create();
33
- this.scope.indentLevel = indentLevel;
33
+ this.scope.scopeLevel = scopeLevel;
34
34
  this.setupRoot();
35
35
  this.silent = silent;
36
- this.log('create new execution context', this.namespace, this.name, this.scope.indentLevel);
36
+ this.log('create new execution context', this.namespace, this.name, this.scope.scopeLevel);
37
37
  this.parentContext = parent;
38
38
  this.warnings = warnings;
39
39
  }
@@ -45,8 +45,8 @@ class ExecutionContext {
45
45
  });
46
46
  }
47
47
  log(...params) {
48
- const indentOutput = ''.padStart(this.scope.indentLevel * 4, ' ');
49
- const indentLevelText = this.scope.indentLevel
48
+ const indentOutput = ''.padStart(this.scope.scopeLevel * 4, ' ');
49
+ const indentLevelText = this.scope.scopeLevel
50
50
  .toString()
51
51
  .padStart(3, ' ');
52
52
  const args = ['[' + indentLevelText + ']', indentOutput, ...params];
@@ -398,7 +398,7 @@ class ExecutionContext {
398
398
  this.addPoint(`${globals_js_1.Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
399
399
  this.tmpPointId += 1;
400
400
  }
401
- this.scope.blockStack.set(this.scope.indentLevel, {
401
+ this.scope.blockStack.set(this.scope.scopeLevel, {
402
402
  start_point: [
403
403
  this.scope.currentComponent,
404
404
  this.scope.currentPin,
@@ -411,8 +411,11 @@ class ExecutionContext {
411
411
  });
412
412
  this.log('enter blocks');
413
413
  }
414
- exitBlocks() {
415
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
414
+ exitBlocks(scopeLevel = null) {
415
+ if (scopeLevel === null) {
416
+ scopeLevel = this.scope.scopeLevel;
417
+ }
418
+ const stackRef = this.scope.blockStack.get(scopeLevel);
416
419
  const { type: blockType } = stackRef;
417
420
  if (blockType === globals_js_1.BlockTypes.Join || blockType === globals_js_1.BlockTypes.Parallel) {
418
421
  const { end_point: finalPoint } = stackRef;
@@ -429,16 +432,18 @@ class ExecutionContext {
429
432
  const { start_point: [component, pin,] } = stackRef;
430
433
  this.atComponent(component, pin, { addSequence: true });
431
434
  }
432
- this.scope.blockStack.delete(this.scope.indentLevel);
435
+ this.scope.blockStack.delete(scopeLevel);
433
436
  this.log('exit blocks');
434
437
  }
435
- closeAllBlocks() {
436
- if (this.scope.blockStack.has(this.scope.indentLevel)) {
438
+ closeOpenPathBlocks() {
439
+ const scope = this.scope;
440
+ const scopeLevel = scope.scopeLevel;
441
+ if (scope.blockStack.has(scopeLevel)) {
437
442
  this.exitBlocks();
438
443
  }
439
444
  }
440
445
  enterBlock(blockIndex) {
441
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
446
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel);
442
447
  const { type: blockType } = stackRef;
443
448
  const blockTypeName = (0, utils_js_1.getBlockTypeString)(blockType);
444
449
  stackRef.inner_blocks.set(blockIndex, {
@@ -454,10 +459,10 @@ class ExecutionContext {
454
459
  this.atComponent(component, pin, { addSequence: true });
455
460
  }
456
461
  this.log(`enter inner block of type (${blockTypeName}) >>>`);
457
- this.scope.indentLevel += 1;
462
+ this.scope.scopeLevel += 1;
458
463
  }
459
464
  exitBlock(blockIndex) {
460
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1);
465
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1);
461
466
  const { type: blockType } = stackRef;
462
467
  const blockIndexRef = stackRef.inner_blocks.get(blockIndex);
463
468
  blockIndexRef.last_net = [
@@ -465,7 +470,7 @@ class ExecutionContext {
465
470
  this.scope.currentPin,
466
471
  this.scope.currentWireId
467
472
  ];
468
- this.scope.indentLevel -= 1;
473
+ this.scope.scopeLevel -= 1;
469
474
  this.log('exit inner block <<<');
470
475
  if (blockType === globals_js_1.BlockTypes.Branch) {
471
476
  const { start_point: [component, pin, wireId] } = stackRef;
@@ -506,8 +511,8 @@ class ExecutionContext {
506
511
  }
507
512
  getPointBlockLocation() {
508
513
  this.log('get block point');
509
- for (let i = 0; i < this.scope.indentLevel; i++) {
510
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
514
+ for (let i = 0; i < this.scope.scopeLevel; i++) {
515
+ const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1 - i);
511
516
  const { start_point } = stackRef;
512
517
  const component = start_point[0];
513
518
  if (component.instanceName.startsWith(`${globals_js_1.Delimiter1}point.`)) {
@@ -557,38 +562,18 @@ class ExecutionContext {
557
562
  if (isVariable || isComponentInstance) {
558
563
  const scopeList = isVariable ? context.scope.variables
559
564
  : context.scope.instances;
560
- let parentValue = undefined;
561
- let useValue = scopeList.get(idName);
562
- if (trailers.length > 0) {
563
- parentValue = useValue;
564
- const trailersPath = trailers.join(".");
565
- if (!isComponentInstance && (parentValue instanceof ClassComponent_js_1.ClassComponent)) {
566
- isComponentInstance = true;
567
- isVariable = false;
568
- }
569
- if (isVariable) {
570
- useValue = parentValue[trailersPath];
571
- }
572
- else if (isComponentInstance) {
573
- const tmpComponent = parentValue;
574
- if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net) {
575
- const usedNet = this.scope.getNet(tmpComponent, 1);
576
- if (usedNet) {
577
- const trailerValue = trailers.join(".");
578
- useValue = usedNet.params.get(trailerValue) ?? null;
579
- }
580
- }
581
- else {
582
- useValue = parentValue.parameters.get(trailersPath);
583
- }
584
- }
565
+ const useValue = scopeList.get(idName);
566
+ if (!isComponentInstance && (useValue instanceof ClassComponent_js_1.ClassComponent)) {
567
+ isComponentInstance = true;
568
+ isVariable = false;
585
569
  }
570
+ const tmpReference = this.resolveTrailers(isVariable ? globals_js_1.ReferenceTypes.variable : globals_js_1.ReferenceTypes.instance, useValue, trailers);
586
571
  return new types_js_1.DeclaredReference({
587
572
  type: isVariable ? globals_js_1.ReferenceTypes.variable
588
573
  : globals_js_1.ReferenceTypes.instance,
589
- found: (useValue !== undefined),
590
- parentValue,
591
- value: useValue,
574
+ found: (tmpReference.value !== undefined),
575
+ parentValue: tmpReference.parentValue,
576
+ value: tmpReference.value,
592
577
  name: idName,
593
578
  trailers,
594
579
  });
@@ -600,6 +585,37 @@ class ExecutionContext {
600
585
  name: idName,
601
586
  });
602
587
  }
588
+ resolveTrailers(type, item, trailers = []) {
589
+ let parentValue;
590
+ let useValue = item;
591
+ if (trailers.length > 0) {
592
+ parentValue = useValue;
593
+ const trailersPath = trailers.join(".");
594
+ if (type === globals_js_1.ReferenceTypes.variable) {
595
+ useValue = parentValue[trailersPath];
596
+ }
597
+ else if (type === globals_js_1.ReferenceTypes.instance) {
598
+ const tmpComponent = parentValue;
599
+ if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net) {
600
+ const usedNet = this.scope.getNet(tmpComponent, 1);
601
+ if (usedNet) {
602
+ const trailerValue = trailers.join(".");
603
+ useValue = usedNet.params.get(trailerValue) ?? null;
604
+ }
605
+ }
606
+ else {
607
+ useValue = parentValue.parameters.get(trailersPath);
608
+ }
609
+ }
610
+ }
611
+ return new types_js_1.AnyReference({
612
+ found: true,
613
+ type: type,
614
+ parentValue,
615
+ trailers,
616
+ value: useValue,
617
+ });
618
+ }
603
619
  callFunction(functionName, functionParams, executionStack, netNamespace) {
604
620
  let __runFunc = null;
605
621
  if (this.__functionCache[functionName] === undefined) {
@@ -194,14 +194,6 @@ async function renderScript(scriptData, outputPath, options) {
194
194
  };
195
195
  visitor.log('reading file');
196
196
  visitor.log('done reading file');
197
- const { tree, parser, parserTimeTaken, lexerTimeTaken } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
198
- (0, utils_js_1.printWarnings)(visitor.getWarnings());
199
- showStats && console.log('Lexing took:', lexerTimeTaken);
200
- showStats && console.log('Parsing took:', parserTimeTaken);
201
- if (dumpNets) {
202
- const nets = visitor.dumpNets();
203
- nets.forEach(item => console.log(item.join(" | ")));
204
- }
205
197
  const dumpDirectory = environment.getRelativeToModule('/dump/');
206
198
  if (dumpData) {
207
199
  console.log('Dump data to:', dumpDirectory);
@@ -209,8 +201,19 @@ async function renderScript(scriptData, outputPath, options) {
209
201
  (0, fs_1.mkdirSync)(dumpDirectory);
210
202
  }
211
203
  }
204
+ const { tree, parser, parserTimeTaken, lexerTimeTaken, throwError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
205
+ (0, utils_js_1.printWarnings)(visitor.getWarnings());
206
+ showStats && console.log('Lexing took:', lexerTimeTaken);
207
+ showStats && console.log('Parsing took:', parserTimeTaken);
208
+ if (dumpNets) {
209
+ const nets = visitor.dumpNets();
210
+ nets.forEach(item => console.log(item.join(" | ")));
211
+ }
212
212
  dumpData && (0, fs_1.writeFileSync)(dumpDirectory + 'tree.lisp', tree.toStringTree(null, parser));
213
213
  dumpData && (0, fs_1.writeFileSync)(dumpDirectory + 'raw-parser.txt', visitor.logger.dump());
214
+ if (throwError) {
215
+ throw throwError;
216
+ }
214
217
  let svgOutput = "";
215
218
  if (errors.length === 0) {
216
219
  const { frameComponent } = visitor.applySheetFrameComponent();
@@ -15,7 +15,7 @@ class ExecutionScope {
15
15
  this.breakStack = [];
16
16
  this.wires = [];
17
17
  this.frames = [];
18
- this.indentLevel = 0;
18
+ this.scopeLevel = 0;
19
19
  this.netCounter = 1;
20
20
  this.unnamedCounter = 1;
21
21
  this.currentComponent = null;
@@ -21,6 +21,7 @@ async function parseFileWithVisitor(visitor, data) {
21
21
  parser.removeErrorListeners();
22
22
  parser.addErrorListener(parserErrorListener);
23
23
  const tree = parser.script();
24
+ let throwError;
24
25
  try {
25
26
  await visitor.visitAsync(tree);
26
27
  }
@@ -30,7 +31,7 @@ async function parseFileWithVisitor(visitor, data) {
30
31
  visitor.onErrorHandler(error.message, null, error);
31
32
  }
32
33
  else {
33
- throw error;
34
+ throwError = error;
34
35
  }
35
36
  }
36
37
  }
@@ -41,6 +42,7 @@ async function parseFileWithVisitor(visitor, data) {
41
42
  hasError: false,
42
43
  parserTimeTaken,
43
44
  lexerTimeTaken,
45
+ throwError
44
46
  };
45
47
  }
46
48
  exports.parseFileWithVisitor = parseFileWithVisitor;
package/dist/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isReference = exports.prepareValue = exports.printWarnings = exports.RenderError = exports.RuntimeExecutionError = exports.ParseError = exports.ParseSyntaxError = exports.getLinePositionAsString = exports.BaseError = exports.getBlockTypeString = exports.generateDebugSequenceAction = exports.sequenceActionString = exports.areasOverlap = exports.isPointWithinArea = exports.resolveToNumericValue = exports.getNumberExponentialText = exports.getNumberExponential = exports.combineMaps = exports.throwWithTokenRange = exports.throwWithToken = exports.throwWithContext = exports.roundValue = exports.getPortType = exports.getBoundsSize = exports.toNearestGrid = exports.resizeToNearestGrid = exports.printBounds = exports.resizeBounds = exports.SimpleStopwatch = void 0;
3
+ exports.isReference = exports.unwrapValue = exports.printWarnings = exports.RenderError = exports.RuntimeExecutionError = exports.ParseError = exports.ParseSyntaxError = exports.getLinePositionAsString = exports.BaseError = exports.getBlockTypeString = exports.generateDebugSequenceAction = exports.sequenceActionString = exports.areasOverlap = exports.isPointWithinArea = exports.resolveToNumericValue = exports.getNumberExponentialText = exports.getNumberExponential = exports.combineMaps = exports.throwWithTokenRange = exports.throwWithToken = exports.throwWithContext = exports.roundValue = exports.getPortType = exports.getBoundsSize = exports.toNearestGrid = exports.resizeToNearestGrid = exports.printBounds = exports.resizeBounds = exports.SimpleStopwatch = void 0;
4
4
  const big_js_1 = require("big.js");
5
5
  const antlr4ng_1 = require("antlr4ng");
6
6
  const ClassComponent_js_1 = require("./objects/ClassComponent.js");
@@ -359,7 +359,7 @@ function printWarnings(warnings) {
359
359
  });
360
360
  }
361
361
  exports.printWarnings = printWarnings;
362
- function prepareValue(value) {
362
+ function unwrapValue(value) {
363
363
  if (isReference(value)) {
364
364
  return value.value;
365
365
  }
@@ -367,7 +367,7 @@ function prepareValue(value) {
367
367
  return value;
368
368
  }
369
369
  }
370
- exports.prepareValue = prepareValue;
370
+ exports.unwrapValue = unwrapValue;
371
371
  function isReference(value) {
372
372
  return (value instanceof types_js_1.AnyReference ||
373
373
  value instanceof types_js_1.DeclaredReference);
@@ -104,17 +104,17 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
104
104
  }
105
105
  const scope = this.getScope();
106
106
  const executor = this.getExecutor();
107
- const indentLevel = scope.indentLevel;
108
- if (scope.blockStack.has(indentLevel)) {
109
- const blockStackEntry = scope.blockStack.get(indentLevel);
107
+ const scopeLevel = scope.scopeLevel;
108
+ if (scope.blockStack.has(scopeLevel)) {
109
+ const blockStackEntry = scope.blockStack.get(scopeLevel);
110
110
  if (blockStackEntry.type !== blockType) {
111
111
  executor.exitBlocks();
112
112
  }
113
113
  }
114
- if (!scope.blockStack.has(indentLevel)) {
114
+ if (!scope.blockStack.has(scopeLevel)) {
115
115
  executor.enterBlocks(blockType);
116
116
  }
117
- const blockStackEntry = scope.blockStack.get(indentLevel);
117
+ const blockStackEntry = scope.blockStack.get(scopeLevel);
118
118
  const { current_index } = blockStackEntry;
119
119
  executor.enterBlock(current_index);
120
120
  this.visit(ctx.expressions_block());
@@ -122,12 +122,9 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
122
122
  blockStackEntry.current_index++;
123
123
  };
124
124
  this.visitGraph_expressions = (ctx) => {
125
+ this.getExecutor().log('graph expressions', this.getScope().scopeLevel);
125
126
  if (ctx.path_block() === null) {
126
- const scope = this.getScope();
127
- const indentLevel = scope.indentLevel;
128
- if (scope.blockStack.has(indentLevel)) {
129
- this.getExecutor().exitBlocks();
130
- }
127
+ this.getExecutor().closeOpenPathBlocks();
131
128
  }
132
129
  const ctxPathBlock = ctx.path_block();
133
130
  const ctxNotPathBlock = ctx.graph_linear_expression();
@@ -406,7 +403,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
406
403
  };
407
404
  this.visitGraphicForExpr = (ctx) => {
408
405
  const forVariableNames = ctx.ID().map(item => item.getText());
409
- const listItems = (0, utils_js_1.prepareValue)(this.visitResult(ctx.data_expr()));
406
+ const listItems = (0, utils_js_1.unwrapValue)(this.visitResult(ctx.data_expr()));
410
407
  let keepLooping = true;
411
408
  let counter = 0;
412
409
  let allCommands = [];
@@ -548,7 +545,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
548
545
  const ctxAssignmentExpr = ctx.assignment_expr();
549
546
  if (ctxDataExpr) {
550
547
  component = this.visitResult(ctxDataExpr);
551
- component = (0, utils_js_1.prepareValue)(component);
548
+ component = (0, utils_js_1.unwrapValue)(component);
552
549
  componentCtx = ctxDataExpr;
553
550
  if (component === null || component === undefined) {
554
551
  this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
@@ -818,9 +815,10 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
818
815
  this.setResult(ctx, result);
819
816
  };
820
817
  this.visitAt_block_pin_expr = (ctx) => {
821
- const atPin = this.visitResult(ctx.pin_select_expr2());
822
818
  const executor = this.getExecutor();
823
819
  const [currentComponent, currentPin] = executor.getCurrentPoint();
820
+ executor.closeOpenPathBlocks();
821
+ const atPin = this.visitResult(ctx.pin_select_expr2());
824
822
  executor.atComponent(currentComponent, atPin, {
825
823
  addSequence: true
826
824
  });
@@ -841,11 +839,11 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
841
839
  executor.log('entering at block');
842
840
  this.visit(ctx.at_component_expr());
843
841
  const [currentComponent, currentPin] = executor.getCurrentPoint();
844
- executor.scope.indentLevel += 1;
842
+ executor.scope.scopeLevel += 1;
845
843
  ctx.at_block_expressions().forEach(expression => {
846
844
  this.visit(expression);
847
845
  });
848
- executor.scope.indentLevel -= 1;
846
+ executor.scope.scopeLevel -= 1;
849
847
  executor.scope.setCurrent(currentComponent, currentPin);
850
848
  executor.log('leaving at block');
851
849
  };
@@ -1029,7 +1027,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1029
1027
  this.log('in for loop');
1030
1028
  const forVariableNames = ctx.ID().map(item => item.getText());
1031
1029
  let listItems = this.visitResult(ctx.data_expr());
1032
- listItems = (0, utils_js_1.prepareValue)(listItems);
1030
+ listItems = (0, utils_js_1.unwrapValue)(listItems);
1033
1031
  this.getExecutor().addBreakContext(ctx);
1034
1032
  let keepLooping = true;
1035
1033
  let counter = 0;
@@ -8,7 +8,7 @@ import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDe
8
8
  import { PinTypes } from "./objects/PinTypes.js";
9
9
  import { Direction, AnyReference, UndeclaredReference } from "./objects/types.js";
10
10
  import { ComponentTypes, DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals.js';
11
- import { isReference, prepareValue } from "./utils.js";
11
+ import { isReference, unwrapValue as unwrapValue } from "./utils.js";
12
12
  import { linkBuiltInMethods } from './builtinMethods.js';
13
13
  import { resolveToNumericValue, RuntimeExecutionError, throwWithContext } from './utils.js';
14
14
  import { SequenceAction } from './objects/ExecutionScope.js';
@@ -23,7 +23,6 @@ export class BaseVisitor extends CircuitScriptVisitor {
23
23
  acceptedDirections = [Direction.Up, Direction.Down,
24
24
  Direction.Right, Direction.Left];
25
25
  resultData = new Map;
26
- paramData = new Map;
27
26
  pinTypesList = [
28
27
  PinTypes.Any,
29
28
  PinTypes.Input,
@@ -128,22 +127,22 @@ export class BaseVisitor extends CircuitScriptVisitor {
128
127
  }
129
128
  const result = this.runExpressions(this.getExecutor(), ctx.expression());
130
129
  this.setResult(ctx, result);
131
- this.getExecutor().closeAllBlocks();
130
+ this.getExecutor().closeOpenPathBlocks();
132
131
  this.log('===', 'end', '===');
133
132
  };
134
133
  visitAssignment_expr = (ctx) => {
135
134
  const ctxAtom = ctx.atom_expr();
136
- const ctxFuncCall = ctx.function_call_expr();
135
+ const ctxFuncCallRef = ctx.function_call_expr();
137
136
  let leftSideReference;
138
137
  if (ctxAtom) {
139
138
  leftSideReference = this.getReference(ctx.atom_expr());
140
139
  }
141
- else if (ctxFuncCall) {
142
- leftSideReference = this.visitResult(ctxFuncCall);
140
+ else if (ctxFuncCallRef) {
141
+ this.setResult(ctxFuncCallRef, { keepReference: true });
142
+ leftSideReference = this.visitResult(ctxFuncCallRef);
143
143
  }
144
- const ctxDataExpr = ctx.data_expr();
145
- const dataValue = this.visitResult(ctxDataExpr);
146
- const rhsValue = prepareValue(dataValue);
144
+ const rhsCtxResult = this.visitResult(ctx.data_expr());
145
+ const rhsValue = unwrapValue(rhsCtxResult);
147
146
  const trailers = leftSideReference.trailers ?? [];
148
147
  const sequenceParts = [];
149
148
  if (trailers.length === 0) {
@@ -186,9 +185,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
186
185
  };
187
186
  visitOperator_assignment_expr = (ctx) => {
188
187
  const reference = this.getReference(ctx.atom_expr());
189
- const ctxDataExpr = ctx.data_expr();
190
- this.visit(ctxDataExpr);
191
- const value = this.getResult(ctxDataExpr);
188
+ const value = this.visitResult(ctx.data_expr());
192
189
  if (!reference.found) {
193
190
  this.throwWithContext(ctx, 'Undefined reference: ' + reference.name);
194
191
  }
@@ -294,13 +291,21 @@ export class BaseVisitor extends CircuitScriptVisitor {
294
291
  this.setResult(ctx, result);
295
292
  };
296
293
  visitFunction_call_expr = (ctx) => {
294
+ const ctxParams = this.getResult(ctx);
295
+ const { keepReference = false } = ctxParams ?? {};
296
+ this.handleFunctionCall(ctx);
297
+ if (!keepReference) {
298
+ const functionResultReference = this.getResult(ctx);
299
+ this.setResult(ctx, functionResultReference.value);
300
+ }
301
+ };
302
+ handleFunctionCall(ctx) {
297
303
  const executor = this.getExecutor();
298
304
  const atomId = ctx.ID().getText();
299
305
  let passedNetNamespace = null;
300
306
  const netNameSpaceExpr = ctx.net_namespace_expr();
301
307
  if (netNameSpaceExpr) {
302
- this.visit(netNameSpaceExpr);
303
- passedNetNamespace = this.getResult(netNameSpaceExpr);
308
+ passedNetNamespace = this.visitResult(netNameSpaceExpr);
304
309
  }
305
310
  let currentReference = executor.resolveVariable(this.executionStack, atomId);
306
311
  if (ctx.trailer_expr().length > 0) {
@@ -309,13 +314,11 @@ export class BaseVisitor extends CircuitScriptVisitor {
309
314
  }
310
315
  currentReference.trailers = [];
311
316
  ctx.trailer_expr().forEach(item => {
312
- const itemValue = item.getText();
313
317
  if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
314
318
  let parameters = [];
315
319
  const ctxParameters = item.parameters();
316
320
  if (ctxParameters) {
317
- this.visit(ctxParameters);
318
- parameters = this.getResult(ctxParameters);
321
+ parameters = this.visitResult(ctxParameters);
319
322
  }
320
323
  const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
321
324
  try {
@@ -338,12 +341,15 @@ export class BaseVisitor extends CircuitScriptVisitor {
338
341
  }
339
342
  }
340
343
  else {
341
- currentReference.trailers.push(itemValue);
344
+ currentReference.trailers.push(item.ID().getText());
345
+ currentReference = this.getExecutor().resolveTrailers(currentReference.type, (currentReference.parentValue !== undefined)
346
+ ? currentReference.parentValue
347
+ : currentReference.value, currentReference.trailers);
342
348
  }
343
349
  });
344
350
  }
345
351
  this.setResult(ctx, currentReference);
346
- };
352
+ }
347
353
  visitValue_expr = (ctx) => {
348
354
  const sign = ctx.Minus() ? -1 : 1;
349
355
  const ctxIntegerValue = ctx.INTEGER_VALUE();
@@ -392,12 +398,10 @@ export class BaseVisitor extends CircuitScriptVisitor {
392
398
  const ctxValueExpr = ctx.value_expr();
393
399
  const ctxAtomExpr = ctx.atom_expr();
394
400
  if (ctxValueExpr) {
395
- this.visit(ctxValueExpr);
396
- value = this.getResult(ctxValueExpr);
401
+ value = this.visitResult(ctxValueExpr);
397
402
  }
398
403
  else if (ctxAtomExpr) {
399
- this.visit(ctxAtomExpr);
400
- const reference = this.getResult(ctxAtomExpr);
404
+ const reference = this.visitResult(ctxAtomExpr);
401
405
  if (!reference.found) {
402
406
  value = new UndeclaredReference(reference);
403
407
  }
@@ -462,33 +466,34 @@ export class BaseVisitor extends CircuitScriptVisitor {
462
466
  executor.returnValue = returnValue;
463
467
  this.setResult(ctx, returnValue);
464
468
  };
465
- visitBreak_keyword = (ctx) => {
466
- const breakContext = this.getExecutor().getBreakContext();
467
- const currentResult = this.getResult(breakContext) ?? {};
468
- this.setResult(breakContext, {
469
- ...currentResult,
470
- breakSignal: true
471
- });
472
- };
473
- visitContinue_keyword = (ctx) => {
474
- const breakContext = this.getExecutor().getBreakContext();
475
- const currentResult = this.getResult(breakContext) ?? {};
476
- this.setResult(breakContext, {
477
- ...currentResult,
478
- breakSignal: true,
479
- continueSignal: true,
480
- });
469
+ visitFlow_expressions = (ctx) => {
470
+ if (ctx.if_expr()) {
471
+ this.visit(ctx.if_expr());
472
+ }
473
+ else if (ctx.while_expr()) {
474
+ this.visit(ctx.while_expr());
475
+ }
476
+ else if (ctx.for_expr()) {
477
+ this.visit(ctx.for_expr());
478
+ }
479
+ else if (ctx.Break() || ctx.Continue()) {
480
+ const breakContext = this.getExecutor().getBreakContext();
481
+ const currentResult = this.getResult(breakContext) ?? {};
482
+ this.setResult(breakContext, {
483
+ ...currentResult,
484
+ breakSignal: true,
485
+ continueSignal: ctx.Continue() ? true : false
486
+ });
487
+ }
481
488
  };
482
489
  visitArray_expr = (ctx) => {
483
490
  const array = ctx.data_expr().map(item => {
484
- this.visit(item);
485
- return this.getResult(item);
491
+ return this.visitResult(item);
486
492
  });
487
493
  this.setResult(ctx, array);
488
494
  };
489
495
  visitArrayExpr = (ctx) => {
490
- this.visit(ctx.array_expr());
491
- this.setResult(ctx, this.getResult(ctx.array_expr()));
496
+ this.setResult(ctx, this.visitResult(ctx.array_expr()));
492
497
  };
493
498
  setResult(ctx, value) {
494
499
  this.resultData.set(ctx, value);
@@ -582,7 +587,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
582
587
  const tmpFuncArg = funcDefinedParameters[i];
583
588
  if (i < passedInParameters.length) {
584
589
  const tmpPassedInArgs = passedInParameters[i];
585
- const argValue = prepareValue(tmpPassedInArgs[2]);
590
+ const argValue = unwrapValue(tmpPassedInArgs[2]);
586
591
  if (tmpPassedInArgs[0] === 'position') {
587
592
  const variableName = tmpFuncArg[0];
588
593
  executor.log('set variable in scope, var name: ', variableName);
@@ -665,7 +670,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
665
670
  const executionLevel = currentExecutionContext.executionLevel;
666
671
  const executionContextNamespace = currentExecutionContext.namespace
667
672
  + executionContextName + ".";
668
- const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
673
+ const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.scopeLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
669
674
  executionStack.push(newExecutor);
670
675
  this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
671
676
  return newExecutor;