circuitscript 0.0.38 → 0.1.2

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 (66) hide show
  1. package/dist/cjs/BaseVisitor.js +69 -46
  2. package/dist/cjs/SymbolValidatorVisitor.js +1 -1
  3. package/dist/cjs/antlr/CircuitScriptLexer.js +80 -80
  4. package/dist/cjs/antlr/CircuitScriptParser.js +580 -613
  5. package/dist/cjs/builtinMethods.js +32 -10
  6. package/dist/cjs/draw_symbols.js +375 -233
  7. package/dist/cjs/execute.js +142 -131
  8. package/dist/cjs/export.js +2 -4
  9. package/dist/cjs/geometry.js +52 -19
  10. package/dist/cjs/globals.js +14 -9
  11. package/dist/cjs/helpers.js +16 -3
  12. package/dist/cjs/layout.js +143 -151
  13. package/dist/cjs/logger.js +8 -1
  14. package/dist/cjs/objects/ClassComponent.js +22 -22
  15. package/dist/cjs/objects/ExecutionScope.js +10 -4
  16. package/dist/cjs/objects/Frame.js +4 -1
  17. package/dist/cjs/objects/ParamDefinition.js +120 -4
  18. package/dist/cjs/objects/PinDefinition.js +1 -4
  19. package/dist/cjs/objects/types.js +41 -0
  20. package/dist/cjs/render.js +41 -110
  21. package/dist/cjs/sizing.js +33 -7
  22. package/dist/cjs/utils.js +92 -2
  23. package/dist/cjs/visitor.js +279 -284
  24. package/dist/esm/BaseVisitor.mjs +70 -47
  25. package/dist/esm/SymbolValidatorVisitor.mjs +1 -1
  26. package/dist/esm/antlr/CircuitScriptLexer.mjs +80 -80
  27. package/dist/esm/antlr/CircuitScriptParser.mjs +580 -613
  28. package/dist/esm/builtinMethods.mjs +29 -10
  29. package/dist/esm/draw_symbols.mjs +381 -238
  30. package/dist/esm/execute.mjs +144 -133
  31. package/dist/esm/export.mjs +2 -4
  32. package/dist/esm/geometry.mjs +52 -19
  33. package/dist/esm/globals.mjs +13 -8
  34. package/dist/esm/helpers.mjs +17 -4
  35. package/dist/esm/layout.mjs +144 -153
  36. package/dist/esm/logger.mjs +8 -1
  37. package/dist/esm/objects/ClassComponent.mjs +21 -26
  38. package/dist/esm/objects/ExecutionScope.mjs +10 -4
  39. package/dist/esm/objects/Frame.mjs +4 -1
  40. package/dist/esm/objects/ParamDefinition.mjs +119 -3
  41. package/dist/esm/objects/PinDefinition.mjs +0 -2
  42. package/dist/esm/objects/types.mjs +42 -0
  43. package/dist/esm/render.mjs +44 -113
  44. package/dist/esm/sizing.mjs +34 -8
  45. package/dist/esm/utils.mjs +86 -1
  46. package/dist/esm/visitor.mjs +281 -286
  47. package/dist/types/BaseVisitor.d.ts +3 -2
  48. package/dist/types/antlr/CircuitScriptParser.d.ts +5 -3
  49. package/dist/types/draw_symbols.d.ts +81 -49
  50. package/dist/types/execute.d.ts +16 -11
  51. package/dist/types/geometry.d.ts +31 -19
  52. package/dist/types/globals.d.ts +15 -10
  53. package/dist/types/helpers.d.ts +2 -1
  54. package/dist/types/layout.d.ts +22 -21
  55. package/dist/types/logger.d.ts +1 -1
  56. package/dist/types/objects/ClassComponent.d.ts +19 -16
  57. package/dist/types/objects/ExecutionScope.d.ts +2 -1
  58. package/dist/types/objects/Frame.d.ts +5 -3
  59. package/dist/types/objects/ParamDefinition.d.ts +31 -2
  60. package/dist/types/objects/PinDefinition.d.ts +0 -2
  61. package/dist/types/objects/types.d.ts +7 -2
  62. package/dist/types/render.d.ts +2 -1
  63. package/dist/types/utils.d.ts +9 -1
  64. package/dist/types/visitor.d.ts +5 -5
  65. package/libs/lib.cst +102 -32
  66. package/package.json +7 -3
@@ -1,9 +1,9 @@
1
1
  import { ClassComponent } from './objects/ClassComponent.mjs';
2
- import { NumericValue, ParamDefinition } from './objects/ParamDefinition.mjs';
2
+ import { NumberOperator, numeric, NumericValue, ParamDefinition } from './objects/ParamDefinition.mjs';
3
3
  import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
4
4
  import { PinTypes } from './objects/PinTypes.mjs';
5
5
  import { DeclaredReference, UndeclaredReference } from './objects/types.mjs';
6
- import { BlockTypes, ComponentTypes, FrameType, GlobalDocumentName, NoNetText, ReferenceTypes, WireAutoDirection } from './globals.mjs';
6
+ import { BlockTypes, ComponentTypes, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide, WireAutoDirection } from './globals.mjs';
7
7
  import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.mjs';
8
8
  import { BaseVisitor } from './BaseVisitor.mjs';
9
9
  import { getPortType } from './utils.mjs';
