circuitscript 0.0.38 → 0.1.0

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 (38) hide show
  1. package/dist/cjs/BaseVisitor.js +56 -38
  2. package/dist/cjs/SymbolValidatorVisitor.js +1 -1
  3. package/dist/cjs/antlr/CircuitScriptParser.js +348 -323
  4. package/dist/cjs/builtinMethods.js +5 -2
  5. package/dist/cjs/draw_symbols.js +63 -45
  6. package/dist/cjs/execute.js +29 -16
  7. package/dist/cjs/globals.js +2 -1
  8. package/dist/cjs/layout.js +14 -26
  9. package/dist/cjs/objects/Frame.js +2 -0
  10. package/dist/cjs/objects/types.js +41 -0
  11. package/dist/cjs/render.js +1 -0
  12. package/dist/cjs/utils.js +25 -1
  13. package/dist/cjs/visitor.js +70 -35
  14. package/dist/esm/BaseVisitor.mjs +56 -38
  15. package/dist/esm/SymbolValidatorVisitor.mjs +1 -1
  16. package/dist/esm/antlr/CircuitScriptParser.mjs +348 -323
  17. package/dist/esm/builtinMethods.mjs +5 -2
  18. package/dist/esm/draw_symbols.mjs +67 -47
  19. package/dist/esm/execute.mjs +29 -16
  20. package/dist/esm/globals.mjs +1 -0
  21. package/dist/esm/layout.mjs +13 -26
  22. package/dist/esm/objects/Frame.mjs +2 -0
  23. package/dist/esm/objects/types.mjs +42 -0
  24. package/dist/esm/render.mjs +2 -1
  25. package/dist/esm/utils.mjs +22 -0
  26. package/dist/esm/visitor.mjs +71 -36
  27. package/dist/types/BaseVisitor.d.ts +2 -1
  28. package/dist/types/antlr/CircuitScriptParser.d.ts +3 -0
  29. package/dist/types/draw_symbols.d.ts +11 -5
  30. package/dist/types/execute.d.ts +1 -1
  31. package/dist/types/globals.d.ts +1 -0
  32. package/dist/types/layout.d.ts +1 -0
  33. package/dist/types/objects/Frame.d.ts +3 -1
  34. package/dist/types/objects/types.d.ts +7 -2
  35. package/dist/types/utils.d.ts +3 -0
  36. package/dist/types/visitor.d.ts +1 -0
  37. package/libs/lib.cst +88 -30
  38. package/package.json +1 -1
@@ -157,10 +157,32 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
157
157
  this.setResult(ctx, createdComponent);
158
158
  };
159
159
  this.visitCreate_graphic_expr = (ctx) => {
160
- const graphicsExpressionsCtx = ctx.graphic_expressions_block();
161
- this.visit(graphicsExpressionsCtx);
162
- const commands = this.getResult(graphicsExpressionsCtx);
163
- const drawing = new draw_symbols_js_1.SymbolDrawingCommands(commands);
160
+ const ctxId = ctx.ID();
161
+ const paramIds = [];
162
+ if (ctxId !== null) {
163
+ const varName = ctxId.getText();
164
+ paramIds.push(varName);
165
+ this.getExecutor().scope.variables.set(varName, {});
166
+ }
167
+ const executor = this.getExecutor();
168
+ const stack = [...this.executionStack];
169
+ const drawing = new draw_symbols_js_1.SymbolDrawingCommands(variables => {
170
+ if (variables && paramIds.length > 0) {
171
+ const obj = {};
172
+ variables.forEach((value, key) => {
173
+ obj[key] = value;
174
+ });
175
+ executor.scope.variables.set(paramIds[0], obj);
176
+ }
177
+ const currentStack = this.executionStack.splice(0);
178
+ this.executionStack.push(...stack);
179
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
180
+ this.visit(graphicsExpressionsCtx);
181
+ const commands = this.getResult(graphicsExpressionsCtx);
182
+ this.executionStack.splice(0);
183
+ this.executionStack.push(...currentStack);
184
+ return commands;
185
+ });
164
186
  drawing.source = ctx.getText();
165
187
  this.setResult(ctx, drawing);
166
188
  };
@@ -182,7 +204,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
182
204
  }
183
205
  return accum;
184
206
  }, []);
185
- accum.push([commandName, positionParams, keywordParams]);
207
+ accum.push([commandName, positionParams, keywordParams, item]);
186
208
  }
187
209
  return accum;
188
210
  }, []);
