circuitscript 0.1.5 → 0.1.7

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 (96) hide show
  1. package/dist/cjs/BaseVisitor.js +127 -73
  2. package/dist/cjs/SemanticTokenVisitor.js +19 -13
  3. package/dist/cjs/antlr/CircuitScriptParser.js +711 -671
  4. package/dist/cjs/builtinMethods.js +29 -25
  5. package/dist/cjs/environment.js +118 -0
  6. package/dist/cjs/execute.js +53 -12
  7. package/dist/cjs/geometry.js +1 -0
  8. package/dist/cjs/globals.js +11 -6
  9. package/dist/cjs/helpers.js +135 -127
  10. package/dist/cjs/index.js +5 -0
  11. package/dist/cjs/layout.js +37 -12
  12. package/dist/cjs/main.js +31 -19
  13. package/dist/cjs/objects/ExecutionScope.js +33 -0
  14. package/dist/cjs/objects/ParamDefinition.js +15 -15
  15. package/dist/cjs/parser.js +27 -21
  16. package/dist/cjs/regenerate-tests.js +9 -6
  17. package/dist/cjs/render.js +3 -1
  18. package/dist/cjs/sizing.js +5 -58
  19. package/dist/cjs/utils.js +85 -30
  20. package/dist/cjs/validate/SymbolTable.js +96 -0
  21. package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +14 -0
  22. package/dist/cjs/validate/SymbolValidatorVisitor.js +170 -0
  23. package/dist/cjs/validate.js +52 -44
  24. package/dist/cjs/visitor.js +140 -24
  25. package/dist/esm/{BaseVisitor.mjs → BaseVisitor.js} +98 -45
  26. package/dist/esm/{SemanticTokenVisitor.mjs → SemanticTokenVisitor.js} +17 -11
  27. package/dist/esm/antlr/{CircuitScriptParser.mjs → CircuitScriptParser.js} +711 -671
  28. package/dist/esm/{builtinMethods.mjs → builtinMethods.js} +20 -16
  29. package/dist/esm/{draw_symbols.mjs → draw_symbols.js} +7 -7
  30. package/dist/esm/environment.js +110 -0
  31. package/dist/esm/{execute.mjs → execute.js} +66 -25
  32. package/dist/esm/{export.mjs → export.js} +2 -2
  33. package/dist/esm/{geometry.mjs → geometry.js} +6 -5
  34. package/dist/esm/{globals.mjs → globals.js} +6 -1
  35. package/dist/esm/helpers.js +377 -0
  36. package/dist/esm/index.js +20 -0
  37. package/dist/esm/{layout.mjs → layout.js} +42 -20
  38. package/dist/esm/{lexer.mjs → lexer.js} +2 -2
  39. package/dist/esm/{main.mjs → main.js} +33 -21
  40. package/dist/esm/objects/{ClassComponent.mjs → ClassComponent.js} +5 -4
  41. package/dist/esm/objects/{ExecutionScope.mjs → ExecutionScope.js} +33 -0
  42. package/dist/esm/objects/{Frame.mjs → Frame.js} +1 -1
  43. package/dist/esm/objects/{ParamDefinition.mjs → ParamDefinition.js} +1 -1
  44. package/dist/esm/objects/{PinDefinition.mjs → PinDefinition.js} +1 -1
  45. package/dist/esm/parser.js +71 -0
  46. package/dist/esm/{regenerate-tests.mjs → regenerate-tests.js} +10 -7
  47. package/dist/esm/{render.mjs → render.js} +11 -9
  48. package/dist/esm/{sizing.mjs → sizing.js} +6 -34
  49. package/dist/esm/{utils.mjs → utils.js} +61 -17
  50. package/dist/esm/validate/SymbolTable.js +90 -0
  51. package/dist/esm/validate/SymbolValidatorResolveVisitor.js +10 -0
  52. package/dist/esm/validate/SymbolValidatorVisitor.js +163 -0
  53. package/dist/esm/validate.js +86 -0
  54. package/dist/esm/{visitor.mjs → visitor.js} +151 -35
  55. package/dist/fonts/Arial.ttf +0 -0
  56. package/dist/fonts/Inter-Bold.ttf +0 -0
  57. package/dist/fonts/Inter-Regular.ttf +0 -0
  58. package/dist/fonts/OpenSans-Regular.ttf +0 -0
  59. package/dist/fonts/Roboto-Regular.ttf +0 -0
  60. package/dist/libs/lib.cst +423 -0
  61. package/dist/types/BaseVisitor.d.ts +34 -21
  62. package/dist/types/SemanticTokenVisitor.d.ts +6 -5
  63. package/dist/types/antlr/CircuitScriptParser.d.ts +4 -2
  64. package/dist/types/builtinMethods.d.ts +3 -2
  65. package/dist/types/environment.d.ts +31 -0
  66. package/dist/types/globals.d.ts +4 -1
  67. package/dist/types/helpers.d.ts +12 -14
  68. package/dist/types/index.d.ts +5 -0
  69. package/dist/types/objects/ClassComponent.d.ts +1 -0
  70. package/dist/types/objects/ExecutionScope.d.ts +11 -0
  71. package/dist/types/objects/types.d.ts +6 -1
  72. package/dist/types/parser.d.ts +7 -11
  73. package/dist/types/sizing.d.ts +0 -3
  74. package/dist/types/utils.d.ts +30 -6
  75. package/dist/types/validate/SymbolTable.d.ts +40 -0
  76. package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +7 -0
  77. package/dist/types/validate/SymbolValidatorVisitor.d.ts +32 -0
  78. package/dist/types/validate.d.ts +1 -1
  79. package/package.json +14 -13
  80. package/dist/cjs/SymbolValidatorVisitor.js +0 -233
  81. package/dist/esm/SymbolValidatorVisitor.mjs +0 -222
  82. package/dist/esm/helpers.mjs +0 -364
  83. package/dist/esm/index.mjs +0 -15
  84. package/dist/esm/parser.mjs +0 -64
  85. package/dist/esm/validate.mjs +0 -74
  86. package/dist/types/SymbolValidatorVisitor.d.ts +0 -61
  87. package/dist/types/layout.d.ts +0 -148
  88. /package/dist/esm/antlr/{CircuitScriptLexer.mjs → CircuitScriptLexer.js} +0 -0
  89. /package/dist/esm/antlr/{CircuitScriptVisitor.mjs → CircuitScriptVisitor.js} +0 -0
  90. /package/dist/esm/{fonts.mjs → fonts.js} +0 -0
  91. /package/dist/esm/{logger.mjs → logger.js} +0 -0
  92. /package/dist/esm/objects/{Net.mjs → Net.js} +0 -0
  93. /package/dist/esm/objects/{PinTypes.mjs → PinTypes.js} +0 -0
  94. /package/dist/esm/objects/{Wire.mjs → Wire.js} +0 -0
  95. /package/dist/esm/objects/{types.mjs → types.js} +0 -0
  96. /package/dist/esm/{server.mjs → server.js} +0 -0
