circuitscript 0.1.10 → 0.1.12

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 (52) hide show
  1. package/dist/cjs/BaseVisitor.js +78 -51
  2. package/dist/cjs/SemanticTokenVisitor.js +6 -1
  3. package/dist/cjs/antlr/CircuitScriptParser.js +1062 -963
  4. package/dist/cjs/builtinMethods.js +5 -1
  5. package/dist/cjs/draw_symbols.js +2 -1
  6. package/dist/cjs/execute.js +43 -22
  7. package/dist/cjs/geometry.js +3 -9
  8. package/dist/cjs/globals.js +7 -1
  9. package/dist/cjs/layout.js +50 -16
  10. package/dist/cjs/objects/ExecutionScope.js +3 -0
  11. package/dist/cjs/objects/Net.js +1 -0
  12. package/dist/cjs/objects/ParamDefinition.js +3 -0
  13. package/dist/cjs/objects/types.js +19 -10
  14. package/dist/cjs/render.js +48 -6
  15. package/dist/cjs/utils.js +16 -1
  16. package/dist/cjs/validate/SymbolValidatorVisitor.js +5 -0
  17. package/dist/cjs/visitor.js +77 -57
  18. package/dist/esm/BaseVisitor.js +72 -45
  19. package/dist/esm/SemanticTokenVisitor.js +6 -1
  20. package/dist/esm/antlr/CircuitScriptParser.js +1055 -958
  21. package/dist/esm/antlr/CircuitScriptVisitor.js +4 -2
  22. package/dist/esm/builtinMethods.js +6 -2
  23. package/dist/esm/draw_symbols.js +2 -1
  24. package/dist/esm/execute.js +43 -22
  25. package/dist/esm/geometry.js +3 -9
  26. package/dist/esm/globals.js +6 -0
  27. package/dist/esm/layout.js +53 -17
  28. package/dist/esm/objects/ExecutionScope.js +3 -0
  29. package/dist/esm/objects/Net.js +1 -0
  30. package/dist/esm/objects/ParamDefinition.js +4 -1
  31. package/dist/esm/objects/types.js +21 -15
  32. package/dist/esm/render.js +49 -7
  33. package/dist/esm/utils.js +13 -0
  34. package/dist/esm/validate/SymbolValidatorVisitor.js +5 -0
  35. package/dist/esm/visitor.js +66 -46
  36. package/dist/types/BaseVisitor.d.ts +2 -2
  37. package/dist/types/SemanticTokenVisitor.d.ts +2 -1
  38. package/dist/types/antlr/CircuitScriptParser.d.ts +100 -85
  39. package/dist/types/antlr/CircuitScriptVisitor.d.ts +8 -4
  40. package/dist/types/execute.d.ts +1 -0
  41. package/dist/types/geometry.d.ts +0 -1
  42. package/dist/types/globals.d.ts +5 -0
  43. package/dist/types/layout.d.ts +16 -3
  44. package/dist/types/objects/ExecutionScope.d.ts +15 -3
  45. package/dist/types/objects/Net.d.ts +1 -0
  46. package/dist/types/objects/types.d.ts +25 -18
  47. package/dist/types/utils.d.ts +3 -1
  48. package/dist/types/validate/SymbolValidatorVisitor.d.ts +2 -1
  49. package/dist/types/visitor.d.ts +3 -2
  50. package/package.json +3 -2
  51. /package/dist/libs/{lib.cst → std.cst} +0 -0
  52. /package/libs/{lib.cst → std.cst} +0 -0
@@ -7,9 +7,10 @@ const PinDefinition_js_1 = require("./objects/PinDefinition.js");
7
7
  const PinTypes_js_1 = require("./objects/PinTypes.js");
8
8
  const types_js_1 = require("./objects/types.js");
9
9
  const globals_js_1 = require("./globals.js");
10
+ const utils_js_1 = require("./utils.js");
10
11
  const draw_symbols_js_1 = require("./draw_symbols.js");
11
12
  const BaseVisitor_js_1 = require("./BaseVisitor.js");
12
- const utils_js_1 = require("./utils.js");
13
+ const utils_js_2 = require("./utils.js");
13
14
  const helpers_js_1 = require("./helpers.js");
14
15
  const Frame_js_1 = require("./objects/Frame.js");
15
16
  class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
