circuitscript 0.0.24 → 0.0.25

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 (63) hide show
  1. package/dist/cjs/BaseVisitor.js +487 -0
  2. package/dist/cjs/SemanticTokenVisitor.js +218 -0
  3. package/dist/cjs/SymbolValidatorVisitor.js +233 -0
  4. package/dist/cjs/antlr/CircuitScriptLexer.js +209 -195
  5. package/dist/cjs/antlr/CircuitScriptParser.js +2310 -2087
  6. package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
  7. package/dist/cjs/draw_symbols.js +67 -22
  8. package/dist/cjs/execute.js +51 -53
  9. package/dist/cjs/geometry.js +28 -8
  10. package/dist/cjs/helpers.js +175 -5
  11. package/dist/cjs/index.js +2 -0
  12. package/dist/cjs/layout.js +8 -0
  13. package/dist/cjs/lexer.js +19 -22
  14. package/dist/cjs/main.js +6 -11
  15. package/dist/cjs/objects/ClassComponent.js +3 -0
  16. package/dist/cjs/objects/ExecutionScope.js +1 -0
  17. package/dist/cjs/objects/types.js +7 -1
  18. package/dist/cjs/parser.js +29 -258
  19. package/dist/cjs/validate.js +81 -0
  20. package/dist/cjs/visitor.js +529 -820
  21. package/dist/esm/BaseVisitor.mjs +488 -0
  22. package/dist/esm/SemanticTokenVisitor.mjs +215 -0
  23. package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
  24. package/dist/esm/antlr/CircuitScriptLexer.mjs +184 -194
  25. package/dist/esm/antlr/CircuitScriptParser.mjs +2279 -2084
  26. package/dist/esm/antlr/CircuitScriptVisitor.mjs +8 -3
  27. package/dist/esm/draw_symbols.mjs +67 -22
  28. package/dist/esm/execute.mjs +50 -52
  29. package/dist/esm/geometry.mjs +28 -8
  30. package/dist/esm/helpers.mjs +165 -6
  31. package/dist/esm/index.mjs +2 -0
  32. package/dist/esm/layout.mjs +8 -0
  33. package/dist/esm/lexer.mjs +10 -10
  34. package/dist/esm/main.mjs +7 -12
  35. package/dist/esm/objects/ClassComponent.mjs +3 -0
  36. package/dist/esm/objects/ExecutionScope.mjs +1 -0
  37. package/dist/esm/objects/types.mjs +6 -0
  38. package/dist/esm/parser.mjs +25 -230
  39. package/dist/esm/validate.mjs +74 -0
  40. package/dist/esm/visitor.mjs +343 -640
  41. package/dist/types/BaseVisitor.d.ts +69 -0
  42. package/dist/types/SemanticTokenVisitor.d.ts +36 -0
  43. package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
  44. package/dist/types/antlr/CircuitScriptLexer.d.ts +8 -7
  45. package/dist/types/antlr/CircuitScriptParser.d.ts +513 -469
  46. package/dist/types/antlr/CircuitScriptVisitor.d.ts +69 -59
  47. package/dist/types/draw_symbols.d.ts +9 -0
  48. package/dist/types/execute.d.ts +5 -8
  49. package/dist/types/geometry.d.ts +4 -0
  50. package/dist/types/helpers.d.ts +32 -1
  51. package/dist/types/index.d.ts +2 -0
  52. package/dist/types/lexer.d.ts +2 -2
  53. package/dist/types/objects/ExecutionScope.d.ts +4 -1
  54. package/dist/types/objects/types.d.ts +5 -0
  55. package/dist/types/parser.d.ts +15 -28
  56. package/dist/types/validate.d.ts +2 -0
  57. package/dist/types/visitor.d.ts +40 -95
  58. package/fonts/Inter-Bold.ttf +0 -0
  59. package/fonts/Inter-Regular.ttf +0 -0
  60. package/fonts/OpenSans-Regular.ttf +0 -0
  61. package/fonts/Roboto-Regular.ttf +0 -0
  62. package/libs/lib.cst +183 -0
  63. package/package.json +11 -6
@@ -1,239 +1,87 @@
1
- import { ParseTreeVisitor } from 'antlr4';
2
- import { readFileSync } from 'fs';
3
- import { join } from 'path';
4
- import { ExecutionContext } from './execute.mjs';
1
+ import { isNetOnlyComponent } from './execute.mjs';
5
2
  import { ClassComponent } from './objects/ClassComponent.mjs';
6
- import { NumericValue, ParamDefinition, PercentageValue, PinBlankValue, } from './objects/ParamDefinition.mjs';
3
+ import { NumericValue, ParamDefinition, } from './objects/ParamDefinition.mjs';
7
4
  import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
8
5
  import { PinTypes } from './objects/PinTypes.mjs';
9
6
  import { UndeclaredReference } from './objects/types.mjs';
10
- import { Logger } from './logger.mjs';
11
7
  import { BlockTypes, ComponentTypes, NoNetText } from './globals.mjs';
12
8
  import { SymbolDrawingCommands } from './draw_symbols.mjs';