@@ -1,26 +1,22 @@
1
- import { readFileSync } from 'fs';
2
- import { join } from 'path';
3
1
  import { Big } from 'big.js';
4
- import { ExpressionContext } from "./antlr/CircuitScriptParser";
5
- import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor";
6
- import { ExecutionContext } from "./execute";
7
- import { Logger } from "./logger";
8
- import { ClassComponent } from "./objects/ClassComponent";
9
- import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition";
10
- import { PinTypes } from "./objects/PinTypes";
11
- import { Direction, UndeclaredReference } from "./objects/types";
12
- import { DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals';
13
- import { linkBuiltInMethods } from './builtinMethods';
14
- import { resolveToNumericValue, throwWithContext } from './utils';
15
- import { SequenceAction } from './objects/ExecutionScope';
2
+ import { ExpressionContext } from "./antlr/CircuitScriptParser.js";
3
+ import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor.js";
4
+ import { ExecutionContext } from "./execute.js";
5
+ import { Logger } from "./logger.js";
6
+ import { ClassComponent } from "./objects/ClassComponent.js";
7
+ import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition.js";
8
+ import { PinTypes } from "./objects/PinTypes.js";
9
+ import { Direction, UndeclaredReference } from "./objects/types.js";
10
+ import { DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals.js';
11
+ import { linkBuiltInMethods } from './builtinMethods.js';
12
+ import { resolveToNumericValue, RuntimeExecutionError, throwWithContext } from './utils.js';
13
+ import { SequenceAction } from './objects/ExecutionScope.js';
16
14
  export class BaseVisitor extends CircuitScriptVisitor {
17
15
  indentLevel = 0;
18
16
  startingContext;
19
17
  executionStack;
20
18
  silent = false;
21
19
  logger;
22
- currentDirectory;
23
- defaultLibsPath;
24
20
  printStream = [];
25
21
  printToConsole = true;
26
22
  acceptedDirections = [Direction.Up, Direction.Down,
@@ -34,14 +30,17 @@ export class BaseVisitor extends CircuitScriptVisitor {
34
30
  PinTypes.IO,
35
31
  PinTypes.Power,
36
32
  ];
37
- onErrorCallbackHandler = null;
38
- onImportFile = (visitor, filePath) => {
33
+ onErrorHandler = null;
34
+ environment;
35
+ importedFiles = [];
36
+ onImportFile = async (visitor, filePath, fileData, onErrorHandler) => {
39
37
  throw "Import file not implemented";
40
38
  };
41
- constructor(silent = false, onErrorHandler = null, currentDirectory, defaultLibsPath) {
39
+ constructor(silent = false, onErrorHandler = null, environment) {
42
40
  super();
43
41
  this.logger = new Logger();
44
- this.onErrorCallbackHandler = onErrorHandler;
42
+ this.onErrorHandler = onErrorHandler;
43
+ this.environment = environment;
45
44
  this.startingContext = new ExecutionContext(DoubleDelimiter1, `${DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, null);
46
45
  const scope = this.startingContext.scope;
47
46
  scope.sequence.push([
@@ -55,12 +54,16 @@ export class BaseVisitor extends CircuitScriptVisitor {
55
54
  this.startingContext.resolveComponentPinNet =
56
55
  this.createComponentPinNetResolver(this.executionStack);
57
56
  this.silent = silent;
58
- this.currentDirectory = currentDirectory;
59
- this.defaultLibsPath = defaultLibsPath;
60
57
  }
61
58
  getExecutor() {
62
59
  return this.executionStack[this.executionStack.length - 1];
63
60
  }
61
+ getScope() {
62
+ return this.getExecutor().scope;
63
+ }
64
+ getRootExecutor() {
65
+ return this.executionStack[0];
66
+ }
64
67
  setupBuiltInFunctions(context) {
65
68
  linkBuiltInMethods(context, this);
66
69
  }
@@ -109,11 +112,21 @@ export class BaseVisitor extends CircuitScriptVisitor {
109
112
  log2(message) {
110
113
  this.getExecutor().log(message);
111
114
  }
112
- visitScript = (ctx) => {
115
+ async visitAsync(ctx) {
116
+ const result = await ctx.accept(this);
117
+ return result;
118
+ }
119
+ visitScript = async (ctx) => {
113
120
  this.log('===', 'start', '===');
114
- const result = this.visitChildren(ctx);
121
+ const imports = ctx.import_expr();
122
+ for (let i = 0; i < imports.length; i++) {
123
+ const ctxImport = imports[i];
124
+ const ID = ctxImport.ID().toString();
125
+ await this.handleImportFile(ID, true, ctxImport);
126
+ }
127
+ const result = this.runExpressions(this.getExecutor(), ctx.expression());
128
+ this.setResult(ctx, result);
115
129
  this.log('===', 'end', '===');
116
- return result;
117
130
  };
118
131
  visitAssignment_expr = (ctx) => {
119
132
  const reference = this.getReference(ctx.atom_expr());
@@ -385,10 +398,10 @@ export class BaseVisitor extends CircuitScriptVisitor {
385
398
  const tmpCtx = defaultValuesProvided[index - boundary];
386
399
  this.visit(tmpCtx);
387
400
  const defaultValue = this.getResult(tmpCtx);
388
- return [idText, defaultValue];
401
+ return [idText, tmpCtx.start, defaultValue];
389
402
  }
390
403
  else {
391
- return [idText];
404
+ return [idText, id.getSymbol()];
392
405
  }
393
406
  });
394
407
  this.setResult(ctx, result);
@@ -410,10 +423,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
410
423
  this.setResult(ctx, returnList);
411
424
  };
412
425
  visitImport_expr = (ctx) => {
413
- const ID = ctx.ID().toString();
414
- this.log('import', ID);
415
- this.handleImportFile(ID, true, ctx);
416
- this.log('done import', ID);
426
+ throw new RuntimeExecutionError("Cannot parse imports here", ctx.start, ctx.stop);
417
427
  };
418
428
  visitFunction_return_expr = (ctx) => {
419
429
  const executor = this.getExecutor();
@@ -463,15 +473,24 @@ export class BaseVisitor extends CircuitScriptVisitor {
463
473
  this.visit(ctx);
464
474
  return this.getResult(ctx);
465
475
  }
466
- handleImportFile(name, throwErrors = true, ctx = null) {
476
+ async handleImportFile(name, throwErrors = true, ctx = null) {
477
+ name = name.trim();
478
+ const importAlready = this.importedFiles.find(item => {
479
+ return item.id === name;
480
+ });
481
+ if (importAlready) {
482
+ return importAlready;
483
+ }
467
484
  let hasError = false;
468
485
  let hasParseError = false;
469
486
  let pathExists = false;
470
- const tmpFilePath = join(this.currentDirectory, name + ".cst");
487
+ const tmpFilePath = this.environment.getRelativeToModule(name + ".cst");
471
488
  this.log('importing path:', tmpFilePath);
472
489
  let fileData = null;
490
+ let filePathUsed = null;
473
491
  try {
474
- fileData = readFileSync(tmpFilePath, { encoding: 'utf8' });
492
+ filePathUsed = tmpFilePath;
493
+ fileData = await this.environment.readFile(tmpFilePath, { encoding: 'utf8' });
475
494
  pathExists = true;
476
495
  }
477
496
  catch (err) {
@@ -479,8 +498,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
479
498
  }
480
499
  if (!pathExists) {
481
500
  try {
482
- const tmpFilePath2 = join(this.defaultLibsPath, name + ".cst");
483
- fileData = readFileSync(tmpFilePath2, { encoding: 'utf8' });
501
+ const tmpFilePath2 = this.environment.getRelativeToDefaultLibs(name + ".cst");
502
+ filePathUsed = tmpFilePath2;
503
+ fileData = await this.environment.readFile(tmpFilePath2, { encoding: 'utf8' });
484
504
  pathExists = true;
485
505
  }
486
506
  catch (err) {
@@ -490,31 +510,39 @@ export class BaseVisitor extends CircuitScriptVisitor {
490
510
  try {
491
511
  if (pathExists) {
492
512
  this.log('done reading imported file data');
493
- const importResult = this.onImportFile(this, fileData, this.onErrorCallbackHandler);
513
+ const importResult = await this.onImportFile(this, filePathUsed, fileData, this.onErrorHandler);
494
514
  hasError = importResult.hasError;
495
515
  hasParseError = importResult.hasParseError;
496
516
  }
497
517
  }
498
518
  catch (err) {
499
- this.log('Failed to import file: ', err.message);
519
+ if (ctx != null) {
520
+ throw new RuntimeExecutionError("An error occurred while importing file", ctx.start, ctx.stop);
521
+ }
522
+ else {
523
+ this.log('An error occurred while importing file:', err.message);
524
+ }
500
525
  }
501
526
  let errorMessage = null;
502
527
  if (throwErrors && (hasError || hasParseError || !pathExists)) {
503
528
  if (!pathExists) {
504
- errorMessage = `File does not exist: ${name}`;
529
+ errorMessage = `File does not exist: ${name} (${filePathUsed})`;
505
530
  }
506
531
  else {
507
532
  errorMessage = `Failed to import: ${name}`;
508
533
  }
509
534
  }
510
535
  if (errorMessage !== null && ctx) {
511
- this.throwWithContext(ctx, errorMessage);
536
+ throw new RuntimeExecutionError(errorMessage, ctx.start, ctx.end);
512
537
  }
513
- return {
538
+ const newImportedFile = {
539
+ id: name.trim(),
514
540
  hasError,
515
541
  hasParseError,
516
542
  pathExists,
517
543
  };
544
+ this.importedFiles.push(newImportedFile);
545
+ return newImportedFile;
518
546
  }
519
547
  visitRoundedBracketsExpr = (ctx) => {
520
548
  const ctxDataExpr = ctx.data_expr();
@@ -544,9 +572,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
544
572
  executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
545
573
  }
546
574
  }
547
- else if (tmpFuncArg.length === 2) {
575
+ else if (tmpFuncArg.length === 3) {
548
576
  const variableName = tmpFuncArg[0];
549
- const defaultValue = tmpFuncArg[1];
577
+ const defaultValue = tmpFuncArg[2];
550
578
  executor.log('set variable in scope, var name: ', variableName);
551
579
  executor.scope.variables.set(variableName, defaultValue);
552
580
  }
@@ -617,7 +645,32 @@ export class BaseVisitor extends CircuitScriptVisitor {
617
645
  prepareStringValue(value) {
618
646
  return value.slice(1, value.length - 1);
619
647
  }
620
- throwWithContext(context, message) {
621
- throwWithContext(context, message);
648
+ throwWithContext(context, messageOrError) {
649
+ throwWithContext(context, messageOrError);
650
+ }
651
+ validateType(value, context, validateFunction, expectedType) {
652
+ if (value === undefined) {
653
+ return false;
654
+ }
655
+ const result = validateFunction(value);
656
+ if (!result) {
657
+ throw new RuntimeExecutionError(`Invalid ${expectedType}`, context.start, context.stop);
658
+ }
659
+ return result;
660
+ }
661
+ validateString(value, context) {
662
+ this.validateType(value, context, (val) => {
663
+ return typeof val === 'string';
664
+ }, 'string');
665
+ }
666
+ validateBoolean(value, context) {
667
+ this.validateType(value, context, (val) => {
668
+ return typeof val === 'boolean';
669
+ }, 'boolean');
670
+ }
671
+ validateNumeric(value, context) {
672
+ this.validateType(value, context, (val) => {
673
+ return (val instanceof NumericValue);
674
+ }, 'numeric value');
622
675
  }
623
676
  }
@@ -1,12 +1,14 @@
1
- import { Assignment_exprContext } from "./antlr/CircuitScriptParser";
2
- import { BaseVisitor } from "./BaseVisitor";
1
+ import { Assignment_exprContext } from "./antlr/CircuitScriptParser.js";
2
+ import { BaseVisitor } from "./BaseVisitor.js";
3
+ import { buildInMethodNamesList } from "./builtinMethods.js";
4
+ import { SymbolValidatorContext } from "./globals.js";
3
5
  export class SemanticTokensVisitor extends BaseVisitor {
4
6
  parsedTokens = [];
5
7
  lexer;
6
8
  script;
7
9
  semanticTokens = new Map();
8
- constructor(silent = false, onErrorHandler = null, currentDirectory, defaultsLibsPath, lexer, script) {
9
- super(silent, onErrorHandler, currentDirectory, defaultsLibsPath);
10
+ constructor(silent = false, onErrorHandler = null, environment, lexer, script) {
11
+ super(silent, onErrorHandler, environment);
10
12
  this.lexer = lexer;
11
13
  this.script = script;
12
14
  }
@@ -17,7 +19,11 @@ export class SemanticTokensVisitor extends BaseVisitor {
17
19
  });
18
20
  };
19
21
  visitFunction_call_expr = (ctx) => {
20
- this.addSemanticToken(ctx.ID(), [], 'function');
22
+ const modifiers = [];
23
+ if (buildInMethodNamesList.indexOf(ctx.ID().getText()) !== -1) {
24
+ modifiers.push('defaultLibrary');
25
+ }
26
+ this.addSemanticToken(ctx.ID(), modifiers, 'function');
21
27
  };
22
28
  visitFunction_def_expr = (ctx) => {
23
29
  const functionName = ctx.ID().getText();
@@ -26,7 +32,7 @@ export class SemanticTokensVisitor extends BaseVisitor {
26
32
  if (ctxFunctionArgsExpr) {
27
33
  this.visit(ctxFunctionArgsExpr);
28
34
  }
29
- const executionContextName = functionName + '_validate';
35
+ const executionContextName = functionName + SymbolValidatorContext;
30
36
  const newExecutor = this.enterNewChildContext(this.executionStack, this.getExecutor(), executionContextName, { netNamespace: "" }, [], []);
31
37
  this.runExpressions(newExecutor, ctx.function_expr());
32
38
  this.executionStack.pop();
@@ -39,9 +45,8 @@ export class SemanticTokensVisitor extends BaseVisitor {
39
45
  };
40
46
  visitCreate_graphic_expr = (ctx) => {
41
47
  this.addSemanticToken(ctx.Create(), ['defaultLibrary'], 'function');
42
- ctx.graphic_expr().forEach(graphic_expr => {
43
- this.visit(graphic_expr);
44
- });
48
+ const graphicsExpressionsCtx = ctx.graphic_expressions_block();
49
+ this.visitResult(graphicsExpressionsCtx);
45
50
  };
46
51
  visitProperty_key_expr = (ctx) => {
47
52
  let useValue = null;
@@ -61,7 +66,7 @@ export class SemanticTokensVisitor extends BaseVisitor {
61
66
  this.addSemanticToken(useValue, [], 'property');
62
67
  }
63
68
  };
64
- visitGraphic_expr = (ctx) => {
69
+ visitGraphicCommandExpr = (ctx) => {
65
70
  let useValue = null;
66
71
  const ctxId = ctx.ID();
67
72
  const ctxPin = ctx.Pin();
@@ -179,7 +184,7 @@ const languageKeywords = [
179
184
  'break', 'branch', 'create', 'component',
180
185
  'graphic', 'wire', 'pin', 'add', 'at', 'to',
181
186
  'point', 'join', 'parallel', 'return', 'def', 'import',
182
- 'true', 'false', 'nc', 'frame',
187
+ 'true', 'false', 'nc', 'sheet', 'frame', 'if', 'for',
183
188
  ];
184
189
  const operatorKeywords = [
185
190
  'at', 'to', 'wire', 'add', 'frame', 'join', 'parallel', 'point'
@@ -203,6 +208,7 @@ function resolveTokenType(tokenType) {
203
208
  case 'ID':
204
209
  return 'variable';
205
210
  case 'Define':
211
+ case 'BOOLEAN_VALUE':
206
212
  return 'keyword';
207
213
  case 'COMMENT':
208
214
  return 'comment';