@@ -22,13 +23,16 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
22
23
  };
23
24
  this.visitPin_select_expr = (ctx) => {
24
25
  let value = null;
25
- const ctxIntegerValue = ctx.INTEGER_VALUE();
26
- const ctxStringValue = ctx.STRING_VALUE();
27
- if (ctxIntegerValue) {
28
- value = Number(ctxIntegerValue.getText());
26
+ const ctxData = ctx.data_expr();
27
+ const result = this.visitResult(ctxData);
28
+ if (result instanceof ParamDefinition_js_1.NumericValue) {
29
+ value = result.toNumber();
29
30
  }
30
- else if (ctxStringValue) {
31
- value = this.prepareStringValue(ctxStringValue.getText());
31
+ else if (typeof result === 'string') {
32
+ value = result;
33
+ }
34
+ else {
35
+ throw new utils_js_2.RuntimeExecutionError("Invalid value for pin", ctx);
32
36
  }
33
37
  this.setResult(ctx, value);
34
38
  };
@@ -52,7 +56,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
52
56
  });
53
57
  }
54
58
  catch (err) {
55
- throw new utils_js_1.RuntimeExecutionError(err.message, ctx);
59
+ throw new utils_js_2.RuntimeExecutionError(err.message, ctx);
56
60
  }
57
61
  });
58
62
  return this.getExecutor().getCurrentPoint();
@@ -84,39 +88,55 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
84
88
  }
85
89
  this.setResult(ctx, componentPin);
86
90
  };
87
- this.visitPath_blocks = (ctx) => {
88
- const blocks = ctx.path_block_inner();
89
- let blockIndex = 0;
91
+ this.visitPath_block = (ctx) => {
90
92
  let blockType = globals_js_1.BlockTypes.Branch;
91
- let prevBlockType = null;
92
- blocks.forEach((block, index) => {
93
- if (block.Branch()) {
94
- blockType = globals_js_1.BlockTypes.Branch;
95
- }
96
- else if (block.Join()) {
97
- blockType = globals_js_1.BlockTypes.Join;
98
- }
99
- else if (block.Parallel()) {
100
- blockType = globals_js_1.BlockTypes.Parallel;
101
- }
102
- else if (block.Point()) {
103
- blockType = globals_js_1.BlockTypes.Point;
93
+ if (ctx.Branch()) {
94
+ blockType = globals_js_1.BlockTypes.Branch;
95
+ }
96
+ else if (ctx.Join()) {
97
+ blockType = globals_js_1.BlockTypes.Join;
98
+ }
99
+ else if (ctx.Parallel()) {
100
+ blockType = globals_js_1.BlockTypes.Parallel;
101
+ }
102
+ else if (ctx.Point()) {
103
+ blockType = globals_js_1.BlockTypes.Point;
104
+ }
105
+ const scope = this.getScope();
106
+ const executor = this.getExecutor();
107
+ const indentLevel = scope.indentLevel;
108
+ if (scope.blockStack.has(indentLevel)) {
109
+ const blockStackEntry = scope.blockStack.get(indentLevel);
110
+ if (blockStackEntry.type !== blockType) {
111
+ executor.exitBlocks();
104
112
  }
105
- if (prevBlockType !== blockType) {
106
- if (index > 0) {
107
- this.getExecutor().exitBlocks();
108
- }
109
- this.getExecutor().enterBlocks(blockType);
110
- blockIndex = 0;
113
+ }
114
+ if (!scope.blockStack.has(indentLevel)) {
115
+ executor.enterBlocks(blockType);
116
+ }
117
+ const blockStackEntry = scope.blockStack.get(indentLevel);
118
+ const { current_index } = blockStackEntry;
119
+ executor.enterBlock(current_index);
120
+ this.visit(ctx.expressions_block());
121
+ executor.exitBlock(current_index);
122
+ blockStackEntry.current_index++;
123
+ };
124
+ this.visitGraph_expressions = (ctx) => {
125
+ 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();
111
130
  }
112
- this.getExecutor().enterBlock(blockIndex);
113
- this.visit(block);
114
- this.getExecutor().exitBlock(blockIndex);
115
- blockIndex += 1;
116
- prevBlockType = blockType;
117
- });
118
- this.getExecutor().exitBlocks();
119
- return this.getExecutor().getCurrentPoint();
131
+ }
132
+ const ctxPathBlock = ctx.path_block();
133
+ const ctxNotPathBlock = ctx.graph_linear_expression();
134
+ if (ctxPathBlock) {
135
+ this.visit(ctxPathBlock);
136
+ }
137
+ if (ctxNotPathBlock) {
138
+ this.visit(ctxNotPathBlock);
139
+ }
120
140
  };
121
141
  this.visitCreate_component_expr = (ctx) => {
122
142
  const scope = this.getScope();
@@ -152,13 +172,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
152
172
  break;
153
173
  case 'display':
154
174
  if (didDefineArrangeProp) {
155
- throw new utils_js_1.RuntimeExecutionError("arrange property has already been defined", ctx);
175
+ throw new utils_js_2.RuntimeExecutionError("arrange property has already been defined", ctx);
156
176
  }
157
177
  didDefineDisplayProp = true;
158
178
  break;
159
179
  case 'arrange':
160
180
  if (didDefineDisplayProp) {
161
- throw new utils_js_1.RuntimeExecutionError("display property already defined", ctx);
181
+ throw new utils_js_2.RuntimeExecutionError("display property already defined", ctx);
162
182
  }
163
183
  didDefineArrangeProp = true;
164
184
  break;
@@ -179,7 +199,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
179
199
  this.validateBoolean(value, ctx);
180
200
  }
181
201
  else {
182
- throw new utils_js_1.RuntimeExecutionError("Invalid value for 'copy' property", ctx);
202
+ throw new utils_js_2.RuntimeExecutionError("Invalid value for 'copy' property", ctx);
183
203
  }
184
204
  break;
185
205
  }
