circuitscript 0.1.12 → 0.1.13

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) {
@@ -557,38 +557,18 @@ class ExecutionContext {
557
557
  if (isVariable || isComponentInstance) {
558
558
  const scopeList = isVariable ? context.scope.variables
559
559
  : 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
- }
560
+ const useValue = scopeList.get(idName);
561
+ if (!isComponentInstance && (useValue instanceof ClassComponent_js_1.ClassComponent)) {
562
+ isComponentInstance = true;
563
+ isVariable = false;
585
564
  }
565
+ const tmpReference = this.resolveTrailers(isVariable ? globals_js_1.ReferenceTypes.variable : globals_js_1.ReferenceTypes.instance, useValue, trailers);
586
566
  return new types_js_1.DeclaredReference({
587
567
  type: isVariable ? globals_js_1.ReferenceTypes.variable
588
568
  : globals_js_1.ReferenceTypes.instance,
589
- found: (useValue !== undefined),
590
- parentValue,
591
- value: useValue,
569
+ found: (tmpReference.value !== undefined),
570
+ parentValue: tmpReference.parentValue,
571
+ value: tmpReference.value,
592
572
  name: idName,
593
573
  trailers,
594
574
  });
@@ -600,6 +580,37 @@ class ExecutionContext {
600
580
  name: idName,
601
581
  });
602
582
  }
583
+ resolveTrailers(type, item, trailers = []) {
584
+ let parentValue;
585
+ let useValue = item;
586
+ if (trailers.length > 0) {
587
+ parentValue = useValue;
588
+ const trailersPath = trailers.join(".");
589
+ if (type === globals_js_1.ReferenceTypes.variable) {
590
+ useValue = parentValue[trailersPath];
591
+ }
592
+ else if (type === globals_js_1.ReferenceTypes.instance) {
593
+ const tmpComponent = parentValue;
594
+ if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net) {
595
+ const usedNet = this.scope.getNet(tmpComponent, 1);
596
+ if (usedNet) {
597
+ const trailerValue = trailers.join(".");
598
+ useValue = usedNet.params.get(trailerValue) ?? null;
599
+ }
600
+ }
601
+ else {
602
+ useValue = parentValue.parameters.get(trailersPath);
603
+ }
604
+ }
605
+ }
606
+ return new types_js_1.AnyReference({
607
+ found: true,
608
+ type: type,
609
+ parentValue,
610
+ trailers,
611
+ value: useValue,
612
+ });
613
+ }
603
614
  callFunction(functionName, functionParams, executionStack, netNamespace) {
604
615
  let __runFunc = null;
605
616
  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();
@@ -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);
@@ -406,7 +406,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
406
406
  };
407
407
  this.visitGraphicForExpr = (ctx) => {
408
408
  const forVariableNames = ctx.ID().map(item => item.getText());
409
- const listItems = (0, utils_js_1.prepareValue)(this.visitResult(ctx.data_expr()));
409
+ const listItems = (0, utils_js_1.unwrapValue)(this.visitResult(ctx.data_expr()));
410
410
  let keepLooping = true;
411
411
  let counter = 0;
412
412
  let allCommands = [];
@@ -548,7 +548,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
548
548
  const ctxAssignmentExpr = ctx.assignment_expr();
549
549
  if (ctxDataExpr) {
550
550
  component = this.visitResult(ctxDataExpr);
551
- component = (0, utils_js_1.prepareValue)(component);
551
+ component = (0, utils_js_1.unwrapValue)(component);
552
552
  componentCtx = ctxDataExpr;
553
553
  if (component === null || component === undefined) {
554
554
  this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
@@ -1029,7 +1029,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1029
1029
  this.log('in for loop');
1030
1030
  const forVariableNames = ctx.ID().map(item => item.getText());
1031
1031
  let listItems = this.visitResult(ctx.data_expr());
1032
- listItems = (0, utils_js_1.prepareValue)(listItems);
1032
+ listItems = (0, utils_js_1.unwrapValue)(listItems);
1033
1033
  this.getExecutor().addBreakContext(ctx);
1034
1034
  let keepLooping = true;
1035
1035
  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,
@@ -133,17 +132,17 @@ export class BaseVisitor extends CircuitScriptVisitor {
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);