13
- import { parseFileWithVisitor } from './parser.mjs';
14
- export class MainVisitor extends ParseTreeVisitor {
15
- indentLevel = 0;
16
- startingContext;
17
- executionStack;
18
- silent = false;
19
- logger;
20
- printStream = [];
21
- printToConsole = true;
22
- acceptedDirections = ['left', 'right', 'up', 'down'];
23
- pinTypesList = [
24
- PinTypes.Any,
25
- PinTypes.Input,
26
- PinTypes.Output,
27
- PinTypes.IO,
28
- PinTypes.Power,
29
- ];
30
- onImportFile = (visitor, filePath) => {
31
- throw "Import file not implemented";
32
- };
33
- constructor(silent = false) {
34
- super();
35
- this.logger = new Logger();
36
- this.startingContext = new ExecutionContext('__', '__.', '/', 0, 0, silent, this.logger);
37
- this.setupPrintFunction(this.startingContext);
38
- this.executionStack = [this.startingContext];
39
- this.startingContext.resolveNet =
40
- this.createNetResolver(this.executionStack);
41
- this.silent = silent;
42
- }
43
- getExecutor() {
44
- return this.executionStack[this.executionStack.length - 1];
45
- }
46
- visit(ctx) {
47
- if (Array.isArray(ctx)) {
48
- return ctx.map(function (child) {
49
- try {
50
- return child.accept(this);
51
- }
52
- catch (err) {
53
- this.handleError(child, err);
54
- }
55
- }, this);
56
- }
57
- else {
58
- try {
59
- return ctx.accept(this);
60
- }
61
- catch (err) {
62
- this.handleError(ctx, err);
63
- }
64
- }
65
- }
66
- handleError(ctx, err) {
67
- if (!(err instanceof VisitorExecutionException)) {
68
- throw new VisitorExecutionException(ctx, err);
69
- }
70
- else {
71
- throw err;
72
- }
73
- }
74
- visitScript(ctx) {
75
- this.print('===', 'start', '===');
76
- const result = this.visitChildren(ctx);
77
- this.print('===', 'end', '===');
78
- return result;
79
- }
80
- visitParameters(ctx) {
81
- const dataExpressions = ctx.data_expr_list();
82
- const keywordAssignmentExpressions = ctx.keyword_assignment_expr_list();
83
- const returnList = [];
84
- dataExpressions.forEach((item, index) => {
85
- const value = this.visit(item);
86
- returnList.push(['position', index, value]);
87
- });
88
- keywordAssignmentExpressions.forEach((item) => {
89
- const [key, value] = this.visit(item);
90
- returnList.push(['keyword', key, value]);
91
- });
92
- return returnList;
93
- }
94
- visitKeyword_assignment_expr(ctx) {
9
+ import { BaseVisitor } from './BaseVisitor.mjs';
10
+ export class ParserVisitor extends BaseVisitor {
11
+ visitKeyword_assignment_expr = (ctx) => {
95
12
  const id = ctx.ID().getText();
96
- const value = this.visit(ctx.data_expr());
97
- return [id, value];
98
- }
99
- visitAssignment_expr(ctx) {
100
- const atomStr = ctx.atom_expr().getText();
101
- if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
102
- throw "Invalid assignment expression!";
103
- }
104
- const reference = this.visit(ctx.atom_expr());
105
- const value = this.visit(ctx.data_expr());
106
- if (value instanceof ClassComponent) {
107
- const instances = this.getExecutor().scope.instances;
108
- const tmpComponent = value;
109
- const oldName = tmpComponent.instanceName;
110
- tmpComponent.instanceName = reference.name;
111
- instances.delete(oldName);
112
- instances.set(reference.name, tmpComponent);
113
- this.getExecutor().print(`assigned '${reference.name}' to ClassComponent`);
114
- }
115
- else {
116
- const trailers = reference.trailers ?? [];
117
- if (trailers.length === 0) {
118
- this.getExecutor().scope.variables.set(reference.name, value);
119
- }
120
- else if (reference.value instanceof ClassComponent) {
121
- this.setInstanceParam(reference.value, trailers, value);
122
- }
123
- }
124
- return value;
125
- }
126
- setInstanceParam(object, trailers, value) {
127
- const paramName = trailers[0].slice(1);
128
- object.setParam(paramName, value);
129
- this.getExecutor().print(`set instance ${object.instanceName} param ${paramName} to ${value}`);
130
- }
131
- visitValue_expr(ctx) {
132
- const sign = ctx.Minus() ? -1 : 1;
133
- if (ctx.INTEGER_VALUE() || ctx.DECIMAL_VALUE() || ctx.NUMERIC_VALUE()) {
134
- if (ctx.INTEGER_VALUE()) {
135
- return sign * Number(ctx.INTEGER_VALUE().getText());
136
- }
137
- else if (ctx.DECIMAL_VALUE()) {
138
- return sign * Number(ctx.DECIMAL_VALUE().getText());
139
- }
140
- else if (ctx.NUMERIC_VALUE()) {
141
- const textExtra = ctx.Minus() ? '-' : '';
142
- return new NumericValue(textExtra + ctx.NUMERIC_VALUE().getText());
143
- }
144
- }
145
- else {
146
- if (sign === -1) {
147
- throw "Invalid value!";
148
- }
149
- }
150
- if (ctx.BOOLEAN_VALUE()) {
151
- const stringValue = ctx.BOOLEAN_VALUE().getText();
152
- if (stringValue === 'true') {
153
- return true;
154
- }
155
- else if (stringValue === 'false') {
156
- return false;
157
- }
158
- }
159
- else if (ctx.STRING_VALUE()) {
160
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
161
- }
162
- else if (ctx.PERCENTAGE_VALUE()) {
163
- return new PercentageValue(ctx.PERCENTAGE_VALUE().getText());
164
- }
165
- else if (ctx.blank_expr()) {
166
- return this.visit(ctx.blank_expr());
167
- }
168
- }
169
- visitBlank_expr(ctx) {
170
- return new PinBlankValue(Number(ctx.INTEGER_VALUE().getText()));
171
- }
172
- visitPin_select_expr(ctx) {
173
- if (ctx.INTEGER_VALUE()) {
174
- return Number(ctx.INTEGER_VALUE().getText());
175
- }
176
- else if (ctx.STRING_VALUE()) {
177
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
13
+ const ctxDataExpr = ctx.data_expr();
14
+ this.visit(ctxDataExpr);
15
+ const value = this.getResult(ctxDataExpr);
16
+ this.setResult(ctx, [id, value]);
17
+ };
18
+ visitPin_select_expr = (ctx) => {
19
+ let value = null;
20
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
21
+ const ctxStringValue = ctx.STRING_VALUE();
22
+ if (ctxIntegerValue) {
23
+ value = Number(ctxIntegerValue.getText());
178
24
  }
179
- return null;
180
- }
181
- visitAdd_component_expr(ctx) {
182
- const [component, pinValue] = this.visit(ctx.data_expr_with_assignment());
183
- if (ctx.ID()) {
184
- this.setComponentOrientation(component, pinValue, ctx.ID().getText());
25
+ else if (ctxStringValue) {
26
+ value = this.prepareStringValue(ctxStringValue.getText());
185
27
  }
28
+ this.setResult(ctx, value);
29
+ };
30
+ visitAdd_component_expr = (ctx) => {
31
+ const ctxDataWithAssignmentExpr = ctx.data_expr_with_assignment();
32
+ this.setParam(ctxDataWithAssignmentExpr, { clone: false });
33
+ this.visit(ctxDataWithAssignmentExpr);
34
+ const [component, pinValue] = this.getResult(ctxDataWithAssignmentExpr);
186
35
  return this.getExecutor().addComponentExisting(component, pinValue);
187
- }
188
- visitAt_component_expr(ctx) {
36
+ };
37
+ visitAt_component_expr = (ctx) => {
189
38
  if (ctx.Point()) {
190
39
  this.getExecutor().atPointBlock();
191
40
  }
192
41
  else {
193
- const [component, pin] = this.visit(ctx.component_select_expr());
194
- const currentPoint = this.getExecutor().atComponent(component, pin, {
195
- addSequence: true,
196
- cloneNetComponent: true
42
+ const ctxComponentSelectExpr = ctx.component_select_expr();
43
+ this.visit(ctxComponentSelectExpr);
44
+ const [component, pin] = this.getResult(ctxComponentSelectExpr);
45
+ this.getExecutor().atComponent(component, pin, {
46
+ addSequence: true
197
47
  });
198
- if (ctx.ID()) {
199
- this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
200
- }
201
48
  }
202
49
  return this.getExecutor().getCurrentPoint();
203
- }
204
- visitTo_component_expr(ctx) {
205
- let currentPoint;
50
+ };
51
+ visitTo_component_expr = (ctx) => {
206
52
  if (ctx.Point()) {
207
53
  this.getExecutor().toPointBlock();
208
54
  }
209
55
  else {
210
- ctx.component_select_expr_list().forEach((item) => {
211
- const [component, pin] = this.visit(item);
212
- currentPoint = this.getExecutor().toComponent(component, pin, {
213
- addSequence: true, cloneNetComponent: true
56
+ ctx.component_select_expr().forEach(item => {
57
+ this.visit(item);
58
+ const [component, pin] = this.getResult(item);
59
+ this.getExecutor().toComponent(component, pin, {
60
+ addSequence: true
214
61
  });
215
62
  });
216
- if (ctx.ID()) {
217
- this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
218
- }
219
63
  }
220
64
  return this.getExecutor().getCurrentPoint();
221
- }
222
- visitComponent_select_expr(ctx) {
223
- if (ctx.data_expr_with_assignment()) {
224
- return this.visit(ctx.data_expr_with_assignment());
65
+ };
66
+ visitComponent_select_expr = (ctx) => {
67
+ const ctxDataExprWithAssigment = ctx.data_expr_with_assignment();
68
+ if (ctxDataExprWithAssigment) {
69
+ this.visit(ctxDataExprWithAssigment);
70
+ this.setResult(ctx, this.getResult(ctxDataExprWithAssigment));
225
71
  }
226
72
  else {
227
73
  const component = this.getExecutor().scope.currentComponent;
228
74
  let pinId = null;
229
- if (ctx.pin_select_expr()) {
230
- pinId = this.visit(ctx.pin_select_expr());
75
+ const ctxPinSelectExpr = ctx.pin_select_expr();
76
+ if (ctxPinSelectExpr) {
77
+ this.visit(ctxPinSelectExpr);
78
+ pinId = this.getResult(ctxPinSelectExpr);
231
79
  }
232
- return [component, pinId];
80
+ this.setResult(ctx, [component, pinId]);
233
81
  }
234
- }
235
- visitPath_blocks(ctx) {
236
- const blocks = ctx.path_block_inner_list();
82
+ };
83
+ visitPath_blocks = (ctx) => {
84
+ const blocks = ctx.path_block_inner();
237
85
  let blockIndex = 0;
238
86
  let blockType = BlockTypes.Branch;
239
87
  let prevBlockType = null;
@@ -265,13 +113,9 @@ export class MainVisitor extends ParseTreeVisitor {
265
113
  });
266
114
  this.getExecutor().exitBlocks();
267
115
  return this.getExecutor().getCurrentPoint();
268
- }
269
- visitBreak_keyword() {
270
- this.getExecutor().breakBranch();
271
- return -1;
272
- }
273
- visitCreate_component_expr(ctx) {
274
- const properties = this.getPropertyExprList(ctx.property_expr_list());
116
+ };
117
+ visitCreate_component_expr = (ctx) => {
118
+ const properties = this.getPropertyExprList(ctx.property_expr());
275
119
  const pins = this.parseCreateComponentPins(properties.get('pins'));
276
120
  let instanceName = this.getExecutor().getUniqueInstanceName('');
277
121
  const propParams = properties.get('params');
@@ -299,11 +143,12 @@ export class MainVisitor extends ParseTreeVisitor {
299
143
  type,
300
144
  width,
301
145
  };
302
- return this.getExecutor().createComponent(instanceName, pins, params, props);
303
- }
304
- visitCreate_graphic_expr(ctx) {
305
- const commands = ctx.sub_expr_list().reduce((accum, item) => {
306
- const [commandName, parameters] = this.visit(item);
146
+ this.setResult(ctx, this.getExecutor().createComponent(instanceName, pins, params, props));
147
+ };
148
+ visitCreate_graphic_expr = (ctx) => {
149
+ const commands = ctx.sub_expr().reduce((accum, item) => {
150
+ this.visit(item);
151
+ const [commandName, parameters] = this.getResult(item);
307
152
  const keywordParams = new Map();
308
153
  const positionParams = parameters.reduce((accum, [argType, name, value]) => {
309
154
  if (argType === 'position') {
@@ -317,100 +162,144 @@ export class MainVisitor extends ParseTreeVisitor {
317
162
  accum.push([commandName, positionParams, keywordParams]);
318
163
  return accum;
319
164
  }, []);
320
- return new SymbolDrawingCommands(commands);
321
- }
322
- visitSub_expr(ctx) {
165
+ const drawing = new SymbolDrawingCommands(commands);
166
+ drawing.source = ctx.getText();
167
+ this.setResult(ctx, drawing);
168
+ };
169
+ visitSub_expr = (ctx) => {
323
170
  let commandName = null;
324
- if (ctx.ID()) {
325
- commandName = ctx.ID().getText();
326
- }
327
- else if (ctx.Pin()) {
328
- commandName = ctx.Pin().getText();
171
+ const command = ctx._command;
172
+ if (command) {
173
+ commandName = command.text;
329
174
  }
330
175
  else {
331
176
  throw "Invalid command!";
332
177
  }
333
- const parameters = this.visit(ctx.parameters());
334
- return [commandName, parameters];
335
- }
336
- visitProperty_expr(ctx) {
337
- const keyName = this.visit(ctx.property_key_expr());
338
- const value = this.visit(ctx.property_value_expr());
178
+ const ctxParameters = ctx.parameters();
179
+ this.visit(ctxParameters);
180
+ const parameters = this.getResult(ctxParameters);
181
+ this.setResult(ctx, [commandName, parameters]);
182
+ };
183
+ visitProperty_expr = (ctx) => {
184
+ const ctxPropertyKeyExpr = ctx.property_key_expr();
185
+ const ctxPropertyValueExpr = ctx.property_value_expr();
186
+ this.visit(ctxPropertyKeyExpr);
187
+ this.visit(ctxPropertyValueExpr);
188
+ const keyName = this.getResult(ctxPropertyKeyExpr);
189
+ const value = this.getResult(ctxPropertyValueExpr);
339
190
  const map = new Map();
340
191
  map.set(keyName, value);
341
- return map;
342
- }
343
- visitSingle_line_property(ctx) {
192
+ this.setResult(ctx, map);
193
+ };
194
+ visitSingle_line_property = (ctx) => {
344
195
  let value;
345
- if (ctx.data_expr_list().length === 1) {
346
- value = this.visit(ctx.data_expr(0));
196
+ if (ctx.data_expr().length === 1) {
197
+ const ctxFirst = ctx.data_expr(0);
198
+ this.visit(ctxFirst);
199
+ value = this.getResult(ctxFirst);
347
200
  }
348
201
  else {
349
- value = ctx.data_expr_list().map(item => {
350
- return this.visit(item);
202
+ value = ctx.data_expr().map(item => {
203
+ this.visit(item);
204
+ return this.getResult(item);
351
205
  });
352
206
  }
353
- return value;
354
- }
355
- visitNested_properties(ctx) {
207
+ this.setResult(ctx, value);
208
+ };
209
+ visitNested_properties = (ctx) => {
356
210
  const result = new Map();
357
- ctx.property_expr_list().forEach((item) => {
358
- const property = this.visit(item);
211
+ ctx.property_expr().forEach((item) => {
212
+ this.visit(item);
213
+ const property = this.getResult(item);
359
214
  for (const [key, value] of property) {
360
215
  result.set(key, value);
361
216
  }
362
217
  });
363
- return result;
364
- }
365
- visitProperty_key_expr(ctx) {
366
- if (ctx.ID()) {
367
- return ctx.ID().getText();
218
+ this.setResult(ctx, result);
219
+ };
220
+ visitProperty_key_expr = (ctx) => {
221
+ const ctxID = ctx.ID();
222
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
223
+ const ctxStringValue = ctx.STRING_VALUE();
224
+ let result = null;
225
+ if (ctxID) {
226
+ result = ctxID.getText();
368
227
  }
369
- else if (ctx.INTEGER_VALUE()) {
370
- return Number(ctx.INTEGER_VALUE().getText());
228
+ else if (ctxIntegerValue) {
229
+ result = Number(ctxIntegerValue.getText());
371
230
  }
372
- else if (ctx.STRING_VALUE()) {
373
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
231
+ else if (ctxStringValue) {
232
+ result = this.prepareStringValue(ctxStringValue.getText());
374
233
  }
375
- }
376
- visitData_expr_with_assignment(ctx) {
377
- let component;
378
- if (ctx.data_expr()) {
379
- component = this.visit(ctx.data_expr());
234
+ this.setResult(ctx, result);
235
+ };
236
+ visitData_expr_with_assignment = (ctx) => {
237
+ let component = null;
238
+ const ctxDataExpr = ctx.data_expr();
239
+ const ctxAssignmentExpr = ctx.assignment_expr();
240
+ if (ctxDataExpr) {
241
+ this.visit(ctxDataExpr);
242
+ component = this.getResult(ctxDataExpr);
380
243
  if (component === null || component === undefined) {
381
- throw "Could not find component: " + ctx.data_expr().getText();
382
- }
383
- }
384
- else if (ctx.assignment_expr()) {
385
- component = this.visit(ctx.assignment_expr());
244
+ throw "Could not find component: " + ctxDataExpr.getText();
245
+ }
246
+ }
247
+ else if (ctxAssignmentExpr) {
248
+ this.visit(ctxAssignmentExpr);
249
+ component = this.getResult(ctxAssignmentExpr);
250
+ }
251
+ let allowClone = true;
252
+ if (this.hasParam(ctx)) {
253
+ const { clone } = this.getParam(ctx);
254
+ allowClone = clone;
255
+ }
256
+ if (allowClone && component instanceof ClassComponent
257
+ && isNetOnlyComponent(component)) {
258
+ component = this.getExecutor().cloneComponent(component);
259
+ }
260
+ if (component && component instanceof ClassComponent) {
261
+ const modifiers = ctx.component_modifier_expr();
262
+ modifiers.forEach(modifier => {
263
+ const modifierText = modifier.ID(0).getText();
264
+ const ctxValueExpr = modifier.value_expr();
265
+ const ctxID2 = modifier.ID(1);
266
+ let result = null;
267
+ if (ctxValueExpr) {
268
+ this.visit(ctxValueExpr);
269
+ result = this.getResult(ctxValueExpr);
270
+ }
271
+ else if (ctxID2) {
272
+ result = ctxID2.getText();
273
+ }
274
+ if (modifierText === 'flip') {
275
+ const flipValue = result;
276
+ if (flipValue.indexOf('x') !== -1) {
277
+ component.setParam('flipX', 1);
278
+ }
279
+ if (flipValue.indexOf('y') !== -1) {
280
+ component.setParam('flipY', 1);
281
+ }
282
+ }
283
+ else if (modifierText === 'angle') {
284
+ const angleValue = Number(result);
285
+ component.setParam('angle', angleValue);
286
+ }
287
+ });
386
288
  }
387
289
  let pinValue = null;
388
- if (ctx.pin_select_expr()) {
389
- pinValue = this.visit(ctx.pin_select_expr());
290
+ const ctxPinSelectExpr = ctx.pin_select_expr();
291
+ if (ctxPinSelectExpr) {
292
+ this.visit(ctxPinSelectExpr);
293
+ pinValue = this.getResult(ctxPinSelectExpr);
390
294
  }
391
295
  else {
392
296
  pinValue = component.getDefaultPin();
393
297
  }
394
- return [component, pinValue];
395
- }
396
- visitValueAtomExpr(ctx) {
397
- let value;
398
- if (ctx.value_expr()) {
399
- value = this.visit(ctx.value_expr());
400
- }
401
- else if (ctx.atom_expr()) {
402
- const reference = this.visit(ctx.atom_expr());
403
- if (!reference.found) {
404
- value = new UndeclaredReference(reference);
405
- }
406
- else {
407
- value = reference.value;
408
- }
409
- }
410
- return value;
411
- }
412
- visitUnaryOperatorExpr(ctx) {
413
- const value = this.visit(ctx.data_expr());
298
+ this.setResult(ctx, [component, pinValue]);
299
+ };
300
+ visitUnaryOperatorExpr = (ctx) => {
301
+ this.visit(ctx.data_expr());
302
+ let value = this.getResult(ctx.data_expr());
414
303
  const unaryOp = ctx.unary_operator();
415
304
  if (unaryOp) {
416
305
  if (unaryOp.Not()) {
@@ -423,334 +312,234 @@ export class MainVisitor extends ParseTreeVisitor {
423
312
  }
424
313
  else if (unaryOp.Minus()) {
425
314
  if (typeof value === 'number') {
426
- return -value;
315
+ value = -value;
427
316
  }
428
317
  else {
429
318
  throw "Failed to do Negation operator";
430
319
  }
431
320
  }
432
321
  }
433
- return value;
434
- }
435
- visitDataExpr(ctx) {
322
+ this.setResult(ctx, value);
323
+ };
324
+ visitDataExpr = (ctx) => {
436
325
  let value;
437
- if (ctx.create_component_expr()) {
438
- value = this.visit(ctx.create_component_expr());
326
+ const ctxCreateComponentExpr = ctx.create_component_expr();
327
+ const ctxCreateGraphicExpr = ctx.create_graphic_expr();
328
+ if (ctxCreateComponentExpr) {
329
+ this.visit(ctxCreateComponentExpr);
330
+ value = this.getResult(ctxCreateComponentExpr);
439
331
  }
440
- else if (ctx.create_graphic_expr()) {
441
- value = this.visit(ctx.create_graphic_expr());
332
+ else if (ctxCreateGraphicExpr) {
333
+ this.visit(ctxCreateGraphicExpr);
334
+ value = this.getResult(ctxCreateGraphicExpr);
442
335
  }
443
- return value;
444
- }
445
- visitBinaryOperatorExpr(ctx) {
446
- const value1 = this.visit(ctx.data_expr(0));
447
- const value2 = this.visit(ctx.data_expr(1));
336
+ else {
337
+ throw "Invalid data expression";
338
+ }
339
+ this.setResult(ctx, value);
340
+ };
341
+ visitBinaryOperatorExpr = (ctx) => {
342
+ const ctx0 = ctx.data_expr(0);
343
+ const ctx1 = ctx.data_expr(1);
344
+ this.visit(ctx0);
345
+ this.visit(ctx1);
346
+ const value1 = this.getResult(ctx0);
347
+ const value2 = this.getResult(ctx1);
448
348
  const binaryOperatorType = ctx.binary_operator();
349
+ let result = null;
449
350
  if (binaryOperatorType.Equals()) {
450
- return value1 == value2;
351
+ result = value1 == value2;
451
352
  }
452
353
  else if (binaryOperatorType.NotEquals()) {
453
- return value1 != value2;
354
+ result = value1 != value2;
454
355
  }
455
- }
456
- visitMultiplyExpr(ctx) {
457
- const value1 = this.visit(ctx.data_expr(0));
458
- const value2 = this.visit(ctx.data_expr(1));
356
+ this.setResult(ctx, result);
357
+ };
358
+ visitMultiplyExpr = (ctx) => {
359
+ this.visit(ctx.data_expr(0));
360
+ this.visit(ctx.data_expr(1));
361
+ const value1 = this.getResult(ctx.data_expr(0));
362
+ const value2 = this.getResult(ctx.data_expr(1));
363
+ let result = null;
459
364
  if (ctx.Multiply()) {
460
- return value1 * value2;
365
+ result = value1 * value2;
461
366
  }
462
367
  else if (ctx.Divide()) {
463
- return value1 / value2;
368
+ result = value1 / value2;
464
369
  }
465
- }
466
- visitAdditionExpr(ctx) {
467
- const value1 = this.visit(ctx.data_expr(0));
468
- const value2 = this.visit(ctx.data_expr(1));
370
+ this.setResult(ctx, result);
371
+ };
372
+ visitAdditionExpr = (ctx) => {
373
+ this.visit(ctx.data_expr(0));
374
+ this.visit(ctx.data_expr(1));
375
+ const value1 = this.getResult(ctx.data_expr(0));
376
+ const value2 = this.getResult(ctx.data_expr(1));
377
+ let result = null;
469
378
  if (ctx.Addition()) {
470
- return value1 + value2;
379
+ result = value1 + value2;
471
380
  }
472
381
  else if (ctx.Minus()) {
473
- return value1 - value2;
382
+ result = value1 - value2;
474
383
  }
475
- }
476
- visitFunction_args_expr(ctx) {
477
- const defaultValuesProvided = ctx.value_expr_list();
478
- const IDs = ctx.ID_list();
479
- const boundary = IDs.length - defaultValuesProvided.length;
480
- return IDs.map((id, index) => {
481
- if (index >= boundary) {
482
- const defaultValue = this.visit(defaultValuesProvided[index - boundary]);
483
- return [id.getText(), defaultValue];
484
- }
485
- else {
486
- return [id.getText()];
487
- }
488
- });
489
- }
490
- createNetResolver(executionStack) {
491
- const resolveNet = (netName, netNamespace) => {
492
- this.print('find net', netNamespace, netName);
493
- const reversed = [...executionStack].reverse();
494
- for (let i = 0; i < reversed.length; i++) {
495
- const context = reversed[i];
496
- const net = context.scope.getNetWithName(netName);
497
- if (net !== null && net.namespace === netNamespace) {
498
- return {
499
- found: true,
500
- net,
501
- };
502
- }
503
- }
504
- return {
505
- found: false
506
- };
507
- };
508
- return resolveNet;
509
- }
510
- visitFunction_def_expr(ctx) {
384
+ this.setResult(ctx, result);
385
+ };
386
+ visitFunction_def_expr = (ctx) => {
511
387
  const functionName = ctx.ID().getText();
512
388
  let funcDefinedParameters = [];
513
- if (ctx.function_args_expr()) {
514
- funcDefinedParameters = this.visit(ctx.function_args_expr());
389
+ const ctxFunctionArgsExpr = ctx.function_args_expr();
390
+ if (ctxFunctionArgsExpr) {
391
+ this.visit(ctxFunctionArgsExpr);
392
+ funcDefinedParameters = this.getResult(ctxFunctionArgsExpr);
515
393
  }
516
394
  const executionStack = this.executionStack;
517
395
  const functionCounter = { counter: 0 };
518
396
  const resolveNet = this.createNetResolver(this.executionStack);
519
397
  const __runFunc = (passedInParameters, options) => {
520
- const { netNamespace = "" } = options;
521
- const currentExecutionContext = executionStack[executionStack.length - 1];
522
- const executionLevel = currentExecutionContext.executionLevel;
523
398
  const executionContextName = functionName + '_' + functionCounter['counter'];
524
- const executionContextNamespace = currentExecutionContext.namespace
525
- + executionContextName + ".";
399
+ const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
526
400
  functionCounter['counter'] += 1;
527
- const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger);
528
- this.setupPrintFunction(newExecutor);
529
401
  newExecutor.resolveNet = resolveNet;
530
- executionStack.push(newExecutor);
531
- this.setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, newExecutor);
532
- const returnValue = this.runExpressions(newExecutor, ctx.function_expr_list());
402
+ const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
533
403
  const lastExecution = executionStack.pop();
534
404
  const nextLastExecution = executionStack[executionStack.length - 1];
535
405
  nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
536
406
  return [lastExecution, returnValue];
537
407
  };
538
408
  this.getExecutor().createFunction(functionName, __runFunc);
539
- }
540
- setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, executor) {
541
- for (let i = 0; i < funcDefinedParameters.length; i++) {
542
- const tmpFuncArg = funcDefinedParameters[i];
543
- if (i < passedInParameters.length) {
544
- const tmpPassedInArgs = passedInParameters[i];
545
- if (tmpPassedInArgs[0] === 'position') {
546
- const variableName = tmpFuncArg[0];
547
- executor.print('set variable in scope, var name: ', variableName);
548
- executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
549
- if (tmpPassedInArgs[2] instanceof ClassComponent) {
550
- const component = tmpPassedInArgs[2];
551
- for (const [pinNumber, net] of component.pinNets) {
552
- executor.scope.setNet(component, pinNumber, net);
553
- }
554
- }
555
- }
556
- }
557
- else if (tmpFuncArg.length === 2) {
558
- const variableName = tmpFuncArg[0];
559
- const defaultValue = tmpFuncArg[1];
560
- executor.print('set variable in scope, var name: ', variableName);
561
- executor.scope.variables.set(variableName, defaultValue);
562
- }
563
- else {
564
- throw `Invalid arguments for function '${functionName}', got: `
565
- + passedInParameters;
566
- }
567
- }
568
- }
569
- visitFunction_return_expr(ctx) {
570
- const executor = this.getExecutor();
571
- executor.print('return from function');
572
- const returnValue = this.visit(ctx.data_expr());
573
- executor.stopFurtherExpressions = true;
574
- executor.returnValue = returnValue;
575
- return returnValue;
576
- }
577
- visitAtom_expr(ctx) {
578
- const executor = this.getExecutor();
579
- const atomId = ctx.ID().getText();
580
- let passedNetNamespace = null;
581
- if (ctx.net_namespace_expr()) {
582
- passedNetNamespace = this.visit(ctx.net_namespace_expr());
583
- }
584
- let currentReference;
585
- if (this.pinTypesList.indexOf(atomId) !== -1) {
586
- currentReference = {
587
- found: true,
588
- value: atomId
589
- };
590
- }
591
- else {
592
- currentReference = executor.resolveVariable(this.executionStack, atomId);
593
- }
594
- if (currentReference.found && currentReference.type === 'instance') {
595
- const tmpComponent = currentReference.value;
596
- for (const [pinId, net] of tmpComponent.pinNets) {
597
- executor.scope.setNet(tmpComponent, pinId, net);
598
- }
599
- }
600
- if (ctx.trailer_expr_list().length > 0) {
601
- if (!currentReference.found) {
602
- throw "Could not find reference! " + atomId;
603
- }
604
- currentReference.trailers = [];
605
- ctx.trailer_expr_list().forEach(item => {
606
- const itemValue = item.getText();
607
- if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
608
- let parameters = [];
609
- if (item.parameters()) {
610
- parameters = this.visit(item.parameters());
611
- }
612
- const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
613
- const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
614
- currentReference = {
615
- found: true,
616
- value: functionResult,
617
- type: (functionResult instanceof ClassComponent) ?
618
- 'instance' : 'value',
619
- };
620
- }
621
- else {
622
- currentReference.trailers.push(itemValue);
623
- }
624
- });
625
- }
626
- return currentReference;
627
- }
628
- visitPin_select_expr2(ctx) {
629
- if (ctx.STRING_VALUE()) {
630
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
409
+ };
410
+ visitPin_select_expr2 = (ctx) => {
411
+ const ctxStringValue = ctx.STRING_VALUE();
412
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
413
+ let result = null;
414
+ if (ctxStringValue) {
415
+ result = this.prepareStringValue(ctxStringValue.getText());
631
416
  }
632
- else if (ctx.INTEGER_VALUE()) {
633
- return Number(ctx.INTEGER_VALUE().getText());
417
+ else if (ctxIntegerValue) {
418
+ result = Number(ctxIntegerValue.getText());
634
419
  }
635
- }
636
- visitAt_block_pin_expr(ctx) {
637
- const atPin = this.visit(ctx.pin_select_expr2());
420
+ this.setResult(ctx, result);
421
+ };
422
+ visitAt_block_pin_expr = (ctx) => {
423
+ const ctxPinSelectExpr2 = ctx.pin_select_expr2();
424
+ this.visit(ctxPinSelectExpr2);
425
+ const atPin = this.getResult(ctxPinSelectExpr2);
638
426
  const executor = this.getExecutor();
639
427
  const currentComponent = executor.scope.currentComponent;
640
428
  const currentPin = executor.scope.currentPin;
641
429
  executor.atComponent(currentComponent, atPin, {
642
430
  addSequence: true
643
431
  });
644
- executor.print('at block pin expressions');
645
- if (ctx.at_block_pin_expression_simple()) {
646
- this.visit(ctx.at_block_pin_expression_simple());
432
+ executor.log('at block pin expressions');
433
+ const ctxAtBlockSimple = ctx.at_block_pin_expression_simple();
434
+ const ctxAtBlockComplex = ctx.at_block_pin_expression_complex();
435
+ if (ctxAtBlockSimple) {
436
+ this.visit(ctxAtBlockSimple);
647
437
  }
648
- else if (ctx.at_block_pin_expression_complex()) {
649
- this.visit(ctx.at_block_pin_expression_complex());
438
+ else if (ctxAtBlockComplex) {
439
+ this.visit(ctxAtBlockComplex);
650
440
  }
651
- executor.print('end at block pin expressions');
652
- return executor.atComponent(currentComponent, currentPin);
653
- }
654
- visitAt_block(ctx) {
441
+ executor.log('end at block pin expressions');
442
+ executor.atComponent(currentComponent, currentPin);
443
+ };
444
+ visitAt_block = (ctx) => {
655
445
  const executor = this.getExecutor();
656
- executor.print('entering at block');
446
+ executor.log('entering at block');
657
447
  this.visit(ctx.at_component_expr());
658
448
  const currentComponent = executor.scope.currentComponent;
659
449
  const currentPin = executor.scope.currentPin;
660
450
  executor.scope.indentLevel += 1;
661
- ctx.at_block_expressions_list().forEach(expression => {
451
+ ctx.at_block_expressions().forEach(expression => {
662
452
  this.visit(expression);
663
453
  });
664
454
  executor.scope.indentLevel -= 1;
665
455
  executor.scope.currentComponent = currentComponent;
666
456
  executor.scope.currentPin = currentPin;
667
- executor.print('leaving at block');
668
- return executor.getCurrentPoint();
669
- }
670
- visitAt_block_pin_expression_simple(ctx) {
671
- if (ctx.expression()) {
672
- this.visit(ctx.expression());
457
+ executor.log('leaving at block');
458
+ };
459
+ visitAt_block_pin_expression_simple = (ctx) => {
460
+ const ctxExpression = ctx.expression();
461
+ if (ctxExpression) {
462
+ this.visit(ctxExpression);
673
463
  }
674
464
  else if (ctx.NOT_CONNECTED()) {
675
465
  return;
676
466
  }
677
- }
678
- visitAt_block_pin_expression_complex(ctx) {
679
- ctx.expression_list().forEach(item => {
467
+ };
468
+ visitAt_block_pin_expression_complex = (ctx) => {
469
+ ctx.expression().forEach(item => {
680
470
  this.visit(item);
681
471
  });
682
- return this.getExecutor().getCurrentPoint();
683
- }
684
- visitWire_expr(ctx) {
685
- const segments = [];
686
- const parts = ctx.children.slice(1);
687
- for (let i = 0; i < parts.length; i++) {
688
- const textValue = parts[i].getText();
689
- if (this.acceptedDirections.indexOf(textValue) !== -1) {
690
- const segment = [textValue];
691
- let skipNext = false;
692
- let invalidValue = true;
693
- if (i + 1 < parts.length) {
694
- const nextValue = parts[i + 1].getText();
695
- const nextValueNumber = Number(nextValue);
696
- if (!isNaN(nextValueNumber)) {
697
- invalidValue = false;
698
- segment.push(nextValueNumber);
699
- skipNext = true;
700
- }
701
- }
702
- if (invalidValue) {
703
- throw `Invalid value provided for direction ${textValue} in wire`;
704
- }
705
- segments.push(segment);
706
- if (skipNext) {
707
- i += 1;
708
- }
472
+ };
473
+ visitWire_expr_direction_only = (ctx) => {
474
+ const value = ctx.ID().getText();
475
+ if (value === 'auto' || value === 'auto_') {
476
+ this.setResult(ctx, [value]);
477
+ }
478
+ else {
479
+ throw 'Invalid direction for wire';
480
+ }
481
+ };
482
+ visitWire_expr_direction_value = (ctx) => {
483
+ const direction = ctx.ID().getText();
484
+ if (this.acceptedDirections.indexOf(direction) !== -1) {
485
+ let useValue = null;
486
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
487
+ const ctxDataExpr = ctx.data_expr();
488
+ if (ctxIntegerValue) {
489
+ useValue = Number(ctxIntegerValue);
490
+ }
491
+ else if (ctxDataExpr) {
492
+ this.visit(ctxDataExpr);
493
+ useValue = this.getResult(ctxDataExpr);
709
494
  }
710
- else if (textValue === "auto" || textValue === "auto_") {
711
- segments.push([textValue]);
495
+ if (useValue !== null) {
496
+ this.setResult(ctx, [direction, useValue]);
497
+ return;
712
498
  }
713
499
  }
500
+ throw "Invalid direction or value for wire";
501
+ };
502
+ visitWire_expr = (ctx) => {
503
+ const wireAtomExpr = ctx.wire_atom_expr();
504
+ const segments = wireAtomExpr.map(wireSegment => {
505
+ this.visit(wireSegment);
506
+ return this.getResult(wireSegment);
507
+ });
714
508
  this.getExecutor().addWire(segments);
715
- }
716
- visitPoint_expr(ctx) {
509
+ };
510
+ visitPoint_expr = (ctx) => {
717
511
  const ID = ctx.ID();
718
512
  return this.getExecutor().addPoint(ID.getText());
719
- }
720
- visitImport_expr(ctx) {
721
- const ID = ctx.ID().toString();
722
- this.print('import', ID);
723
- const { hasError, hasParseError } = this.onImportFile(this, ID);
724
- if (hasError || hasParseError) {
725
- this.print('import', ID, 'failed');
726
- throw `import ${ID} failed`;
727
- }
728
- this.print('done import', ID);
729
- }
730
- visitProperty_set_expr(ctx) {
731
- const result = this.visit(ctx.data_expr());
732
- const resolvedProperty = this.visit(ctx.atom_expr());
513
+ };
514
+ visitProperty_set_expr = (ctx) => {
515
+ const ctxDataExpr = ctx.data_expr();
516
+ this.visit(ctxDataExpr);
517
+ const result = this.getResult(ctxDataExpr);
518
+ const ctxAtomExpr = ctx.atom_expr();
519
+ this.visit(ctxAtomExpr);
520
+ const resolvedProperty = this.getResult(ctxAtomExpr);
733
521
  this.getExecutor().setProperty(resolvedProperty, result);
734
- }
735
- visitDouble_dot_property_set_expr(ctx) {
736
- const result = this.visit(ctx.data_expr());
522
+ };
523
+ visitDouble_dot_property_set_expr = (ctx) => {
524
+ const ctxDataExpr = ctx.data_expr();
525
+ this.visit(ctxDataExpr);
526
+ const result = this.getResult(ctxDataExpr);
737
527
  const propertyName = ctx.ID().getText();
738
528
  this.getExecutor().setProperty('..' + propertyName, result);
739
- }
740
- visitRoundedBracketsExpr(ctx) {
741
- return this.visit(ctx.data_expr());
742
- }
743
- visitFrame_expr(ctx) {
529
+ };
530
+ visitFrame_expr = (ctx) => {
744
531
  const frameId = this.getExecutor().enterFrame();
745
- this.runExpressions(this.getExecutor(), ctx.expression_list());
532
+ this.runExpressions(this.getExecutor(), ctx.expression());
746
533
  this.getExecutor().exitFrame(frameId);
747
- }
748
- visitNet_namespace_expr(ctx) {
534
+ };
535
+ visitNet_namespace_expr = (ctx) => {
749
536
  let dataValue = null;
750
537
  let netNamespace = null;
751
538
  const hasPlus = ctx.Addition();
752
- if (ctx.data_expr()) {
753
- dataValue = this.visit(ctx.data_expr());
539
+ const ctxDataExpr = ctx.data_expr();
540
+ if (ctxDataExpr) {
541
+ this.visit(ctxDataExpr);
542
+ dataValue = this.getResult(ctxDataExpr);
754
543
  if (dataValue instanceof UndeclaredReference) {
755
544
  netNamespace = "/" + dataValue.reference.name;
756
545
  }
@@ -764,8 +553,8 @@ export class MainVisitor extends ParseTreeVisitor {
764
553
  else {
765
554
  netNamespace = "/";
766
555
  }
767
- return (hasPlus ? "+" : "") + netNamespace;
768
- }
556
+ this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
557
+ };
769
558
  pinTypes = [
770
559
  PinTypes.Any,
771
560
  PinTypes.IO,
@@ -773,44 +562,6 @@ export class MainVisitor extends ParseTreeVisitor {
773
562
  PinTypes.Output,
774
563
  PinTypes.Power,
775
564
  ];
776
- createImportFileHandler(directory, defaultLibsPath) {
777
- return (visitor, importPath) => {
778
- let importResult;
779
- importResult = this.importLib(visitor, directory, importPath);
780
- if (!importResult.pathExists && importPath == 'lib') {
781
- importResult = this.importLib(visitor, defaultLibsPath, importPath);
782
- }
783
- return importResult;
784
- };
785
- }
786
- importLib(visitor, directory, filename) {
787
- const tmpFilePath = join(directory, filename + ".cst");
788
- visitor.print('importing path:', tmpFilePath);
789
- let pathExists = false;
790
- let fileData = null;
791
- try {
792
- fileData = readFileSync(tmpFilePath, { encoding: 'utf8' });
793
- pathExists = true;
794
- }
795
- catch (err) {
796
- pathExists = false;
797
- }
798
- try {
799
- if (pathExists) {
800
- visitor.print('done reading imported file data');
801
- const { hasError, hasParseError } = parseFileWithVisitor(visitor, fileData);
802
- return { hasError, hasParseError, pathExists };
803
- }
804
- }
805
- catch (err) {
806
- visitor.print('Failed to import file: ', err.message);
807
- }
808
- return {
809
- hasError: true,
810
- hasParseError: true,
811
- pathExists,
812
- };
813
- }
814
565
  parseCreateComponentPins(pinData) {
815
566
  const pins = [];
816
567
  if (typeof pinData === 'number') {
@@ -862,18 +613,6 @@ export class MainVisitor extends ParseTreeVisitor {
862
613
  }
863
614
  return result;
864
615
  }
865
- prepareStringValue(value) {
866
- return value.slice(1, value.length - 1);
867
- }
868
- print(...params) {
869
- const indentOutput = ''.padStart(this.indentLevel * 4, ' ');
870
- const indentLevelText = this.indentLevel.toString().padStart(3, ' ');
871
- const args = ['[' + indentLevelText + ']', indentOutput, ...params];
872
- this.logger.add(args.join(' '));
873
- if (!this.silent) {
874
- console.log.apply(null, args);
875
- }
876
- }
877
616
  printNets() {
878
617
  this.getExecutor().scope.printNets();
879
618
  }
@@ -935,7 +674,10 @@ export class MainVisitor extends ParseTreeVisitor {
935
674
  }
936
675
  getGraph() {
937
676
  const executor = this.getExecutor();
938
- const sequence = executor.scope.sequence;
677
+ const fullSequence = executor.scope.sequence;
678
+ const tmpNet = executor.scope.getNet(executor.scope.componentRoot, 1);
679
+ const sequence = (tmpNet === null)
680
+ ? fullSequence.slice(1) : fullSequence;
939
681
  const nets = executor.scope.getNets();
940
682
  return {
941
683
  sequence,
@@ -944,7 +686,7 @@ export class MainVisitor extends ParseTreeVisitor {
944
686
  };
945
687
  }
946
688
  annotateComponents() {
947
- this.print('===== annotate components =====');
689
+ this.log('===== annotate components =====');
948
690
  const annotater = new ComponentAnnotater();
949
691
  const instances = this.getExecutor().scope.instances;
950
692
  const toAnnotate = [];
@@ -956,7 +698,7 @@ export class MainVisitor extends ParseTreeVisitor {
956
698
  continue;
957
699
  }
958
700
  if (instance.typeProp === null) {
959
- this.print('Instance has no type:', instance.instanceName, ' assuming connector');
701
+ this.log('Instance has no type:', instance.instanceName, ' assuming connector');
960
702
  instance.typeProp = 'conn';
961
703
  }
962
704
  if (instance.parameters.has('refdes')) {
@@ -964,7 +706,7 @@ export class MainVisitor extends ParseTreeVisitor {
964
706
  if (refdes) {
965
707
  instance.assignedRefDes = refdes;
966
708
  annotater.trackRefDes(refdes);
967
- this.print(refdes, '-', instance.instanceName);
709
+ this.log(refdes, '-', instance.instanceName);
968
710
  continue;
969
711
  }
970
712
  }
@@ -975,14 +717,14 @@ export class MainVisitor extends ParseTreeVisitor {
975
717
  const newRefDes = annotater.getAnnotation(instance.typeProp);
976
718
  if (newRefDes !== null) {
977
719
  instance.assignedRefDes = newRefDes;
978
- this.print(newRefDes, '-', instance.instanceName);
720
+ this.log(newRefDes, '-', instance.instanceName);
979
721
  }
980
722
  else {
981
- this.print('Failed to annotate:', instance.instanceName);
723
+ this.log('Failed to annotate:', instance.instanceName);
982
724
  }
983
725
  });
984
- this.print('===== annotate done =====');
985
- this.print('');
726
+ this.log('===== annotate done =====');
727
+ this.log('');
986
728
  }
987
729
  resolveNets(scope, instance) {
988
730
  const result = [];
@@ -1011,61 +753,22 @@ export class MainVisitor extends ParseTreeVisitor {
1011
753
  throw "Invalid modifier for orientation";
1012
754
  }
1013
755
  }
756
+ setComponentFlip(component, flipValue) {
757
+ if (this.acceptedFlip.indexOf(flipValue) !== -1) {
758
+ component.setParam(flipValue, 1);
759
+ }
760
+ }
1014
761
  getPropertyExprList(items) {
1015
762
  const properties = new Map();
1016
763
  items.forEach((item) => {
1017
- const result = this.visit(item);
764
+ this.visit(item);
765
+ const result = this.getResult(item);
1018
766
  for (const [key, value] of result) {
1019
767
  properties.set(key, value);
1020
768
  }
1021
769
  });
1022
770
  return properties;
1023
771
  }
1024
- runExpressions(executor, expressions) {
1025
- let returnValue = null;
1026
- for (let i = 0; i < expressions.length; i++) {
1027
- const expr = expressions[i];
1028
- this.visit(expr);
1029
- if (executor.stopFurtherExpressions) {
1030
- returnValue = executor.returnValue;
1031
- break;
1032
- }
1033
- }
1034
- return returnValue;
1035
- }
1036
- setupPrintFunction(context) {
1037
- context.createFunction('print', (params) => {
1038
- const items = params.map(([, , value]) => {
1039
- return value;
1040
- });
1041
- if (this.printToConsole) {
1042
- console.log('::', ...items);
1043
- }
1044
- this.printStream.push(...items);
1045
- return [this, null];
1046
- });
1047
- }
1048
- getNetNamespace(executorNetNamespace, passedNetNamespace) {
1049
- let result = executorNetNamespace;
1050
- if (passedNetNamespace !== null && passedNetNamespace.length > 0) {
1051
- if (passedNetNamespace === '/' || passedNetNamespace === '_') {
1052
- result = '';
1053
- }
1054
- else if (passedNetNamespace[0] === '+') {
1055
- if (executorNetNamespace === '/') {
1056
- result = passedNetNamespace.slice(1);
1057
- }
1058
- else {
1059
- result = executorNetNamespace + passedNetNamespace.slice(2);
1060
- }
1061
- }
1062
- else {
1063
- result = passedNetNamespace;
1064
- }
1065
- result = result + '/';
1066
- }
1067
- return result;
1068
- }
1069
772
  }
1070
773
  const ComponentRefDesPrefixes = {
1071
774
  'res': 'R',