@@ -189,7 +209,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
189
209
  if (keyName === 'arrange') {
190
210
  const [sideKeyCtx, sideKeyName] = path[1];
191
211
  if (globals_js_1.ValidPinSides.indexOf(sideKeyName) === -1) {
192
- throw new utils_js_1.RuntimeExecutionError(`Invalid side ${sideKeyName} in arrange`, sideKeyCtx);
212
+ throw new utils_js_2.RuntimeExecutionError(`Invalid side ${sideKeyName} in arrange`, sideKeyCtx);
193
213
  }
194
214
  else {
195
215
  if (path.length === 2 && value instanceof ParamDefinition_js_1.NumericValue) {
@@ -200,12 +220,12 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
200
220
  const goodBlank = value.length === 1 &&
201
221
  value[0] instanceof ParamDefinition_js_1.NumericValue;
202
222
  if (!goodBlank) {
203
- throw new utils_js_1.RuntimeExecutionError(`Invalid blank specifier`, ctx);
223
+ throw new utils_js_2.RuntimeExecutionError(`Invalid blank specifier`, ctx);
204
224
  }
205
225
  }
206
226
  else {
207
227
  if (!(value instanceof ParamDefinition_js_1.NumericValue)) {
208
- throw new utils_js_1.RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx);
228
+ throw new utils_js_2.RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx);
209
229
  }
210
230
  else {
211
231
  checkPinExistsAndNotDuplicated(value.toNumber(), ctx);
@@ -234,7 +254,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
234
254
  if (value.length === 2) {
235
255
  const [pinType,] = value;
236
256
  if (pinType instanceof types_js_1.UndeclaredReference) {
237
- throw new utils_js_1.RuntimeExecutionError(`Invalid pin type: ${pinType.reference.name}`, ctx);
257
+ throw new utils_js_2.RuntimeExecutionError(`Invalid pin type: ${pinType.reference.name}`, ctx);
238
258
  }
239
259
  }
240
260
  }
@@ -295,7 +315,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
295
315
  if (ctxId !== null) {
296
316
  const varName = ctxId.getText();
297
317
  paramIds.push(varName);
298
- this.getScope().variables.set(varName, {});
318
+ this.getScope().setVariable(varName, {});
299
319
  }
300
320
  const executor = this.getExecutor();
301
321
  const stack = [...this.executionStack];
@@ -305,7 +325,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
305
325
  variables.forEach((value, key) => {
306
326
  obj[key] = value;
307
327
  });
308
- executor.scope.variables.set(paramIds[0], obj);
328
+ executor.scope.setVariable(paramIds[0], obj);
309
329
  }
310
330
  const currentStack = this.executionStack.splice(0);