@@ -302,7 +324,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
302
324
  const [firstBlock] = ctxPropertyBlock;
303
325
  this.visit(firstBlock);
304
326
  const [keyName, expressionsBlock] = this.getResult(firstBlock);
305
- if (keyName === 'contains') {
327
+ if (keyName === globals_js_1.ModuleContainsKeyword) {
306
328
  createdComponent.moduleContainsExpressions = expressionsBlock;
307
329
  this.expandModuleContains(createdComponent, this.getExecutor().netNamespace);
308
330
  }
@@ -323,7 +345,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
323
345
  this.visit(ctxPropertyValueExpr);
324
346
  const keyName = this.getResult(ctxPropertyKeyExpr);
325
347
  const value = this.getResult(ctxPropertyValueExpr);
326
- if (value instanceof types_js_1.UndeclaredReference) {
348
+ if (value instanceof types_js_1.UndeclaredReference && (value.reference.parentValue === undefined
349
+ && value.reference.value === undefined)) {
327
350
  throw value.throwMessage();
328
351
  }
329
352
  const map = new Map();
@@ -379,30 +402,34 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
379
402
  };
380
403
  this.visitData_expr_with_assignment = (ctx) => {
381
404
  let component = null;
405
+ let componentCtx = null;
382
406
  const ctxDataExpr = ctx.data_expr();
383
407
  const ctxAssignmentExpr = ctx.assignment_expr();
384
408
  if (ctxDataExpr) {
385
409
  this.visit(ctxDataExpr);
386
410
  component = this.getResult(ctxDataExpr);
411
+ componentCtx = ctxDataExpr;
387
412
  if (component === null || component === undefined) {
388
- throw "Could not find component: " + ctxDataExpr.getText();
413
+ this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
389
414
  }
390
415
  }
391
416
  else if (ctxAssignmentExpr) {
392
417
  this.visit(ctxAssignmentExpr);
393
418
  component = this.getResult(ctxAssignmentExpr);
419
+ componentCtx = ctxAssignmentExpr;
394
420
  }
395
421
  if (component instanceof ClassComponent_js_1.ClassComponent
396
422
  && component.copyProp) {
397
423
  component = this.getExecutor().copyComponent(component);
398
424
  }
399
- if (component instanceof types_js_1.DeclaredReference
400
- && component.found
401
- && component.trailers
402
- && component.trailers.length > 0
403
- && component.trailers[0] === 'contains') {
404
- component = component.value;
405
- this.placeModuleContains(component);
425
+ if (component instanceof types_js_1.UndeclaredReference) {
426
+ const { reference: { trailers = [], parentValue = null } } = component;
427
+ if (parentValue instanceof ClassComponent_js_1.ClassComponent
428
+ && trailers.length > 0
429
+ && trailers[0] === globals_js_1.ModuleContainsKeyword) {
430
+ component = parentValue;
431
+ this.placeModuleContains(component);
432
+ }
406
433
  }
407
434
  if (component && component instanceof ClassComponent_js_1.ClassComponent) {
408
435
  const modifiers = ctx.component_modifier_expr();
@@ -436,19 +463,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
436
463
  shouldIgnoreWireOrientation = true;
437
464
  }
438
465
  else if (modifierText === 'anchor') {
439
- if (component.displayProp
440
- && component.displayProp instanceof draw_symbols_js_1.SymbolDrawingCommands) {
441
- const commands = (component.displayProp)
442
- .getCommands();
443
- commands.forEach(command => {
444
- const positionParams = command[1];
445
- const keywordParams = command[2];
446
- if (command[0] === draw_symbols_js_1.PlaceHolderCommands.label
447
- && positionParams[0] === 'value') {
448
- keywordParams.set('anchor', result);
449
- }
450
- });
451
- }
466
+ component.setParam('anchor', result);
452
467
  }
453
468
  if (shouldIgnoreWireOrientation) {
454
469
  component.useWireOrientationAngle = false;
@@ -467,7 +482,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
467
482
  }
468
483
  else {
469
484
  const undeclaredRef = component;
470
- throw 'Invalid component: ' + undeclaredRef.reference.name;
485
+ this.throwWithContext(componentCtx, 'Invalid component: ' + undeclaredRef.reference.name);
471
486
  }
472
487
  }
473
488
  this.setResult(ctx, [component, pinValue]);
@@ -781,7 +796,11 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
781
796
  const ctxDataExpr = ctx.data_expr();
782
797
  this.visit(ctxDataExpr);
783
798
  const result = this.getResult(ctxDataExpr);
784
- if (result) {
799
+ let resultValue = result;
800
+ if (result instanceof types_js_1.UndeclaredReference) {
801
+ resultValue = false;
802
+ }
803
+ if (resultValue) {
785
804
  this.visit(ctx.expressions_block());
786
805
  }
787
806
  else {
@@ -944,10 +963,22 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
944
963
  this.visit(data_expr);
945
964
  const value = this.getResult(data_expr);
946
965
  if (value instanceof types_js_1.UndeclaredReference) {
947
- throw value.throwMessage();
966
+ this.throwWithContext(data_expr, value.throwMessage());
967
+ }
968
+ else if (value instanceof types_js_1.DeclaredReference) {
969
+ return this.resolveDataValue(value);
948
970
  }
949
971
  return value;
950
972
  }
973
+ resolveDataValue(reference) {
974
+ const { value } = reference;
975
+ if (value instanceof ParamDefinition_js_1.NumericValue) {
976
+ return value.toDisplayString();
977
+ }
978
+ else {
979
+ return value;
980
+ }
981
+ }
951
982
  parseCreateComponentPins(pinData) {
952
983
  const pins = [];
953
984
  if (typeof pinData === 'number') {
@@ -1140,10 +1171,14 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
1140
1171
  let frameComponent = null;
1141
1172
  if (document && document[Frame_js_1.FrameParamKeys.SheetType]) {
1142
1173
  frameComponent = document[Frame_js_1.FrameParamKeys.SheetType];
1143
- baseScope.frames.forEach(item => {
1144
- if (item.frameType === globals_js_1.FrameType.Sheet) {
1145
- item.parameters.set(Frame_js_1.FrameParamKeys.SheetType, frameComponent);
1146
- }
1174
+ const sheets = baseScope.frames.filter(item => {
1175
+ return item.frameType === globals_js_1.FrameType.Sheet;
1176
+ });
1177
+ const totalSheets = sheets.length;
1178
+ sheets.forEach((item, index) => {
1179
+ item.parameters.set(Frame_js_1.FrameParamKeys.SheetType, frameComponent);
1180
+ item.parameters.set(Frame_js_1.FrameParamKeys.SheetNumber, index + 1);
1181
+ item.parameters.set(Frame_js_1.FrameParamKeys.SheetTotal, totalSheets);
1147
1182
  });
1148
1183
  }
1149
1184
  return {
@@ -10,6 +10,7 @@ import { PinTypes } from "./objects/PinTypes";
10
10
  import { Direction, UndeclaredReference } from "./objects/types";
11
11
  import { GlobalDocumentName, ReferenceTypes } from './globals';
12
12
  import { linkBuiltInMethods } from './builtinMethods';
13
+ import { throwWithContext } from './utils';
13
14
  export class BaseVisitor extends CircuitScriptVisitor {
14
15
  indentLevel = 0;
15
16
  startingContext;
@@ -108,18 +109,21 @@ export class BaseVisitor extends CircuitScriptVisitor {
108
109
  tmpComponent.instanceName = reference.name;
109
110
  instances.delete(oldName);
110
111
  instances.set(reference.name, tmpComponent);
111
- this.getExecutor().log(`assigned '${reference.name}' to ClassComponent`);
112
+ this.log2(`assigned '${reference.name}' to ClassComponent`);
112
113
  }
113
114
  else {
114
115
  this.getExecutor().scope.variables.set(reference.name, value);
116
+ this.log2(`assigned variable ${reference.name} to ${value}`);
115
117
  }
116
118
  }
117
119
  else {
118
- if (reference.value instanceof ClassComponent) {
119
- this.setInstanceParam(reference.value, trailers, value);
120
+ if (reference.parentValue instanceof ClassComponent) {
121
+ this.setInstanceParam(reference.parentValue, trailers, value);
122
+ this.log2(`assigned component param ${reference.parentValue} trailers: ${trailers} value: ${value}`);
120
123
  }
121
- else if (reference.value instanceof Object) {
122
- reference.value[trailers.join('.')] = value;
124
+ else if (reference.parentValue instanceof Object) {
125
+ reference.parentValue[trailers.join('.')] = value;
126
+ this.log2(`assigned object ${reference.parentValue} trailers: ${trailers} value: ${value}`);
123
127
  }
124
128
  }
125
129
  this.setResult(ctx, value);
@@ -130,7 +134,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
130
134
  this.visit(ctxDataExpr);
131
135
  const value = this.getResult(ctxDataExpr);
132
136
  if (!reference.found) {
133
- throw 'Undefined reference: ' + reference.name;
137
+ this.throwWithContext(ctx, 'Undefined reference: ' + reference.name);
134
138
  }
135
139
  const trailers = reference.trailers ?? [];
136
140
  let currentValue = null;
@@ -146,7 +150,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
146
150
  }
147
151
  }
148
152
  if (currentValue === null) {
149
- throw 'Operator assignment failed: could not get value';
153
+ this.throwWithContext(ctx, 'Operator assignment failed: could not get value');
150
154
  }
151
155
  let newValue = 0;
152
156
  if (ctx.AdditionAssign()) {
@@ -165,7 +169,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
165
169
  newValue = currentValue % value;
166
170
  }
167
171
  else {
168
- throw 'Operator assignment failed: could not perform operator';
172
+ this.throwWithContext(ctx, 'Operator assignment failed: could not perform operator');
169
173
  }
170
174
  if (trailers.length === 0) {
171
175
  this.getExecutor().scope.variables.set(reference.name, newValue);
@@ -183,12 +187,15 @@ export class BaseVisitor extends CircuitScriptVisitor {
183
187
  getReference(ctx) {
184
188
  const atomStr = ctx.getText();
185
189
  if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
186
- throw "Invalid assignment expression!";
190
+ this.throwWithContext(ctx, "Invalid assignment expression!");
187
191
  }
188
192
  this.visit(ctx);
189
193
  const reference = this.getResult(ctx);
190
- if (!reference.found && reference.trailers && reference.trailers.length > 0) {
191
- throw 'Undefined reference: ' + reference.name + '.' + reference.trailers.join('.');
194
+ const { trailers = [] } = reference;
195
+ const undefinedParentWithTrailers = trailers.length > 0
196
+ && reference.parentValue === undefined;
197
+ if (undefinedParentWithTrailers) {
198
+ this.throwWithContext(ctx, 'Undefined reference: ' + reference.name + '.' + trailers.join('.'));
192
199
  }
193
200
  return reference;
194
201
  }
@@ -197,6 +204,14 @@ export class BaseVisitor extends CircuitScriptVisitor {
197
204
  const firstId = ctx.ID(0);
198
205
  const atomId = firstId.getText();
199
206
  let currentReference;
207
+ const idTrailers = [];
208
+ if (ctx.ID().length > 1) {
209
+ const idLength = ctx.ID().length;
210
+ for (let i = 1; i < idLength; i++) {
211
+ const tmpCtx = ctx.ID(i);
212
+ idTrailers.push(tmpCtx.getText());
213
+ }
214
+ }
200
215
  if (this.pinTypesList.indexOf(atomId) !== -1) {
201
216
  currentReference = {
202
217
  found: true,
@@ -205,26 +220,17 @@ export class BaseVisitor extends CircuitScriptVisitor {
205
220
  };
206
221
  }
207
222
  else {
208
- currentReference = executor.resolveVariable(this.executionStack, atomId);
209
- }
210
- const idTrailers = [];
211
- if (ctx.ID().length > 1) {
212
- const idLength = ctx.ID().length;
213
- for (let i = 1; i < idLength; i++) {
214
- const tmpCtx = ctx.ID(i);
215
- idTrailers.push(tmpCtx.getText());
216
- }
223
+ currentReference = executor.resolveVariable(this.executionStack, atomId, idTrailers);
217
224
  }
218
- currentReference.trailers = idTrailers;
219
- if (currentReference.found && currentReference.type === 'instance') {
225
+ if (currentReference.found && currentReference.type === 'instance' && idTrailers.length === 0) {
220
226
  const tmpComponent = currentReference.value;
221
227
  for (const [pinId, net] of tmpComponent.pinNets) {
222
228
  executor.scope.setNet(tmpComponent, pinId, net);
223
229
  }
224
230
  }
225
- this.getExecutor().log('atomId:', atomId, currentReference);
231
+ this.log2(`atomId: ${atomId} ${currentReference}`);
226
232
  if (ctx.parent instanceof ExpressionContext && !currentReference.found) {
227
- throw "Unknown symbol: " + atomId;
233
+ this.throwWithContext(ctx, "Unknown symbol: " + atomId);
228
234
  }
229
235
  this.setResult(ctx, currentReference);
230
236
  };
@@ -246,7 +252,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
246
252
  let currentReference = executor.resolveVariable(this.executionStack, atomId);
247
253
  if (ctx.trailer_expr().length > 0) {
248
254
  if (!currentReference.found) {
249
- throw "Unknown function name: " + atomId;
255
+ this.throwWithContext(ctx, "Unknown function name: " + atomId);
250
256
  }
251
257
  currentReference.trailers = [];
252
258
  ctx.trailer_expr().forEach(item => {
@@ -259,13 +265,18 @@ export class BaseVisitor extends CircuitScriptVisitor {
259
265
  parameters = this.getResult(ctxParameters);
260
266
  }
261
267
  const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
262
- const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
263
- currentReference = {
264
- found: true,
265
- value: functionResult,
266
- type: (functionResult instanceof ClassComponent) ?
267
- 'instance' : 'value',
268
- };
268
+ try {
269
+ const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
270
+ currentReference = {
271
+ found: true,
272
+ value: functionResult,
273
+ type: (functionResult instanceof ClassComponent) ?
274
+ 'instance' : 'value',
275
+ };
276
+ }
277
+ catch (err) {
278
+ this.throwWithContext(ctx, err);
279
+ }
269
280
  }
270
281
  else {
271
282
  currentReference.trailers.push(itemValue);
@@ -297,7 +308,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
297
308
  }
298
309
  else {
299
310
  if (sign === -1) {
300
- throw "Invalid value!";
311
+ this.throwWithContext(ctx, "Invalid value");
301
312
  }
302
313
  }
303
314
  if (ctxBooleanValue) {
@@ -384,7 +395,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
384
395
  visitImport_expr = (ctx) => {
385
396
  const ID = ctx.ID().toString();
386
397
  this.log('import', ID);
387
- this.handleImportFile(ID, true);
398
+ this.handleImportFile(ID, true, ctx);
388
399
  this.log('done import', ID);
389
400
  };
390
401
  visitFunction_return_expr = (ctx) => {
@@ -431,7 +442,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
431
442
  getResult(ctx) {
432
443
  return this.resultData.get(ctx);
433
444
  }
434
- handleImportFile(name, throwErrors = true) {
445
+ handleImportFile(name, throwErrors = true, ctx = null) {
435
446
  let hasError = false;
436
447
  let hasParseError = false;
437
448
  let pathExists = false;
@@ -466,14 +477,18 @@ export class BaseVisitor extends CircuitScriptVisitor {
466
477
  catch (err) {
467
478
  this.log('Failed to import file: ', err.message);
468
479
  }
480
+ let errorMessage = null;
469
481
  if (throwErrors && (hasError || hasParseError || !pathExists)) {
470
482
  if (!pathExists) {
471
- throw `File does not exist: ${name}`;
483
+ errorMessage = `File does not exist: ${name}`;
472
484
  }
473
485
  else {
474
- throw `Failed to import: ${name}`;
486
+ errorMessage = `Failed to import: ${name}`;
475
487
  }
476
488
  }
489
+ if (errorMessage !== null && ctx) {
490
+ this.throwWithContext(ctx, errorMessage);
491
+ }
477
492
  return {
478
493
  hasError,
479
494
  hasParseError,
@@ -561,7 +576,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
561
576
  setInstanceParam(object, trailers, value) {
562
577
  const paramName = trailers[0];
563
578
  object.setParam(paramName, value);
564
- this.getExecutor().log(`set instance ${object.instanceName} param ${paramName} to ${value}`);
579
+ this.log2(`set instance ${object.instanceName} param ${paramName} to ${value}`);
565
580
  }
566
581
  getInstanceParam(object, trailers) {
567
582
  const paramName = trailers[0];
@@ -582,4 +597,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
582
597
  prepareStringValue(value) {
583
598
  return value.slice(1, value.length - 1);
584
599
  }
600
+ throwWithContext(context, message) {
601
+ throwWithContext(context, message);
602
+ }
585
603
  }
@@ -37,7 +37,7 @@ export class SymbolValidatorVisitor extends BaseVisitor {
37
37
  }
38
38
  visitImport_expr = (ctx) => {
39
39
  const ID = ctx.ID().toString();
40
- const { pathExists } = this.handleImportFile(ID, false);
40
+ const { pathExists } = this.handleImportFile(ID, false, ctx);
41
41
  if (!pathExists) {
42
42
  this.symbolTable.addUndefined(this.getExecutor(), ID, ctx.ID());
43
43
  }