@@ -12,9 +12,7 @@ import { FrameParamKeys } from './objects/Frame.mjs';
12
12
  export class ParserVisitor extends BaseVisitor {
13
13
  visitKeyword_assignment_expr = (ctx) => {
14
14
  const id = ctx.ID().getText();
15
- const ctxDataExpr = ctx.data_expr();
16
- this.visit(ctxDataExpr);
17
- const value = this.getResult(ctxDataExpr);
15
+ const value = this.visitResult(ctx.data_expr());
18
16
  this.setResult(ctx, [id, value]);
19
17
  };
20
18
  visitPin_select_expr = (ctx) => {
@@ -30,56 +28,48 @@ export class ParserVisitor extends BaseVisitor {
30
28
  this.setResult(ctx, value);
31
29
  };
32
30
  visitAdd_component_expr = (ctx) => {
33
- const ctxDataWithAssignmentExpr = ctx.data_expr_with_assignment();
34
- this.visit(ctxDataWithAssignmentExpr);
35
- const [component, pinValue] = this.getResult(ctxDataWithAssignmentExpr);
31
+ const [component, pinValue] = this.visitResult(ctx.data_expr_with_assignment());
36
32
  this.getExecutor().addComponentExisting(component, pinValue);
37
33
  };
38
34
  visitAt_component_expr = (ctx) => {
39
- if (ctx.Point()) {
40
- this.getExecutor().atPointBlock();
41
- }
42
- else {
43
- const ctxComponentSelectExpr = ctx.component_select_expr();
44
- this.visit(ctxComponentSelectExpr);
45
- const [component, pin] = this.getResult(ctxComponentSelectExpr);
46
- this.getExecutor().atComponent(component, pin, {
47
- addSequence: true
48
- });
49
- }
35
+ const [component, pin] = this.visitResult(ctx.component_select_expr());
36
+ this.getExecutor().atComponent(component, pin, {
37
+ addSequence: true
38
+ });
50
39
  return this.getExecutor().getCurrentPoint();
51
40
  };
52
41
  visitTo_component_expr = (ctx) => {
53
- if (ctx.Point()) {
54
- this.getExecutor().toPointBlock();
55
- }
56
- else {
57
- ctx.component_select_expr().forEach(item => {
58
- this.visit(item);
59
- const [component, pin] = this.getResult(item);
60
- this.getExecutor().toComponent(component, pin, {
61
- addSequence: true
62
- });
42
+ ctx.component_select_expr().forEach(item => {
43
+ const [component, pin] = this.visitResult(item);
44
+ this.getExecutor().toComponent(component, pin, {
45
+ addSequence: true
63
46
  });
64
- }
47
+ });
65
48
  return this.getExecutor().getCurrentPoint();
66
49
  };
67
50
  visitComponent_select_expr = (ctx) => {
68
51
  const ctxDataExprWithAssigment = ctx.data_expr_with_assignment();
69
- if (ctxDataExprWithAssigment) {
70
- this.visit(ctxDataExprWithAssigment);
71
- this.setResult(ctx, this.getResult(ctxDataExprWithAssigment));
52
+ let componentPin = null;
53
+ if (ctx.Point()) {
54
+ const [component, pin,] = this.getExecutor().getPointBlockLocation();
55
+ componentPin = [component, pin];
56
+ }
57
+ else if (ctxDataExprWithAssigment) {
58
+ componentPin = this.visitResult(ctxDataExprWithAssigment);
72
59
  }
73
60
  else {
74
61
  const component = this.getExecutor().scope.currentComponent;
75
62
  let pinId = null;
76
63
  const ctxPinSelectExpr = ctx.pin_select_expr();
77
64
  if (ctxPinSelectExpr) {
78
- this.visit(ctxPinSelectExpr);
79
- pinId = this.getResult(ctxPinSelectExpr);
65
+ pinId = this.visitResult(ctxPinSelectExpr);
80
66
  }
81
- this.setResult(ctx, [component, pinId]);
67
+ if (pinId === null) {
68
+ this.throwWithContext(ctx, "Could not resolve pin");
69
+ }
70
+ componentPin = [component, pinId];
82
71
  }
72
+ this.setResult(ctx, componentPin);
83
73
  };
84
74
  visitPath_blocks = (ctx) => {
85
75
  const blocks = ctx.path_block_inner();
@@ -118,7 +108,7 @@ export class ParserVisitor extends BaseVisitor {
118
108
  visitCreate_component_expr = (ctx) => {
119
109
  const properties = this.getPropertyExprList(ctx.property_expr());
120
110
  const pins = this.parseCreateComponentPins(properties.get('pins'));
121
- let instanceName = this.getExecutor().getUniqueInstanceName('');
111
+ let instanceName = this.getExecutor().getUniqueInstanceName();
122
112
  const propParams = properties.get('params');
123
113
  const params = this.parseCreateComponentParams(propParams);
124
114
  if (params.length > 0) {
@@ -140,29 +130,51 @@ export class ParserVisitor extends BaseVisitor {
140
130
  properties.get('copy') : false;
141
131
  const width = properties.has('width') ?
142
132
  properties.get('width') : null;
143
- const angle = properties.has('angle') ?
144
- properties.get('angle') : null;
133
+ const height = properties.has('height') ?
134
+ properties.get('height') : null;
135
+ const angle = properties.has(ParamKeys.angle) ?
136
+ properties.get(ParamKeys.angle) : null;
145
137
  const followWireOrientation = properties.has('followWireOrientation') ?
146
138
  properties.get('followWireOrientation') : true;
147
139
  const props = {
148
- arrange, display, type, width, copy,
140
+ arrange, display, type, width, height, copy,
149
141
  angle, followWireOrientation
150
142
  };
151
143
  const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
152
144
  this.setResult(ctx, createdComponent);
153
145
  };
154
146
  visitCreate_graphic_expr = (ctx) => {
155
- const graphicsExpressionsCtx = ctx.graphic_expressions_block();
156
- this.visit(graphicsExpressionsCtx);
157
- const commands = this.getResult(graphicsExpressionsCtx);
158
- const drawing = new SymbolDrawingCommands(commands);
147
+ const ctxId = ctx.ID();
148
+ const paramIds = [];
149
+ if (ctxId !== null) {
150
+ const varName = ctxId.getText();
151
+ paramIds.push(varName);
152
+ this.getExecutor().scope.variables.set(varName, {});
153
+ }
154
+ const executor = this.getExecutor();
155
+ const stack = [...this.executionStack];
156
+ const drawing = new SymbolDrawingCommands(variables => {
157
+ if (variables && paramIds.length > 0) {
158
+ const obj = {};
159
+ variables.forEach((value, key) => {
160
+ obj[key] = value;
161
+ });
162
+ executor.scope.variables.set(paramIds[0], obj);
163
+ }
164
+ const currentStack = this.executionStack.splice(0);
165
+ this.executionStack.push(...stack);
166
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
167
+ const commands = this.visitResult(graphicsExpressionsCtx);
168
+ this.executionStack.splice(0);
169
+ this.executionStack.push(...currentStack);
170
+ return commands;
171
+ });
159
172
  drawing.source = ctx.getText();
160
173
  this.setResult(ctx, drawing);
161
174
  };
162
175
  visitGraphic_expressions_block = (ctx) => {
163
176
  const commands = ctx.graphic_expr().reduce((accum, item) => {
164
- this.visit(item);
165
- const [commandName, parameters] = this.getResult(item);
177
+ const [commandName, parameters] = this.visitResult(item);
166
178
  if (commandName === PlaceHolderCommands.for) {
167
179
  accum = accum.concat(parameters);
168
180
  }
@@ -177,7 +189,7 @@ export class ParserVisitor extends BaseVisitor {
177
189
  }
178
190
  return accum;
179
191
  }, []);
180
- accum.push([commandName, positionParams, keywordParams]);
192
+ accum.push([commandName, positionParams, keywordParams, item]);
181
193
  }
182
194
  return accum;
183
195
  }, []);
@@ -195,18 +207,15 @@ export class ParserVisitor extends BaseVisitor {
195
207
  let parameters = [];
196
208
  const ctxNestedProperties = ctx.nested_properties_inner();
197
209
  if (ctxNestedProperties) {
198
- this.visit(ctxNestedProperties);
199
- const nestedKeyValues = this.getResult(ctxNestedProperties);
210
+ const nestedKeyValues = this.visitResult(ctxNestedProperties);
200
211
  nestedKeyValues.forEach((value, key) => {
201
212
  parameters.push(['keyword', key, value]);
202
213
  });
203
214
  }
204
215
  else {
205
- const ctxParameters = ctx.parameters();
206
- this.visit(ctxParameters);
207
- parameters = this.getResult(ctxParameters);
216
+ parameters = this.visitResult(ctx.parameters());
208
217
  }
209
- if (commandName === 'label') {
218
+ if (commandName === PlaceHolderCommands.label) {
210
219
  parameters.forEach(item => {
211
220
  if (item[0] == 'keyword' && item[1] === 'portType') {
212
221
  if (item[2] === 'in') {
@@ -222,9 +231,7 @@ export class ParserVisitor extends BaseVisitor {
222
231
  };
223
232
  visitGraphicForExpr = (ctx) => {
224
233
  const forVariableNames = ctx.ID().map(item => item.getText());
225
- const ctxDataExpr = ctx.data_expr();
226
- this.visit(ctxDataExpr);
227
- const listItems = this.getResult(ctxDataExpr);
234
+ const listItems = this.visitResult(ctx.data_expr());
228
235
  let keepLooping = true;
229
236
  let counter = 0;
230
237
  let allCommands = [];
@@ -237,9 +244,7 @@ export class ParserVisitor extends BaseVisitor {
237
244
  useValueArray.forEach((value, index) => {
238
245
  this.getExecutor().scope.variables.set(forVariableNames[index], value);
239
246
  });
240
- const graphicsExpressionsCtx = ctx.graphic_expressions_block();
241
- this.visit(graphicsExpressionsCtx);
242
- const commands = this.getResult(graphicsExpressionsCtx);
247
+ const commands = this.visitResult(ctx.graphic_expressions_block());
243
248
  allCommands = allCommands.concat(commands);
244
249
  counter += 1;
245
250
  }
@@ -251,8 +256,10 @@ export class ParserVisitor extends BaseVisitor {
251
256
  };
252
257
  visitCreate_module_expr = (ctx) => {
253
258
  const properties = this.getPropertyExprList(ctx.property_expr());
254
- const { left: leftPorts, right: rightPorts } = this.parseCreateModulePorts(properties.get('ports'));
255
- const allPorts = [...leftPorts, ...rightPorts].filter(item => {
259
+ const modulePorts = this.parseCreateModulePorts(properties.get('ports'));
260
+ const { [SymbolPinSide.Left]: leftPorts, [SymbolPinSide.Right]: rightPorts, [SymbolPinSide.Top]: topPorts, [SymbolPinSide.Bottom]: bottomPorts } = modulePorts;
261
+ const allPorts = [...leftPorts, ...rightPorts,
262
+ ...topPorts, ...bottomPorts].filter(item => {
256
263
  return !(Array.isArray(item));
257
264
  });
258
265
  const nameToPinId = new Map();
@@ -260,65 +267,44 @@ export class ParserVisitor extends BaseVisitor {
260
267
  nameToPinId.set(portName, index + 1);
261
268
  return new PinDefinition(index + 1, PinIdType.Int, portName, PinTypes.Any);
262
269
  });
263
- const arrangeLeftItems = leftPorts.map(item => {
264
- if (Array.isArray(item)) {
265
- return item;
266
- }
267
- else {
268
- return nameToPinId.get(item);
269
- }
270
- });
271
- const arrangeRightItems = rightPorts.map(item => {
272
- if (Array.isArray(item)) {
273
- return item;
274
- }
275
- else {
276
- return nameToPinId.get(item);
277
- }
278
- });
279
- const arrange = new Map();
280
- if (arrangeLeftItems.length > 0) {
281
- arrange.set('left', arrangeLeftItems);
282
- }
283
- if (arrangeRightItems.length > 0) {
284
- arrange.set('right', arrangeRightItems);
285
- }
270
+ const arrange = this.getArrangePropFromModulePorts(modulePorts, nameToPinId);
286
271
  const width = properties.has('width') ?
287
272
  properties.get('width') : null;
273
+ const height = properties.has('height') ?
274
+ properties.get('height') : null;
288
275
  const blankParams = [];
289
276
  const props = {
290
- arrange, width
277
+ arrange, width, height,
278
+ copy: false,
279
+ followWireOrientation: true,
291
280
  };
292
- const moduleInstanceName = this.getExecutor().getUniqueInstanceName('');
293
- const createdComponent = this.getExecutor().createComponent(moduleInstanceName, tmpPorts, blankParams, props);
294
- createdComponent.typeProp = 'module';
281
+ const moduleInstanceName = this.getExecutor().getUniqueInstanceName();
282
+ const moduleComponent = this.getExecutor().createComponent(moduleInstanceName, tmpPorts, blankParams, props, true);
283
+ moduleComponent.typeProp = ComponentTypes.module;
295
284
  const ctxPropertyBlock = ctx.property_block_expr();
296
285
  if (ctxPropertyBlock) {
297
286
  const [firstBlock] = ctxPropertyBlock;
298
- this.visit(firstBlock);
299
- const [keyName, expressionsBlock] = this.getResult(firstBlock);
300
- if (keyName === 'contains') {
301
- createdComponent.moduleContainsExpressions = expressionsBlock;
302
- this.expandModuleContains(createdComponent, this.getExecutor().netNamespace);
287
+ const [keyName, expressionsBlock] = this.visitResult(firstBlock);
288
+ if (keyName === ModuleContainsKeyword) {
289
+ moduleComponent.moduleContainsExpressions = expressionsBlock;
290
+ this.expandModuleContains(moduleComponent, this.getExecutor().netNamespace);
303
291
  }
304
292
  }
305
- this.setResult(ctx, createdComponent);
293
+ if (moduleComponent.moduleContainsExpressions === undefined) {
294
+ throw 'Module has no `contains` block defined!';
295
+ }
296
+ this.setResult(ctx, moduleComponent);
306
297
  };
307
298
  visitProperty_block_expr = (ctx) => {
308
- const tmpCtx = ctx.property_key_expr();
309
- this.visit(tmpCtx);
310
- const keyName = this.getResult(tmpCtx);
299
+ const keyName = this.visitResult(ctx.property_key_expr());
311
300
  const expressionsBlock = ctx.expressions_block();
312
301
  this.setResult(ctx, [keyName, expressionsBlock]);
313
302
  };
314
303
  visitProperty_expr = (ctx) => {
315
- const ctxPropertyKeyExpr = ctx.property_key_expr();
316
- const ctxPropertyValueExpr = ctx.property_value_expr();
317
- this.visit(ctxPropertyKeyExpr);
318
- this.visit(ctxPropertyValueExpr);
319
- const keyName = this.getResult(ctxPropertyKeyExpr);
320
- const value = this.getResult(ctxPropertyValueExpr);
321
- if (value instanceof UndeclaredReference) {
304
+ const keyName = this.visitResult(ctx.property_key_expr());
305
+ const value = this.visitResult(ctx.property_value_expr());
306
+ if (value instanceof UndeclaredReference && (value.reference.parentValue === undefined
307
+ && value.reference.value === undefined)) {
322
308
  throw value.throwMessage();
323
309
  }
324
310
  const map = new Map();
@@ -328,14 +314,11 @@ export class ParserVisitor extends BaseVisitor {
328
314
  visitSingle_line_property = (ctx) => {
329
315
  let value;
330
316
  if (ctx.data_expr().length === 1) {
331
- const ctxFirst = ctx.data_expr(0);
332
- this.visit(ctxFirst);
333
- value = this.getResult(ctxFirst);
317
+ value = this.visitResult(ctx.data_expr(0));
334
318
  }
335
319
  else {
336
320
  value = ctx.data_expr().map(item => {
337
- this.visit(item);
338
- return this.getResult(item);
321
+ return this.visitResult(item);
339
322
  });
340
323
  }
341
324
  this.setResult(ctx, value);
@@ -343,8 +326,7 @@ export class ParserVisitor extends BaseVisitor {
343
326
  visitNested_properties_inner = (ctx) => {
344
327
  const result = new Map();
345
328
  ctx.property_expr().forEach((item) => {
346
- this.visit(item);
347
- const property = this.getResult(item);
329
+ const property = this.visitResult(item);
348
330
  for (const [key, value] of property) {
349
331
  result.set(key, value);
350
332
  }
@@ -352,9 +334,7 @@ export class ParserVisitor extends BaseVisitor {
352
334
  this.setResult(ctx, result);
353
335
  };
354
336
  visitNested_properties = (ctx) => {
355
- const ctxNested = ctx.nested_properties_inner();
356
- this.visit(ctxNested);
357
- this.setResult(ctx, this.getResult(ctxNested));
337
+ this.setResult(ctx, this.visitResult(ctx.nested_properties_inner()));
358
338
  };
359
339
  visitProperty_key_expr = (ctx) => {
360
340
  const ctxID = ctx.ID();
@@ -374,30 +354,32 @@ export class ParserVisitor extends BaseVisitor {
374
354
  };
375
355
  visitData_expr_with_assignment = (ctx) => {
376
356
  let component = null;
357
+ let componentCtx = null;
377
358
  const ctxDataExpr = ctx.data_expr();
378
359
  const ctxAssignmentExpr = ctx.assignment_expr();
379
360
  if (ctxDataExpr) {
380
- this.visit(ctxDataExpr);
381
- component = this.getResult(ctxDataExpr);
361
+ component = this.visitResult(ctxDataExpr);
362
+ componentCtx = ctxDataExpr;
382
363
  if (component === null || component === undefined) {
383
- throw "Could not find component: " + ctxDataExpr.getText();
364
+ this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
384
365
  }
385
366
  }
386
367
  else if (ctxAssignmentExpr) {
387
- this.visit(ctxAssignmentExpr);
388
- component = this.getResult(ctxAssignmentExpr);
368
+ component = this.visitResult(ctxAssignmentExpr);
369
+ componentCtx = ctxAssignmentExpr;
389
370
  }
390
371
  if (component instanceof ClassComponent
391
372
  && component.copyProp) {
392
373
  component = this.getExecutor().copyComponent(component);
393
374
  }
394
- if (component instanceof DeclaredReference
395
- && component.found
396
- && component.trailers
397
- && component.trailers.length > 0
398
- && component.trailers[0] === 'contains') {
399
- component = component.value;
400
- this.placeModuleContains(component);
375
+ if (component instanceof UndeclaredReference) {
376
+ const { reference: { trailers = [], parentValue = null } } = component;
377
+ if (parentValue instanceof ClassComponent
378
+ && trailers.length > 0
379
+ && trailers[0] === ModuleContainsKeyword) {
380
+ component = parentValue;
381
+ this.placeModuleContains(component);
382
+ }
401
383
  }
402
384
  if (component && component instanceof ClassComponent) {
403
385
  const modifiers = ctx.component_modifier_expr();
@@ -407,43 +389,29 @@ export class ParserVisitor extends BaseVisitor {
407
389
  const ctxID2 = modifier.ID(1);
408
390
  let result = null;
409
391
  if (ctxValueExpr) {
410
- this.visit(ctxValueExpr);
411
- result = this.getResult(ctxValueExpr);
392
+ result = this.visitResult(ctxValueExpr);
412
393
  }
413
394
  else if (ctxID2) {
414
395
  result = ctxID2.getText();
415
396
  }
416
397
  let shouldIgnoreWireOrientation = false;
417
- if (modifierText === 'flip') {
398
+ if (modifierText === ParamKeys.flip) {
418
399
  const flipValue = result;
419
400
  if (flipValue.indexOf('x') !== -1) {
420
- component.setParam('flipX', 1);
401
+ component.setParam(ParamKeys.flipX, 1);
421
402
  shouldIgnoreWireOrientation = true;
422
403
  }
423
404
  if (flipValue.indexOf('y') !== -1) {
424
- component.setParam('flipY', 1);
405
+ component.setParam(ParamKeys.flipY, 1);
425
406
  shouldIgnoreWireOrientation = true;
426
407
  }
427
408
  }
428
- else if (modifierText === 'angle') {
429
- const angleValue = Number(result);
430
- component.setParam('angle', angleValue);
409
+ else if (modifierText === ParamKeys.angle) {
410
+ component.setParam(ParamKeys.angle, result);
431
411
  shouldIgnoreWireOrientation = true;
432
412
  }
433
413
  else if (modifierText === 'anchor') {
434
- if (component.displayProp
435
- && component.displayProp instanceof SymbolDrawingCommands) {
436
- const commands = (component.displayProp)
437
- .getCommands();
438
- commands.forEach(command => {
439
- const positionParams = command[1];
440
- const keywordParams = command[2];
441
- if (command[0] === PlaceHolderCommands.label
442
- && positionParams[0] === 'value') {
443
- keywordParams.set('anchor', result);
444
- }
445
- });
446
- }
414
+ component.setParam('anchor', result);
447
415
  }
448
416
  if (shouldIgnoreWireOrientation) {
449
417
  component.useWireOrientationAngle = false;
@@ -453,8 +421,7 @@ export class ParserVisitor extends BaseVisitor {
453
421
  let pinValue = null;
454
422
  const ctxPinSelectExpr = ctx.pin_select_expr();
455
423
  if (ctxPinSelectExpr) {
456
- this.visit(ctxPinSelectExpr);
457
- pinValue = this.getResult(ctxPinSelectExpr);
424
+ pinValue = this.visitResult(ctxPinSelectExpr);
458
425
  }
459
426
  else {
460
427
  if (component instanceof ClassComponent) {
@@ -462,7 +429,7 @@ export class ParserVisitor extends BaseVisitor {
462
429
  }
463
430
  else {
464
431
  const undeclaredRef = component;
465
- throw 'Invalid component: ' + undeclaredRef.reference.name;
432
+ this.throwWithContext(componentCtx, 'Invalid component: ' + undeclaredRef.reference.name);
466
433
  }
467
434
  }
468
435
  this.setResult(ctx, [component, pinValue]);
@@ -471,11 +438,12 @@ export class ParserVisitor extends BaseVisitor {
471
438
  this.getExecutor().log('expanding module `contains`');
472
439
  const executionStack = this.executionStack;
473
440
  const resolveNet = this.createNetResolver(executionStack);
474
- const executionContextName = this.getExecutor().namespace + "_"
441
+ const executor = this.getExecutor();
442
+ const executionContextName = executor.namespace + "_"
475
443
  + component.instanceName
476
444
  + '_' + component.moduleCounter;
477
445
  const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + "_" + component.moduleCounter);
478
- const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, { netNamespace: tmpNamespace }, [], []);
446
+ const newExecutor = this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
479
447
  component.moduleCounter += 1;
480
448
  newExecutor.resolveNet = resolveNet;
481
449
  this.visit(component.moduleContainsExpressions);
@@ -493,9 +461,9 @@ export class ParserVisitor extends BaseVisitor {
493
461
  });
494
462
  const pinIdToPortMap = new Map();
495
463
  moduleComponent.modulePinIdToPortMap = pinIdToPortMap;
496
- for (const [key, component] of executionContext.scope.instances) {
497
- if (component._copyID !== null && component.typeProp === 'port') {
498
- const portName = component.parameters.get('net_name');
464
+ for (const [, component] of executionContext.scope.instances) {
465
+ if (component._copyID !== null && component.typeProp === ComponentTypes.port) {
466
+ const portName = component.parameters.get(ParamKeys.net_name);
499
467
  const modulePinId = modulePinMapping.get(portName);
500
468
  pinIdToPortMap.set(modulePinId, component);
501
469
  const portType = getPortType(component);
@@ -505,7 +473,7 @@ export class ParserVisitor extends BaseVisitor {
505
473
  }
506
474
  }
507
475
  placeModuleContains(moduleComponent) {
508
- if (moduleComponent.typeProp === 'module'
476
+ if (moduleComponent.typeProp === ComponentTypes.module
509
477
  && moduleComponent.moduleContainsExpressions) {
510
478
  this.log('place module `contains`');
511
479
  this.getExecutor().mergeScope(moduleComponent.moduleExecutionContext.scope, moduleComponent.moduleExecutionContextName);
@@ -517,24 +485,23 @@ export class ParserVisitor extends BaseVisitor {
517
485
  }
518
486
  }
519
487
  visitUnaryOperatorExpr = (ctx) => {
520
- this.visit(ctx.data_expr());
521
- let value = this.getResult(ctx.data_expr());
488
+ let value = this.visitResult(ctx.data_expr());
522
489
  const unaryOp = ctx.unary_operator();
523
490
  if (unaryOp) {
524
491
  if (unaryOp.Not()) {
525
492
  if (typeof value === "boolean") {
526
493
  value = !value;
527
494
  }
528
- else if (typeof value === "number") {
529
- value = (value === 0) ? false : true;
495
+ else if (value instanceof NumericValue) {
496
+ value = (value.toNumber() === 0) ? true : false;
530
497
  }
531
498
  else {
532
499
  throw "Failed to do Not operator";
533
500
  }
534
501
  }
535
502
  else if (unaryOp.Minus()) {
536
- if (typeof value === 'number') {
537
- value = -value;
503
+ if (value instanceof NumericValue) {
504
+ value = value.neg();
538
505
  }
539
506
  else {
540
507
  throw "Failed to do Negation operator";
@@ -549,16 +516,13 @@ export class ParserVisitor extends BaseVisitor {
549
516
  const ctxCreateGraphicExpr = ctx.create_graphic_expr();
550
517
  const ctxCreateModuleExpr = ctx.create_module_expr();
551
518
  if (ctxCreateComponentExpr) {
552
- this.visit(ctxCreateComponentExpr);
553
- value = this.getResult(ctxCreateComponentExpr);
519
+ value = this.visitResult(ctxCreateComponentExpr);
554
520
  }
555
521
  else if (ctxCreateGraphicExpr) {
556
- this.visit(ctxCreateGraphicExpr);
557
- value = this.getResult(ctxCreateGraphicExpr);
522
+ value = this.visitResult(ctxCreateGraphicExpr);
558
523
  }
559
524
  else if (ctxCreateModuleExpr) {
560
- this.visit(ctxCreateModuleExpr);
561
- value = this.getResult(ctxCreateModuleExpr);
525
+ value = this.visitResult(ctxCreateModuleExpr);
562
526
  }
563
527
  else {
564
528
  throw "Invalid data expression";
@@ -568,10 +532,14 @@ export class ParserVisitor extends BaseVisitor {
568
532
  visitBinaryOperatorExpr = (ctx) => {
569
533
  const ctx0 = ctx.data_expr(0);
570
534
  const ctx1 = ctx.data_expr(1);
571
- this.visit(ctx0);
572
- this.visit(ctx1);
573
- const value1 = this.getResult(ctx0);
574
- const value2 = this.getResult(ctx1);
535
+ let value1 = this.visitResult(ctx0);
536
+ let value2 = this.visitResult(ctx1);
537
+ if (value1 instanceof NumericValue) {
538
+ value1 = value1.toNumber();
539
+ }
540
+ if (value2 instanceof NumericValue) {
541
+ value2 = value2.toNumber();
542
+ }
575
543
  const binaryOperatorType = ctx.binary_operator();
576
544
  let result = null;
577
545
  if (binaryOperatorType.Equals()) {
@@ -597,60 +565,87 @@ export class ParserVisitor extends BaseVisitor {
597
565
  visitLogicalOperatorExpr = (ctx) => {
598
566
  const ctx0 = ctx.data_expr(0);
599
567
  const ctx1 = ctx.data_expr(1);
600
- this.visit(ctx0);
601
- const value1 = this.getResult(ctx0);
568
+ let value1 = this.visitResult(ctx0);
569
+ if (value1 instanceof NumericValue) {
570
+ value1 = value1.toNumber();
571
+ }
602
572
  let value2 = false;
603
573
  let skipNext = false;
604
- if (ctx.LogicalOr() && value1) {
574
+ const isLogicalOr = ctx.LogicalOr();
575
+ if (isLogicalOr && value1) {
605
576
  skipNext = true;
606
577
  }
607
578
  if (!skipNext) {
608
- this.visit(ctx1);
609
- value2 = this.getResult(ctx1);
579
+ value2 = this.visitResult(ctx1);
580
+ if (value2 instanceof NumericValue) {
581
+ value2 = value2.toNumber();
582
+ }
610
583
  }
611
584
  let result = null;
612
585
  if (ctx.LogicalAnd()) {
613
586
  result = value1 && value2;
614
587
  }
615
- else if (ctx.LogicalOr()) {
588
+ else if (isLogicalOr) {
616
589
  result = value1 || value2;
617
590
  }
591
+ if (typeof result === "number") {
592
+ result = numeric(result);
593
+ }
618
594
  this.setResult(ctx, result);
619
595
  };
620
596
  visitMultiplyExpr = (ctx) => {
621
597
  const value1 = this.resolveDataExpr(ctx.data_expr(0));
622
598
  const value2 = this.resolveDataExpr(ctx.data_expr(1));
599
+ const operator = new NumberOperator();
600
+ const tmpValue1 = operator.prepare(value1);
601
+ const tmpValue2 = operator.prepare(value2);
623
602
  let result = null;
624
603
  if (ctx.Multiply()) {
625
- result = value1 * value2;
604
+ result = operator.multiply(tmpValue1, tmpValue2);
626
605
  }
627
606
  else if (ctx.Divide()) {
628
- result = value1 / value2;
607
+ result = operator.divide(tmpValue1, tmpValue2);
629
608
  }
630
609
  else if (ctx.Modulus()) {
631
- result = value1 % value2;
610
+ result = operator.modulus(tmpValue1, tmpValue2);
632
611
  }
633
612
  this.setResult(ctx, result);
634
613
  };
635
614
  visitAdditionExpr = (ctx) => {
636
615
  const value1 = this.resolveDataExpr(ctx.data_expr(0));
637
616
  const value2 = this.resolveDataExpr(ctx.data_expr(1));
638
- let result = null;
639
- if (ctx.Addition()) {
640
- result = value1 + value2;
617
+ if (ctx.Addition() && (typeof value1 === 'string' || typeof value2 === 'string')) {
618
+ let tmpValue1 = value1;
619
+ if (value1 instanceof NumericValue) {
620
+ tmpValue1 = value1.toDisplayString();
621
+ }
622
+ let tmpValue2 = value2;
623
+ if (value2 instanceof NumericValue) {
624
+ tmpValue2 = value2.toDisplayString();
625
+ }
626
+ const result = tmpValue1 + tmpValue2;
627
+ this.setResult(ctx, result);
641
628
  }
642
- else if (ctx.Minus()) {
643
- result = value1 - value2;
629
+ else {
630
+ const operator = new NumberOperator();
631
+ const tmpValue1 = operator.prepare(value1);
632
+ const tmpValue2 = operator.prepare(value2);
633
+ let result = null;
634
+ if (ctx.Addition()) {
635
+ result = operator.addition(tmpValue1, tmpValue2);
636
+ }
637
+ else if (ctx.Minus()) {
638
+ result = operator.subtraction(tmpValue1, tmpValue2);
639
+ }
640
+ this.setResult(ctx, result);
644
641
  }
645
- this.setResult(ctx, result);
646
642
  };
647
643
  visitFunction_def_expr = (ctx) => {
648
644
  const functionName = ctx.ID().getText();
649
645
  let funcDefinedParameters = [];
650
646
  const ctxFunctionArgsExpr = ctx.function_args_expr();
651
647
  if (ctxFunctionArgsExpr) {
652
- this.visit(ctxFunctionArgsExpr);
653
- funcDefinedParameters = this.getResult(ctxFunctionArgsExpr);
648
+ funcDefinedParameters = this.visitResult(ctxFunctionArgsExpr);
654
649
  }
655
650
  const executionStack = this.executionStack;
656
651
  const functionCounter = { counter: 0 };
@@ -681,12 +676,9 @@ export class ParserVisitor extends BaseVisitor {
681
676
  this.setResult(ctx, result);
682
677
  };
683
678
  visitAt_block_pin_expr = (ctx) => {
684
- const ctxPinSelectExpr2 = ctx.pin_select_expr2();
685
- this.visit(ctxPinSelectExpr2);
686
- const atPin = this.getResult(ctxPinSelectExpr2);
679
+ const atPin = this.visitResult(ctx.pin_select_expr2());
687
680
  const executor = this.getExecutor();
688
- const currentComponent = executor.scope.currentComponent;
689
- const currentPin = executor.scope.currentPin;
681
+ const [currentComponent, currentPin] = executor.getCurrentPoint();
690
682
  executor.atComponent(currentComponent, atPin, {
691
683
  addSequence: true
692
684
  });
@@ -748,8 +740,7 @@ export class ParserVisitor extends BaseVisitor {
748
740
  useValue = Number(ctxIntegerValue);
749
741
  }
750
742
  else if (ctxDataExpr) {
751
- this.visit(ctxDataExpr);
752
- useValue = this.getResult(ctxDataExpr);
743
+ useValue = this.visitResult(ctxDataExpr);
753
744
  }
754
745
  if (useValue !== null) {
755
746
  this.setResult(ctx, [direction, new UnitDimension(useValue)]);
@@ -761,8 +752,7 @@ export class ParserVisitor extends BaseVisitor {
761
752
  visitWire_expr = (ctx) => {
762
753
  const wireAtomExpr = ctx.wire_atom_expr();
763
754
  const segments = wireAtomExpr.map(wireSegment => {
764
- this.visit(wireSegment);
765
- return this.getResult(wireSegment);
755
+ return this.visitResult(wireSegment);
766
756
  });
767
757
  this.getExecutor().addWire(segments);
768
758
  };
@@ -771,18 +761,12 @@ export class ParserVisitor extends BaseVisitor {
771
761
  return this.getExecutor().addPoint(ID.getText());
772
762
  };
773
763
  visitProperty_set_expr = (ctx) => {
774
- const ctxDataExpr = ctx.data_expr();
775
- this.visit(ctxDataExpr);
776
- const result = this.getResult(ctxDataExpr);
777
- const ctxAtomExpr = ctx.atom_expr();
778
- this.visit(ctxAtomExpr);
779
- const resolvedProperty = this.getResult(ctxAtomExpr);
764
+ const result = this.visitResult(ctx.data_expr());
765
+ const resolvedProperty = this.visitResult(ctx.atom_expr());
780
766
  this.getExecutor().setProperty(resolvedProperty, result);
781
767
  };
782
768
  visitDouble_dot_property_set_expr = (ctx) => {
783
- const ctxDataExpr = ctx.data_expr();
784
- this.visit(ctxDataExpr);
785
- const result = this.getResult(ctxDataExpr);
769
+ const result = this.visitResult(ctx.data_expr());
786
770
  const propertyName = ctx.ID().getText();
787
771
  this.getExecutor().setProperty('..' + propertyName, result);
788
772
  };
@@ -804,8 +788,7 @@ export class ParserVisitor extends BaseVisitor {
804
788
  const hasPlus = ctx.Addition();
805
789
  const ctxDataExpr = ctx.data_expr();
806
790
  if (ctxDataExpr) {
807
- this.visit(ctxDataExpr);
808
- dataValue = this.getResult(ctxDataExpr);
791
+ dataValue = this.visitResult(ctxDataExpr);
809
792
  if (dataValue instanceof UndeclaredReference) {
810
793
  netNamespace = "/" + dataValue.reference.name;
811
794
  }
@@ -822,19 +805,19 @@ export class ParserVisitor extends BaseVisitor {
822
805
  this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
823
806
  };
824
807
  visitIf_expr = (ctx) => {
825
- const ctxDataExpr = ctx.data_expr();
826
- this.visit(ctxDataExpr);
827
- const result = this.getResult(ctxDataExpr);
828
- if (result) {
808
+ const result = this.visitResult(ctx.data_expr());
809
+ let resultValue = result;
810
+ if (result instanceof UndeclaredReference) {
811
+ resultValue = false;
812
+ }
813
+ if (resultValue) {
829
814
  this.visit(ctx.expressions_block());
830
815
  }
831
816
  else {
832
817
  const ctxInnerIfExprs = ctx.if_inner_expr();
833
818
  let innerIfWasTrue = false;
834
819
  for (let i = 0; i < ctxInnerIfExprs.length; i++) {
835
- const tmpCtx = ctxInnerIfExprs[i];
836
- this.visit(tmpCtx);
837
- const innerResult = this.getResult(tmpCtx);
820
+ const innerResult = this.visitResult(ctxInnerIfExprs[i]);
838
821
  if (innerResult) {
839
822
  innerIfWasTrue = true;
840
823
  break;
@@ -849,9 +832,7 @@ export class ParserVisitor extends BaseVisitor {
849
832
  }
850
833
  };
851
834
  visitIf_inner_expr = (ctx) => {
852
- const ctxDataExpr = ctx.data_expr();
853
- this.visit(ctxDataExpr);
854
- const result = this.getResult(ctxDataExpr);
835
+ const result = this.visitResult(ctx.data_expr());
855
836
  if (result) {
856
837
  this.visit(ctx.expressions_block());
857
838
  }
@@ -863,8 +844,7 @@ export class ParserVisitor extends BaseVisitor {
863
844
  this.log('enter while loop');
864
845
  this.getExecutor().addBreakContext(ctx);
865
846
  while (keepLooping) {
866
- this.visit(dataExpr);
867
- const result = this.getResult(dataExpr);
847
+ const result = this.visitResult(dataExpr);
868
848
  if (result) {
869
849
  this.visit(ctx.expressions_block());
870
850
  keepLooping = true;
@@ -889,10 +869,9 @@ export class ParserVisitor extends BaseVisitor {
889
869
  this.log('exit while loop');
890
870
  };
891
871
  visitFor_expr = (ctx) => {
872
+ this.log('in for loop');
892
873
  const forVariableNames = ctx.ID().map(item => item.getText());
893
- const ctxDataExpr = ctx.data_expr();
894
- this.visit(ctxDataExpr);
895
- const listItems = this.getResult(ctxDataExpr);
874
+ const listItems = this.visitResult(ctx.data_expr());
896
875
  this.getExecutor().addBreakContext(ctx);
897
876
  let keepLooping = true;
898
877
  let counter = 0;
@@ -909,6 +888,7 @@ export class ParserVisitor extends BaseVisitor {
909
888
  keepLooping = true;
910
889
  const currentResult = this.getResult(ctx) ?? {};
911
890
  const { breakSignal = false, continueSignal = false } = currentResult;
891
+ this.log('condition result: ', breakSignal, continueSignal);
912
892
  if (breakSignal && !continueSignal) {
913
893
  keepLooping = false;
914
894
  }
@@ -928,13 +908,24 @@ export class ParserVisitor extends BaseVisitor {
928
908
  this.getExecutor().popBreakContext();
929
909
  };
930
910
  resolveDataExpr(data_expr) {
931
- this.visit(data_expr);
932
- const value = this.getResult(data_expr);
911
+ const value = this.visitResult(data_expr);
933
912
  if (value instanceof UndeclaredReference) {
934
- throw value.throwMessage();
913
+ this.throwWithContext(data_expr, value.throwMessage());
914
+ }
915
+ else if (value instanceof DeclaredReference) {
916
+ return this.resolveDataValue(value);
935
917
  }
936
918
  return value;
937
919
  }
920
+ resolveDataValue(reference) {
921
+ const { value } = reference;
922
+ if (value instanceof NumericValue) {
923
+ return value.toDisplayString();
924
+ }
925
+ else {
926
+ return value;
927
+ }
928
+ }
938
929
  pinTypes = [
939
930
  PinTypes.Any,
940
931
  PinTypes.IO,
@@ -944,8 +935,8 @@ export class ParserVisitor extends BaseVisitor {
944
935
  ];
945
936
  parseCreateComponentPins(pinData) {
946
937
  const pins = [];
947
- if (typeof pinData === 'number') {
948
- const lastPin = pinData;
938
+ if (pinData instanceof NumericValue) {
939
+ const lastPin = pinData.toNumber();
949
940
  for (let i = 0; i < lastPin; i++) {
950
941
  const pinId = i + 1;
951
942
  pins.push(new PinDefinition(pinId, PinIdType.Int, pinId.toString()));
@@ -981,30 +972,49 @@ export class ParserVisitor extends BaseVisitor {
981
972
  else {
982
973
  pinName = pinDef;
983
974
  }
975
+ this.log('pins', pinId, pinIdType, pinName, pinType, altPinNames);
984
976
  pins.push(new PinDefinition(pinId, pinIdType, pinName, pinType, altPinNames));
985
977
  }
986
978
  }
987
979
  return pins;
988
980
  }
989
981
  parseCreateModulePorts(portsDefinition) {
990
- let leftItems = [];
991
- let rightItems = [];
992
- if (portsDefinition.has('left')) {
993
- leftItems = portsDefinition.get('left');
994
- if (!Array.isArray(leftItems)) {
995
- leftItems = [leftItems];
982
+ return {
983
+ left: this.getPortItems(portsDefinition, SymbolPinSide.Left),
984
+ right: this.getPortItems(portsDefinition, SymbolPinSide.Right),
985
+ top: this.getPortItems(portsDefinition, SymbolPinSide.Top),
986
+ bottom: this.getPortItems(portsDefinition, SymbolPinSide.Bottom),
987
+ };
988
+ }
989
+ getArrangePropFromModulePorts(modulePorts, nameToPinId) {
990
+ const keys = [SymbolPinSide.Left, SymbolPinSide.Right, SymbolPinSide.Top, SymbolPinSide.Bottom];
991
+ const arrangeProp = new Map();
992
+ keys.forEach(key => {
993
+ if (modulePorts[key]) {
994
+ const items = modulePorts[key].map(item => {
995
+ if (Array.isArray(item)) {
996
+ return item;
997
+ }
998
+ else {
999
+ return numeric(nameToPinId.get(item));
1000
+ }
1001
+ });
1002
+ if (items.length > 0) {
1003
+ arrangeProp.set(key, items);
1004
+ }
996
1005
  }
997
- }
998
- if (portsDefinition.has('right')) {
999
- rightItems = portsDefinition.get('right');
1000
- if (!Array.isArray(rightItems)) {
1001
- rightItems = [rightItems];
1006
+ });
1007
+ return arrangeProp;
1008
+ }
1009
+ getPortItems(portsDefinition, key) {
1010
+ let tmpItems = [];
1011
+ if (portsDefinition.has(key)) {
1012
+ tmpItems = portsDefinition.get(key);
1013
+ if (!Array.isArray(tmpItems)) {
1014
+ tmpItems = [tmpItems];
1002
1015
  }
1003
1016
  }
1004
- return {
1005
- left: leftItems,
1006
- right: rightItems
1007
- };
1017
+ return tmpItems;
1008
1018
  }
1009
1019
  parseCreateComponentParams(params) {
1010
1020
  const result = [];
@@ -1083,8 +1093,7 @@ export class ParserVisitor extends BaseVisitor {
1083
1093
  const nets = executor.scope.getNets();
1084
1094
  return {
1085
1095
  sequence,
1086
- nets,
1087
- components: Array.from(executor.scope.instances.values())
1096
+ nets
1088
1097
  };
1089
1098
  }
1090
1099
  annotateComponents() {
@@ -1093,16 +1102,11 @@ export class ParserVisitor extends BaseVisitor {
1093
1102
  const instances = this.getExecutor().scope.instances;
1094
1103
  const toAnnotate = [];
1095
1104
  for (const [, instance] of instances) {
1105
+ if (instance.typeProp === ComponentTypes.net
1106
+ || instance.typeProp == ComponentTypes.graphic) {
1107
+ continue;
1108
+ }
1096
1109
  if (instance.assignedRefDes === null) {
1097
- if (instance.typeProp === ComponentTypes.label ||
1098
- instance.typeProp === ComponentTypes.net ||
1099
- instance.typeProp === ComponentTypes.point) {
1100
- continue;
1101
- }
1102
- if (instance.typeProp === null) {
1103
- this.log('Instance has no type:', instance.instanceName, ' assuming connector');
1104
- instance.typeProp = 'conn';
1105
- }
1106
1110
  if (instance.parameters.has('refdes')) {
1107
1111
  const refdes = instance.parameters.get('refdes');
1108
1112
  if (refdes) {
@@ -1116,7 +1120,10 @@ export class ParserVisitor extends BaseVisitor {
1116
1120
  }
1117
1121
  }
1118
1122
  toAnnotate.forEach(instance => {
1119
- const newRefDes = annotater.getAnnotation(instance.typeProp);
1123
+ const useTypeProp = instance.typeProp ?? 'conn';
1124
+ instance.typeProp === null
1125
+ && this.log('Instance has no type:', instance.instanceName, ' assuming connector');
1126
+ const newRefDes = annotater.getAnnotation(useTypeProp);
1120
1127
  if (newRefDes !== null) {
1121
1128
  instance.assignedRefDes = newRefDes;
1122
1129
  this.log(newRefDes, '-', instance.instanceName);
@@ -1134,10 +1141,14 @@ export class ParserVisitor extends BaseVisitor {
1134
1141
  let frameComponent = null;
1135
1142
  if (document && document[FrameParamKeys.SheetType]) {
1136
1143
  frameComponent = document[FrameParamKeys.SheetType];
1137
- baseScope.frames.forEach(item => {
1138
- if (item.frameType === FrameType.Sheet) {
1139
- item.parameters.set(FrameParamKeys.SheetType, frameComponent);
1140
- }
1144
+ const sheets = baseScope.frames.filter(item => {
1145
+ return item.frameType === FrameType.Sheet;
1146
+ });
1147
+ const totalSheets = sheets.length;
1148
+ sheets.forEach((item, index) => {
1149
+ item.parameters.set(FrameParamKeys.SheetType, frameComponent)
1150
+ .set(FrameParamKeys.SheetNumber, index + 1)
1151
+ .set(FrameParamKeys.SheetTotal, totalSheets);
1141
1152
  });
1142
1153
  }
1143
1154
  return {
@@ -1162,25 +1173,10 @@ export class ParserVisitor extends BaseVisitor {
1162
1173
  }
1163
1174
  return result;
1164
1175
  }
1165
- setComponentOrientation(component, pin, orientation) {
1166
- if (this.acceptedDirections.indexOf(orientation) !== -1) {
1167
- component.setParam('_addDirection', orientation);
1168
- component.setParam('_addPin', pin);
1169
- }
1170
- else {
1171
- throw "Invalid modifier for orientation";
1172
- }
1173
- }
1174
- setComponentFlip(component, flipValue) {
1175
- if (this.acceptedFlip.indexOf(flipValue) !== -1) {
1176
- component.setParam(flipValue, 1);
1177
- }
1178
- }
1179
1176
  getPropertyExprList(items) {
1180
1177
  const properties = new Map();
1181
1178
  items.forEach((item) => {
1182
- this.visit(item);
1183
- const result = this.getResult(item);
1179
+ const result = this.visitResult(item);
1184
1180
  for (const [key, value] of result) {
1185
1181
  properties.set(key, value);
1186
1182
  }
@@ -1189,14 +1185,14 @@ export class ParserVisitor extends BaseVisitor {
1189
1185
  }
1190
1186
  }
1191
1187
  const ComponentRefDesPrefixes = {
1192
- 'res': 'R',
1193
- 'cap': 'C',
1194
- 'ind': 'L',
1195
- 'diode': 'D',
1196
- 'conn': 'J',
1197
- 'transistor': 'Q',
1198
- 'relay': 'K',
1199
- 'ic': 'U',
1188
+ res: 'R',
1189
+ cap: 'C',
1190
+ ind: 'L',
1191
+ diode: 'D',
1192
+ conn: 'J',
1193
+ transistor: 'Q',
1194
+ relay: 'K',
1195
+ ic: 'U',
1200
1196
  '?': '?',
1201
1197
  };
1202
1198
  class ComponentAnnotater {
@@ -1206,7 +1202,6 @@ class ComponentAnnotater {
1206
1202
  for (const key in ComponentRefDesPrefixes) {
1207
1203
  this.counter[key] = 1;
1208
1204
  }
1209
- this.counter['?'] = 1;
1210
1205
  }
1211
1206
  getAnnotation(type) {
1212
1207
  if (this.counter[type] === undefined && type.length <= 2) {
@@ -1224,7 +1219,7 @@ class ComponentAnnotater {
1224
1219
  return null;
1225
1220
  }
1226
1221
  let attempts = 100;
1227
- let proposedName;
1222
+ let proposedName = "";
1228
1223
  while (attempts >= 0) {
1229
1224
  proposedName = ComponentRefDesPrefixes[type] + this.counter[type];
1230
1225
  this.counter[type]++;