311
331
  this.executionStack.push(...stack);
@@ -386,7 +406,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
386
406
  };
387
407
  this.visitGraphicForExpr = (ctx) => {
388
408
  const forVariableNames = ctx.ID().map(item => item.getText());
389
- const listItems = this.visitResult(ctx.data_expr());
409
+ const listItems = (0, utils_js_1.prepareValue)(this.visitResult(ctx.data_expr()));
390
410
  let keepLooping = true;
391
411
  let counter = 0;
392
412
  let allCommands = [];
@@ -397,7 +417,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
397
417
  useValueArray = [useValueArray];
398
418
  }
399
419
  useValueArray.forEach((value, index) => {
400
- this.getScope().variables.set(forVariableNames[index], value);
420
+ this.getScope().setVariable(forVariableNames[index], value);
401
421
  });
402
422
  const commands = this.visitResult(ctx.graphic_expressions_block());
403
423
  allCommands = allCommands.concat(commands);
@@ -528,6 +548,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
528
548
  const ctxAssignmentExpr = ctx.assignment_expr();
529
549
  if (ctxDataExpr) {
530
550
  component = this.visitResult(ctxDataExpr);
551
+ component = (0, utils_js_1.prepareValue)(component);
531
552
  componentCtx = ctxDataExpr;
532
553
  if (component === null || component === undefined) {
533
554
  this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
@@ -819,15 +840,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
819
840
  const executor = this.getExecutor();
820
841
  executor.log('entering at block');
821
842
  this.visit(ctx.at_component_expr());
822
- const currentComponent = executor.scope.currentComponent;
823
- const currentPin = executor.scope.currentPin;
843
+ const [currentComponent, currentPin] = executor.getCurrentPoint();
824
844
  executor.scope.indentLevel += 1;
825
845
  ctx.at_block_expressions().forEach(expression => {
826
846
  this.visit(expression);
827
847
  });
828
848
  executor.scope.indentLevel -= 1;
829
- executor.scope.currentComponent = currentComponent;
830
- executor.scope.currentPin = currentPin;
849
+ executor.scope.setCurrent(currentComponent, currentPin);
831
850
  executor.log('leaving at block');
832
851
  };
833
852
  this.visitAt_block_pin_expression_simple = (ctx) => {
@@ -890,7 +909,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
890
909
  pointValue = resultValue;
891
910
  }
892
911
  else {
893
- throw new utils_js_1.RuntimeExecutionError('Invalid value for point');
912
+ throw new utils_js_2.RuntimeExecutionError('Invalid value for point');
894
913
  }
895
914
  }
896
915
  else if (ID) {
@@ -1009,7 +1028,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1009
1028
  this.visitFor_expr = (ctx) => {
1010
1029
  this.log('in for loop');
1011
1030
  const forVariableNames = ctx.ID().map(item => item.getText());
1012
- const listItems = this.visitResult(ctx.data_expr());
1031
+ let listItems = this.visitResult(ctx.data_expr());
1032
+ listItems = (0, utils_js_1.prepareValue)(listItems);
1013
1033
  this.getExecutor().addBreakContext(ctx);
1014
1034
  let keepLooping = true;
1015
1035
  let counter = 0;
@@ -1020,7 +1040,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1020
1040
  useValueArray = [useValueArray];
1021
1041
  }
1022
1042
  useValueArray.forEach((value, index) => {
1023
- this.getScope().variables.set(forVariableNames[index], value);
1043
+ this.getScope().setVariable(forVariableNames[index], value);
1024
1044
  });
1025
1045
  this.visit(ctx.expressions_block());
1026
1046
  keepLooping = true;
@@ -1085,7 +1105,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1085
1105
  const portName = component.parameters.get(globals_js_1.ParamKeys.net_name);
1086
1106
  const modulePinId = modulePinMapping.get(portName);
1087
1107
  pinIdToPortMap.set(modulePinId, component);
1088
- const portType = (0, utils_js_1.getPortType)(component);
1108
+ const portType = (0, utils_js_2.getPortType)(component);
1089
1109
  const tmpPin = moduleComponent.pins.get(modulePinId);
1090
1110
  tmpPin.pinType = portType;
1091
1111
  }
@@ -6,8 +6,9 @@ import { Logger } from "./logger.js";
6
6
  import { ClassComponent } from "./objects/ClassComponent.js";
7
7
  import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition.js";
8
8
  import { PinTypes } from "./objects/PinTypes.js";
9
- import { Direction, UndeclaredReference } from "./objects/types.js";
10
- import { DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals.js';
9
+ import { Direction, AnyReference, UndeclaredReference } from "./objects/types.js";
10
+ import { ComponentTypes, DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals.js';
11
+ import { isReference, prepareValue } from "./utils.js";
11
12
  import { linkBuiltInMethods } from './builtinMethods.js';
12
13
  import { resolveToNumericValue, RuntimeExecutionError, throwWithContext } from './utils.js';
13
14
  import { SequenceAction } from './objects/ExecutionScope.js';
@@ -47,7 +48,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
47
48
  scope.sequence.push([
48
49
  SequenceAction.At, scope.componentRoot, scope.currentPin
49
50
  ]);
50
- scope.variables.set(GlobalDocumentName, {});
51
+ scope.setVariable(GlobalDocumentName, {});
51
52
  this.setupBuiltInFunctions(this.startingContext);
52
53
  this.executionStack = [this.startingContext];
53
54
  this.startingContext.resolveNet =
@@ -127,37 +128,61 @@ export class BaseVisitor extends CircuitScriptVisitor {
127
128
  }
128
129
  const result = this.runExpressions(this.getExecutor(), ctx.expression());
129
130
  this.setResult(ctx, result);
131
+ this.getExecutor().closeAllBlocks();
130
132
  this.log('===', 'end', '===');
131
133
  };
132
134
  visitAssignment_expr = (ctx) => {
133
- const reference = this.getReference(ctx.atom_expr());
135
+ const ctxAtom = ctx.atom_expr();
136
+ const ctxFuncCall = ctx.function_call_expr();
137
+ let leftSideReference;
138
+ if (ctxAtom) {
139
+ leftSideReference = this.getReference(ctx.atom_expr());
140
+ }
141
+ else if (ctxFuncCall) {
142
+ leftSideReference = this.visitResult(ctxFuncCall);
143
+ }
134
144
  const ctxDataExpr = ctx.data_expr();
135
- this.visit(ctxDataExpr);
136
- const value = this.getResult(ctxDataExpr);
137
- const trailers = reference.trailers ?? [];
145
+ const dataValue = this.visitResult(ctxDataExpr);
146
+ const rhsValue = prepareValue(dataValue);
147
+ const trailers = leftSideReference.trailers ?? [];
148
+ const sequenceParts = [];
138
149
  if (trailers.length === 0) {
139
- if (value instanceof ClassComponent) {
140
- const variables = this.getExecutor().scope.variables;
141
- variables.set(reference.name, value);
142
- this.getExecutor().scope.sequence.push([SequenceAction.Assign, reference.name, value]);
143
- this.log2(`assigned '${reference.name}' to ClassComponent`);
150
+ if (rhsValue instanceof ClassComponent) {
151
+ this.getScope().setVariable(leftSideReference.name, rhsValue);
152
+ sequenceParts.push(...['instance', leftSideReference.name, rhsValue]);
153
+ this.log2(`assigned '${leftSideReference.name}' to ClassComponent`);
144
154
  }
145
155
  else {
146
- this.getExecutor().scope.variables.set(reference.name, value);
147
- this.log2(`assigned variable ${reference.name} to ${value}`);
156
+ this.getScope().setVariable(leftSideReference.name, rhsValue);
157
+ this.log2(`assigned variable ${leftSideReference.name} to ${rhsValue}`);
158
+ sequenceParts.push(...['variable', leftSideReference.name, rhsValue]);
148
159
  }
149
160
  }
150
161
  else {
151
- if (reference.parentValue instanceof ClassComponent) {
152
- this.setInstanceParam(reference.parentValue, trailers, value);
153
- this.log2(`assigned component param ${reference.parentValue} trailers: ${trailers} value: ${value}`);
162
+ if (leftSideReference.parentValue instanceof ClassComponent) {
163
+ this.setInstanceParam(leftSideReference.parentValue, trailers, rhsValue);
164
+ this.log2(`assigned component param ${leftSideReference.parentValue} trailers: ${trailers} value: ${rhsValue}`);
165
+ sequenceParts.push(...['instance', [leftSideReference.parentValue, trailers], rhsValue]);
166
+ if (leftSideReference.parentValue.typeProp === ComponentTypes.net) {
167
+ const net = this.getScope().getNet(leftSideReference.parentValue, 1);
168
+ if (net) {
169
+ const trailerValue = trailers.join(".");
170
+ net.params.set(trailerValue, rhsValue);
171
+ }
172
+ }
154
173
  }
155
- else if (reference.parentValue instanceof Object) {
156
- reference.parentValue[trailers.join('.')] = value;
157
- this.log2(`assigned object ${reference.parentValue} trailers: ${trailers} value: ${value}`);
174
+ else if (leftSideReference.parentValue instanceof Object) {
175
+ leftSideReference.parentValue[trailers.join('.')] = rhsValue;
176
+ this.log2(`assigned object ${leftSideReference.parentValue} trailers: ${trailers} value: ${rhsValue}`);
177
+ sequenceParts.push(...['variable', [leftSideReference.parentValue, trailers], rhsValue]);
158
178
  }
159
179
  }
160
- this.setResult(ctx, value);
180
+ if (sequenceParts.length > 0) {
181
+ this.getScope().sequence.push([
182
+ SequenceAction.Assign, ...sequenceParts
183
+ ]);
184
+ }
185
+ this.setResult(ctx, rhsValue);
161
186
  };
162
187
  visitOperator_assignment_expr = (ctx) => {
163
188
  const reference = this.getReference(ctx.atom_expr());
@@ -204,7 +229,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
204
229
  this.throwWithContext(ctx, 'Operator assignment failed: could not perform operator');
205
230
  }
206
231
  if (trailers.length === 0) {
207
- this.getExecutor().scope.variables.set(reference.name, newValue);
232
+ this.getExecutor().scope.setVariable(reference.name, newValue);
208
233
  }
209
234
  else {
210
235
  if (reference.value instanceof ClassComponent) {
@@ -221,8 +246,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
221
246
  if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
222
247
  this.throwWithContext(ctx, "Invalid assignment expression!");
223
248
  }
224
- this.visit(ctx);
225
- const reference = this.getResult(ctx);
249
+ const reference = this.visitResult(ctx);
226
250
  const { trailers = [] } = reference;
227
251
  const undefinedParentWithTrailers = trailers.length > 0
228
252
  && reference.parentValue === undefined;
@@ -245,11 +269,11 @@ export class BaseVisitor extends CircuitScriptVisitor {
245
269
  }
246
270
  }
247
271
  if (this.pinTypesList.indexOf(atomId) !== -1) {
248
- currentReference = {
272
+ currentReference = new AnyReference({
249
273
  found: true,
250
274
  value: atomId,
251
275
  type: ReferenceTypes.pinType,
252
- };
276
+ });
253
277
  }
254
278
  else {
255
279
  currentReference = executor.resolveVariable(this.executionStack, atomId, idTrailers);
@@ -266,9 +290,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
266
290
  this.setResult(ctx, currentReference);
267
291
  };
268
292
  visitFunctionCallExpr = (ctx) => {
269
- const tmpCtx = ctx.function_call_expr();
270
- this.visit(tmpCtx);
271
- const result = this.getResult(tmpCtx);
293
+ const result = this.visitResult(ctx.function_call_expr());
272
294
  this.setResult(ctx, result);
273
295
  };
274
296
  visitFunction_call_expr = (ctx) => {
@@ -298,12 +320,18 @@ export class BaseVisitor extends CircuitScriptVisitor {
298
320
  const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
299
321
  try {
300
322
  const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
301
- currentReference = {
302
- found: true,
303
- value: functionResult,
304
- type: (functionResult instanceof ClassComponent) ?
305
- 'instance' : 'value',
306
- };
323
+ if (isReference(functionResult)) {
324
+ currentReference = functionResult;
325
+ }
326
+ else {
327
+ currentReference = new AnyReference({
328
+ found: true,
329
+ value: functionResult,
330
+ trailers: [],
331
+ type: (functionResult instanceof ClassComponent) ?
332
+ ReferenceTypes.instance : ReferenceTypes.value,
333
+ });
334
+ }
307
335
  }
308
336
  catch (err) {
309
337
  this.throwWithContext(ctx, err);
@@ -314,7 +342,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
314
342
  }
315
343
  });
316
344
  }
317
- this.setResult(ctx, currentReference.value);
345
+ this.setResult(ctx, currentReference);
318
346
  };
319
347
  visitValue_expr = (ctx) => {
320
348
  const sign = ctx.Minus() ? -1 : 1;
@@ -412,13 +440,11 @@ export class BaseVisitor extends CircuitScriptVisitor {
412
440
  const keywordAssignmentExpressions = ctx.keyword_assignment_expr();
413
441
  const returnList = [];
414
442
  dataExpressions.forEach((item, index) => {
415
- this.visit(item);
416
- const value = this.getResult(item);
443
+ const value = this.visitResult(item);
417
444
  returnList.push(['position', index, value]);
418
445
  });
419
446
  keywordAssignmentExpressions.forEach((item) => {
420
- this.visit(item);
421
- const [key, value] = this.getResult(item);
447
+ const [key, value] = this.visitResult(item);
422
448
  returnList.push(['keyword', key, value]);
423
449
  });
424
450
  this.setResult(ctx, returnList);
@@ -556,12 +582,13 @@ export class BaseVisitor extends CircuitScriptVisitor {
556
582
  const tmpFuncArg = funcDefinedParameters[i];
557
583
  if (i < passedInParameters.length) {
558
584
  const tmpPassedInArgs = passedInParameters[i];
585
+ const argValue = prepareValue(tmpPassedInArgs[2]);
559
586
  if (tmpPassedInArgs[0] === 'position') {
560
587
  const variableName = tmpFuncArg[0];
561
588
  executor.log('set variable in scope, var name: ', variableName);
562
- executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
563
- if (tmpPassedInArgs[2] instanceof ClassComponent) {
564
- const component = tmpPassedInArgs[2];
589
+ executor.scope.setVariable(variableName, argValue);
590
+ if (argValue instanceof ClassComponent) {
591
+ const component = argValue;
565
592
  for (const [pinNumber, net] of component.pinNets) {
566
593
  executor.scope.setNet(component, pinNumber, net);
567
594
  }
@@ -570,14 +597,14 @@ export class BaseVisitor extends CircuitScriptVisitor {
570
597
  else if (tmpPassedInArgs[0] === 'keyword') {
571
598
  const variableName = tmpPassedInArgs[1];
572
599
  executor.log('set variable in scope, var name: ', variableName);
573
- executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
600
+ executor.scope.setVariable(variableName, argValue);
574
601
  }
575
602
  }
576
603
  else if (tmpFuncArg.length === 3) {
577
604
  const variableName = tmpFuncArg[0];
578
605
  const defaultValue = tmpFuncArg[2];
579
606
  executor.log('set variable in scope, var name: ', variableName);
580
- executor.scope.variables.set(variableName, defaultValue);
607
+ executor.scope.setVariable(variableName, defaultValue);
581
608
  }
582
609
  else {
583
610
  throw `Invalid arguments got: ` + passedInParameters;
@@ -102,6 +102,11 @@ export class SemanticTokensVisitor extends BaseVisitor {
102
102
  visitImport_expr = (ctx) => {
103
103
  this.addSemanticToken(ctx.ID(), [], 'namespace');
104
104
  };
105
+ visitFor_expr = (ctx) => {
106
+ ctx.ID().forEach(item => {
107
+ this.addSemanticToken(item, [], 'variable');
108
+ });
109
+ };
105
110
  addSemanticToken(node, modifiers, tokenType = null) {
106
111
  const parsedToken = this.parseToken(node, modifiers, tokenType);
107
112
  this.semanticTokens.set(parsedToken.line + "_" + parsedToken.column, parsedToken);
@@ -184,7 +189,7 @@ const languageKeywords = [
184
189
  'break', 'branch', 'create', 'component',
185
190
  'graphic', 'wire', 'pin', 'add', 'at', 'to',
186
191
  'point', 'join', 'parallel', 'return', 'def', 'import',
187
- 'true', 'false', 'nc', 'sheet', 'frame', 'if', 'for',
192
+ 'true', 'false', 'nc', 'sheet', 'frame', 'if', 'else', 'for', 'in',
188
193
  ];
189
194
  const operatorKeywords = [
190
195
  'at', 'to', 'wire', 'add', 'frame', 'join', 'parallel', 'point'