circuitscript 0.3.2 → 0.4.1

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 (147) hide show
  1. package/dist/cjs/BaseVisitor.js +394 -262
  2. package/dist/cjs/LexerDiagnosticListener.js +375 -0
  3. package/dist/cjs/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
  4. package/dist/cjs/annotate/DefaultPostAnnotationCallback.js +126 -0
  5. package/dist/cjs/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
  6. package/dist/cjs/annotate/utils.js +70 -0
  7. package/dist/cjs/antlr/CircuitScriptLexer.js +279 -286
  8. package/dist/cjs/antlr/CircuitScriptParser.js +1954 -3535
  9. package/dist/cjs/antlr/CircuitScriptParserVisitor.js +7 -0
  10. package/dist/cjs/cache/deserializer.js +34 -0
  11. package/dist/cjs/cache/hash.js +8 -0
  12. package/dist/cjs/cache/serializer.js +122 -0
  13. package/dist/cjs/cache/storage.js +45 -0
  14. package/dist/cjs/cache/types.js +4 -0
  15. package/dist/cjs/{environment.js → environment/environment.js} +18 -6
  16. package/dist/cjs/environment/esm-environment.js +21 -0
  17. package/dist/cjs/environment/helpers.js +8 -0
  18. package/dist/cjs/execute.js +49 -15
  19. package/dist/cjs/globals.js +9 -1
  20. package/dist/cjs/helpers.js +3 -485
  21. package/dist/cjs/importResolver.js +102 -0
  22. package/dist/cjs/index.js +12 -7
  23. package/dist/cjs/lexer.js +48 -12
  24. package/dist/cjs/main.js +14 -4
  25. package/dist/cjs/objects/ClassComponent.js +1 -1
  26. package/dist/cjs/objects/ExecutionScope.js +0 -1
  27. package/dist/cjs/objects/types.js +17 -1
  28. package/dist/cjs/parser.js +18 -4
  29. package/dist/cjs/pipeline.js +284 -0
  30. package/dist/cjs/regenerate-tests.js +4 -3
  31. package/dist/cjs/render/KiCadNetListOutputHandler.js +30 -0
  32. package/dist/cjs/render/PaperSizes.js +46 -0
  33. package/dist/cjs/{draw_symbols.js → render/draw_symbols.js} +58 -36
  34. package/dist/cjs/{export.js → render/export.js} +2 -2
  35. package/dist/cjs/{geometry.js → render/geometry.js} +5 -5
  36. package/dist/cjs/{graph.js → render/graph.js} +7 -7
  37. package/dist/cjs/{layout.js → render/layout.js} +8 -8
  38. package/dist/cjs/{render.js → render/render.js} +9 -8
  39. package/dist/cjs/rules-check/no-connect-on-connected-pin.js +1 -1
  40. package/dist/cjs/rules-check/unconnected-pins.js +1 -1
  41. package/dist/cjs/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
  42. package/dist/cjs/semantic-tokens/getSemanticTokens.js +55 -0
  43. package/dist/cjs/sizing.js +2 -2
  44. package/dist/cjs/utils.js +2 -2
  45. package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +6 -0
  46. package/dist/cjs/validate/SymbolValidatorVisitor.js +34 -39
  47. package/dist/cjs/validate/validateScript.js +54 -0
  48. package/dist/cjs/validate.js +5 -4
  49. package/dist/cjs/visitor.js +140 -204
  50. package/dist/esm/BaseVisitor.js +396 -264
  51. package/dist/esm/LexerDiagnosticListener.js +371 -0
  52. package/dist/esm/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
  53. package/dist/esm/annotate/DefaultPostAnnotationCallback.js +122 -0
  54. package/dist/esm/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
  55. package/dist/esm/annotate/utils.js +66 -0
  56. package/dist/esm/antlr/CircuitScriptLexer.js +279 -286
  57. package/dist/esm/antlr/CircuitScriptParser.js +1962 -3522
  58. package/dist/esm/antlr/{CircuitScriptVisitor.js → CircuitScriptParserVisitor.js} +14 -35
  59. package/dist/esm/cache/deserializer.js +30 -0
  60. package/dist/esm/cache/hash.js +4 -0
  61. package/dist/esm/cache/serializer.js +118 -0
  62. package/dist/esm/cache/storage.js +39 -0
  63. package/dist/esm/cache/types.js +1 -0
  64. package/dist/esm/{environment.js → environment/environment.js} +18 -6
  65. package/dist/esm/environment/esm-environment.js +17 -0
  66. package/dist/esm/environment/helpers.js +4 -0
  67. package/dist/esm/execute.js +49 -15
  68. package/dist/esm/globals.js +8 -0
  69. package/dist/esm/helpers.js +5 -474
  70. package/dist/esm/importResolver.js +96 -0
  71. package/dist/esm/index.js +12 -7
  72. package/dist/esm/lexer.js +51 -12
  73. package/dist/esm/main.js +13 -3
  74. package/dist/esm/objects/ClassComponent.js +1 -1
  75. package/dist/esm/objects/ExecutionScope.js +0 -1
  76. package/dist/esm/objects/types.js +21 -1
  77. package/dist/esm/parser.js +19 -5
  78. package/dist/esm/pipeline.js +276 -0
  79. package/dist/esm/regenerate-tests.js +3 -2
  80. package/dist/esm/render/KiCadNetListOutputHandler.js +20 -0
  81. package/dist/esm/render/PaperSizes.js +41 -0
  82. package/dist/esm/{draw_symbols.js → render/draw_symbols.js} +58 -36
  83. package/dist/esm/{export.js → render/export.js} +2 -2
  84. package/dist/esm/{geometry.js → render/geometry.js} +5 -5
  85. package/dist/esm/{graph.js → render/graph.js} +7 -7
  86. package/dist/esm/{layout.js → render/layout.js} +8 -8
  87. package/dist/esm/{render.js → render/render.js} +8 -7
  88. package/dist/esm/rules-check/no-connect-on-connected-pin.js +1 -1
  89. package/dist/esm/rules-check/unconnected-pins.js +1 -1
  90. package/dist/esm/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
  91. package/dist/esm/semantic-tokens/getSemanticTokens.js +51 -0
  92. package/dist/esm/sizing.js +2 -2
  93. package/dist/esm/utils.js +2 -2
  94. package/dist/esm/validate/SymbolValidatorResolveVisitor.js +3 -0
  95. package/dist/esm/validate/SymbolValidatorVisitor.js +36 -41
  96. package/dist/esm/validate/validateScript.js +50 -0
  97. package/dist/esm/validate.js +4 -3
  98. package/dist/esm/visitor.js +142 -206
  99. package/dist/libs/std.cst +15 -19
  100. package/dist/types/BaseVisitor.d.ts +25 -18
  101. package/dist/types/BomGeneration.d.ts +1 -1
  102. package/dist/types/LexerDiagnosticListener.d.ts +85 -0
  103. package/dist/types/{ComponentAnnotater.d.ts → annotate/ComponentAnnotater.d.ts} +1 -1
  104. package/dist/types/annotate/DefaultPostAnnotationCallback.d.ts +7 -0
  105. package/dist/types/{RefdesAnnotationVisitor.d.ts → annotate/RefdesAnnotationVisitor.d.ts} +6 -8
  106. package/dist/types/annotate/utils.d.ts +6 -0
  107. package/dist/types/antlr/CircuitScriptLexer.d.ts +71 -70
  108. package/dist/types/antlr/CircuitScriptParser.d.ts +357 -515
  109. package/dist/types/antlr/{CircuitScriptVisitor.d.ts → CircuitScriptParserVisitor.d.ts} +27 -69
  110. package/dist/types/cache/deserializer.d.ts +5 -0
  111. package/dist/types/cache/hash.d.ts +1 -0
  112. package/dist/types/cache/serializer.d.ts +3 -0
  113. package/dist/types/cache/storage.d.ts +4 -0
  114. package/dist/types/cache/types.d.ts +20 -0
  115. package/dist/types/{environment.d.ts → environment/environment.d.ts} +5 -4
  116. package/dist/types/environment/esm-environment.d.ts +4 -0
  117. package/dist/types/environment/helpers.d.ts +2 -0
  118. package/dist/types/execute.d.ts +3 -2
  119. package/dist/types/globals.d.ts +1 -0
  120. package/dist/types/helpers.d.ts +31 -36
  121. package/dist/types/importResolver.d.ts +4 -0
  122. package/dist/types/index.d.ts +12 -7
  123. package/dist/types/lexer.d.ts +9 -5
  124. package/dist/types/objects/ClassComponent.d.ts +1 -1
  125. package/dist/types/objects/ExecutionScope.d.ts +1 -4
  126. package/dist/types/objects/types.d.ts +16 -2
  127. package/dist/types/parser.d.ts +9 -2
  128. package/dist/types/pipeline.d.ts +9 -0
  129. package/dist/types/render/KiCadNetListOutputHandler.d.ts +10 -0
  130. package/dist/types/render/PaperSizes.d.ts +12 -0
  131. package/dist/types/{draw_symbols.d.ts → render/draw_symbols.d.ts} +4 -4
  132. package/dist/types/{export.d.ts → render/export.d.ts} +1 -1
  133. package/dist/types/{geometry.d.ts → render/geometry.d.ts} +2 -2
  134. package/dist/types/{graph.d.ts → render/graph.d.ts} +6 -6
  135. package/dist/types/{layout.d.ts → render/layout.d.ts} +10 -10
  136. package/dist/types/{render.d.ts → render/render.d.ts} +1 -1
  137. package/dist/types/{SemanticTokenVisitor.d.ts → semantic-tokens/SemanticTokenVisitor.d.ts} +6 -6
  138. package/dist/types/semantic-tokens/getSemanticTokens.d.ts +6 -0
  139. package/dist/types/sizing.d.ts +1 -1
  140. package/dist/types/utils.d.ts +1 -1
  141. package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +3 -0
  142. package/dist/types/validate/SymbolValidatorVisitor.d.ts +8 -8
  143. package/dist/types/validate/validateScript.d.ts +3 -0
  144. package/dist/types/visitor.d.ts +8 -14
  145. package/libs/std.cst +15 -19
  146. package/package.json +3 -6
  147. package/dist/cjs/antlr/CircuitScriptVisitor.js +0 -7
package/dist/cjs/lexer.js CHANGED
@@ -4,28 +4,40 @@ exports.MainLexer = void 0;
4
4
  const antlr4ng_1 = require("antlr4ng");
5
5
  const CircuitScriptParser_js_1 = require("./antlr/CircuitScriptParser.js");
6
6
  const CircuitScriptLexer_js_1 = require("./antlr/CircuitScriptLexer.js");
7
+ const LexerDiagnosticListener_js_1 = require("./LexerDiagnosticListener.js");
7
8
  class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
8
- constructor(input) {
9
+ constructor(input, enableDiagnostics = false) {
9
10
  super(input);
10
11
  this.tokens = [];
12
+ this.tokensHead = 0;
11
13
  this.indents = [];
12
14
  this.opened = 0;
15
+ this.lineOffset = 0;
16
+ this.diagnosticCollector = new LexerDiagnosticListener_js_1.LexerDiagnosticCollector();
17
+ this.diagnosticCollector.setEnabled(enableDiagnostics);
13
18
  }
14
19
  reset() {
15
20
  this.tokens = [];
21
+ this.tokensHead = 0;
16
22
  this.indents = [];
17
23
  this.opened = 0;
18
24
  super.reset();
19
25
  }
20
26
  emitToken(token) {
27
+ this.diagnosticCollector.onTokenStart();
21
28
  super.emitToken(token);
22
29
  this.tokens.push(token);
30
+ this.diagnosticCollector.onTokenGenerated(token, this.tokens.length - this.tokensHead);
23
31
  }
24
32
  nextToken() {
25
33
  if (this.inputStream.LA(1) === CircuitScriptParser_js_1.CircuitScriptParser.EOF && this.indents.length) {
26
- this.tokens = this.tokens.filter(function (val) {
27
- return val.type !== CircuitScriptParser_js_1.CircuitScriptParser.EOF;
28
- });
34
+ let writeIdx = this.tokensHead;
35
+ for (let i = this.tokensHead; i < this.tokens.length; i++) {
36
+ if (this.tokens[i].type !== CircuitScriptParser_js_1.CircuitScriptParser.EOF) {
37
+ this.tokens[writeIdx++] = this.tokens[i];
38
+ }
39
+ }
40
+ this.tokens.length = writeIdx;
29
41
  const fillerNewLine = this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, "");
30
42
  this.emitToken(fillerNewLine);
31
43
  fillerNewLine.__skip = true;
@@ -36,7 +48,19 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
36
48
  this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.EOF, ""));
37
49
  }
38
50
  const next = super.nextToken();
39
- return this.tokens.length ? this.tokens.shift() : next;
51
+ let returnToken;
52
+ if (this.tokensHead < this.tokens.length) {
53
+ returnToken = this.tokens[this.tokensHead++];
54
+ if (this.tokensHead > 64) {
55
+ this.tokens = this.tokens.slice(this.tokensHead);
56
+ this.tokensHead = 0;
57
+ }
58
+ }
59
+ else {
60
+ returnToken = next;
61
+ }
62
+ returnToken.line += this.lineOffset;
63
+ return returnToken;
40
64
  }
41
65
  createDedent() {
42
66
  return this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.DEDENT, "");
@@ -80,9 +104,6 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
80
104
  }
81
105
  return count;
82
106
  }
83
- atStartOfInput() {
84
- return this.getCharIndex() === 0;
85
- }
86
107
  openBrace() {
87
108
  this.opened++;
88
109
  }
@@ -90,8 +111,19 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
90
111
  this.opened--;
91
112
  }
92
113
  onNewLine() {
93
- const newLine = this.text.replace(/[^\r\n]+/g, '');
94
- const spaces = this.text.replace(/[\r\n]+/g, '');
114
+ const text = this.text;
115
+ let nlLen = 0;
116
+ while (nlLen < text.length) {
117
+ const c = text.charCodeAt(nlLen);
118
+ if (c === 13 || c === 10 || c === 12) {
119
+ nlLen++;
120
+ }
121
+ else {
122
+ break;
123
+ }
124
+ }
125
+ const newLine = text.substring(0, nlLen);
126
+ const spaces = text.substring(nlLen);
95
127
  const next = this.inputStream.LA(1);
96
128
  const nextnext = this.inputStream.LA(2);
97
129
  if (this.opened > 0 || (nextnext != -1 &&
@@ -99,8 +131,9 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
99
131
  this.skip();
100
132
  }
101
133
  else {
102
- const start = this.getCharIndex() - this.text.length;
103
- const stop = this.getCharIndex() - 1;
134
+ const charIndex = this.getCharIndex();
135
+ const start = charIndex - this.text.length;
136
+ const stop = charIndex - 1;
104
137
  this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, newLine, start, start));
105
138
  const indent = this.getIndentationCount(spaces);
106
139
  const previous = this.indents.length ? this.indents[this.indents.length - 1] : 0;
@@ -119,5 +152,8 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
119
152
  }
120
153
  }
121
154
  }
155
+ setLineOffset(offset) {
156
+ this.lineOffset = offset;
157
+ }
122
158
  }
123
159
  exports.MainLexer = MainLexer;
package/dist/cjs/main.js CHANGED
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const commander_1 = require("commander");
8
8
  const figlet_1 = __importDefault(require("figlet"));
9
9
  const fs_1 = require("fs");
10
- const helpers_js_1 = require("./helpers.js");
11
- const environment_js_1 = require("./environment.js");
10
+ const pipeline_js_1 = require("./pipeline.js");
11
+ const environment_js_1 = require("./environment/environment.js");
12
12
  async function main() {
13
13
  const env = new environment_js_1.NodeScriptEnvironment();
14
14
  environment_js_1.NodeScriptEnvironment.setInstance(env);
@@ -27,7 +27,12 @@ async function main() {
27
27
  .option('-s, --stats', 'Show stats during generation')
28
28
  .option('-x, --skip-output', 'Skip output generation')
29
29
  .option('-e, --erc', 'Enable ERC output')
30
- .option('-b, --bom [output-path]', 'Generate Bill of Materials in csv format');
30
+ .option('-b, --bom [output-path]', 'Generate Bill of Materials in csv format')
31
+ .option('-l, --lexer-diagnostics', 'Enable lexer performance diagnostics')
32
+ .option('--lexer-verbose', 'Log each token as it is generated (requires -l)')
33
+ .option('--lexer-tokens [limit]', 'Print token stream (optionally limit number of tokens, requires -l)')
34
+ .option('--lexer-mapping [lines]', 'Print character-to-token mapping (optionally specify line range like "1-10", requires -l)')
35
+ .option('--lexer-summary', 'Print lexer operation summary (requires -l)');
31
36
  commander_1.program.addHelpText('before', figlet_1.default.textSync('circuitscript', {
32
37
  font: 'Small Slant'
33
38
  }));
@@ -92,6 +97,11 @@ async function main() {
92
97
  enableBom,
93
98
  bomOutputPath,
94
99
  environment: env,
100
+ lexerDiagnostics: options.lexerDiagnostics,
101
+ lexerVerbose: options.lexerVerbose,
102
+ lexerTokens: options.lexerTokens,
103
+ lexerMapping: options.lexerMapping,
104
+ lexerSummary: options.lexerSummary,
95
105
  inputPath: inputFilePath,
96
106
  updateSource,
97
107
  saveAnnotatedCopy: saveAnnotatedCopyPath,
@@ -119,7 +129,7 @@ async function main() {
119
129
  exports.default = main;
120
130
  async function parseFile(scriptData, outputPath, scriptOptions) {
121
131
  try {
122
- const { svgOutput: output, errors } = await (0, helpers_js_1.renderScript)(scriptData, outputPath, scriptOptions);
132
+ const { svgOutput: output, errors } = await (0, pipeline_js_1.renderScript)(scriptData, outputPath, scriptOptions);
123
133
  errors.forEach((err, index) => {
124
134
  console.log(`[${index}] ${err}`);
125
135
  });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModuleComponent = exports.ClassComponent = exports.ComponentUnit = void 0;
4
- const draw_symbols_js_1 = require("../draw_symbols.js");
4
+ const draw_symbols_js_1 = require("../render/draw_symbols.js");
5
5
  const PinDefinition_js_1 = require("./PinDefinition.js");
6
6
  const PinTypes_js_1 = require("./PinTypes.js");
7
7
  const globals_js_1 = require("../globals.js");
@@ -11,7 +11,6 @@ class ExecutionScope {
11
11
  this.functions = new Map();
12
12
  this.functionCounter = new Map();
13
13
  this.variables = new Map();
14
- this.symbols = new Map();
15
14
  this.libraries = new Map();
16
15
  this.blockStack = new Map();
17
16
  this.contextStack = [];
@@ -5,6 +5,8 @@ const globals_js_1 = require("../globals.js");
5
5
  const utils_js_1 = require("../utils.js");
6
6
  class CFunctionEntry {
7
7
  constructor(namespace, name, execute, source, uniqueId) {
8
+ this.lazyLoaded = false;
9
+ this.lazyLoader = null;
8
10
  this.name = name;
9
11
  this.namespace = namespace;
10
12
  this.originalNamespace = namespace;
@@ -15,6 +17,9 @@ class CFunctionEntry {
15
17
  toString() {
16
18
  return `[Function: ${this.name}]`;
17
19
  }
20
+ getFunctionPath() {
21
+ return `${this.namespace}${this.name}`;
22
+ }
18
23
  }
19
24
  exports.CFunctionEntry = CFunctionEntry;
20
25
  ;
@@ -117,9 +122,13 @@ var NetTypes;
117
122
  NetTypes["Source"] = "source";
118
123
  })(NetTypes || (exports.NetTypes = NetTypes = {}));
119
124
  class ImportedLibrary {
120
- constructor(libraryName, libraryNamespace, libraryFilePath, tree, tokens, context, flag, specifiedImports) {
125
+ constructor(libraryName, libraryNamespace, libraryFilePath, tree, tokens, context, flag, specifiedImports, fileHash, importStatement) {
121
126
  this.enableRefdesAnnotation = false;
122
127
  this.enableRefdesAnnotationFile = false;
128
+ this.referencedTokens = [];
129
+ this.writeToCache = false;
130
+ this.refdesAnnotations = new Map;
131
+ this.parseError = false;
123
132
  this.libraryName = libraryName;
124
133
  this.libraryNamespace = libraryNamespace;
125
134
  this.libraryFilePath = libraryFilePath;
@@ -128,6 +137,13 @@ class ImportedLibrary {
128
137
  this.context = context;
129
138
  this.importHandlingFlag = flag;
130
139
  this.specifiedImports = specifiedImports;
140
+ this.fileHash = fileHash;
141
+ this.importStatement = importStatement;
142
+ }
143
+ addRefdesModifications(mods) {
144
+ for (const [ctx, modification] of mods) {
145
+ this.refdesAnnotations.set(ctx, modification);
146
+ }
131
147
  }
132
148
  }
133
149
  exports.ImportedLibrary = ImportedLibrary;
@@ -5,27 +5,40 @@ const CircuitScriptParser_js_1 = require("./antlr/CircuitScriptParser.js");
5
5
  const lexer_js_1 = require("./lexer.js");
6
6
  const utils_js_1 = require("./utils.js");
7
7
  const antlr4ng_1 = require("antlr4ng");
8
- async function parseFileWithVisitor(visitor, data) {
8
+ function parseFileWithVisitor(visitor, data, options) {
9
9
  const lexerErrorListener = new CircuitscriptParserErrorListener(visitor.onErrorHandler);
10
10
  const parserErrorListener = new CircuitscriptParserErrorListener(visitor.onErrorHandler);
11
11
  const chars = antlr4ng_1.CharStream.fromString(data);
12
- const lexer = new lexer_js_1.MainLexer(chars);
12
+ const enableDiagnostics = options?.enableLexerDiagnostics ?? false;
13
+ const enableVerbose = options?.enableLexerVerbose ?? false;
14
+ const enableTokenStream = options?.enableLexerTokenStream ?? false;
15
+ const lineOffset = options?.lineOffset ?? 0;
16
+ const lexer = new lexer_js_1.MainLexer(chars, enableDiagnostics);
17
+ lexer.setLineOffset(lineOffset);
18
+ if (enableDiagnostics) {
19
+ lexer.diagnosticCollector.setSourceText(data);
20
+ lexer.diagnosticCollector.setVerboseLogging(enableVerbose);
21
+ if (enableTokenStream) {
22
+ lexer.diagnosticCollector.setRecordTokenStream(true);
23
+ }
24
+ }
13
25
  lexer.removeErrorListeners();
14
26
  lexer.addErrorListener(lexerErrorListener);
15
27
  const lexerTimer = new utils_js_1.SimpleStopwatch();
16
28
  const tokens = new antlr4ng_1.CommonTokenStream(lexer);
17
29
  tokens.fill();
18
30
  const lexerTimeTaken = lexerTimer.lap();
19
- const parserTimer = new utils_js_1.SimpleStopwatch();
20
31
  const parser = new CircuitScriptParser_js_1.CircuitScriptParser(tokens);
32
+ parser.interpreter.predictionMode = antlr4ng_1.PredictionMode.SLL;
21
33
  parser.removeErrorListeners();
22
34
  parser.addErrorListener(parserErrorListener);
35
+ const parserTimer = new utils_js_1.SimpleStopwatch();
23
36
  const tree = parser.script();
24
37
  let throwError;
25
38
  let hasError = false;
26
39
  let hasParseError = false;
27
40
  try {
28
- await visitor.visitAsync(tree);
41
+ visitor.visit(tree);
29
42
  }
30
43
  catch (error) {
31
44
  if (visitor.onErrorHandler) {
@@ -43,6 +56,7 @@ async function parseFileWithVisitor(visitor, data) {
43
56
  return {
44
57
  tree, parser,
45
58
  tokens,
59
+ lexer,
46
60
  hasParseError,
47
61
  hasError,
48
62
  parserTimeTaken,
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderScriptCustom = exports.renderScript = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const pdfkit_1 = __importDefault(require("pdfkit"));
9
+ const antlr4ng_1 = require("antlr4ng");
10
+ const DefaultPostAnnotationCallback_js_1 = require("./annotate/DefaultPostAnnotationCallback.js");
11
+ const BomGeneration_js_1 = require("./BomGeneration.js");
12
+ const globals_js_1 = require("./globals.js");
13
+ const graph_js_1 = require("./render/graph.js");
14
+ const layout_js_1 = require("./render/layout.js");
15
+ const logger_js_1 = require("./logger.js");
16
+ const Frame_js_1 = require("./objects/Frame.js");
17
+ const parser_js_1 = require("./parser.js");
18
+ const KiCadNetListOutputHandler_js_1 = require("./render/KiCadNetListOutputHandler.js");
19
+ const render_js_1 = require("./render/render.js");
20
+ const rules_js_1 = require("./rules-check/rules.js");
21
+ const utils_js_1 = require("./utils.js");
22
+ const visitor_js_1 = require("./visitor.js");
23
+ async function renderScript(scriptData, outputPath, options) {
24
+ const parseHandlers = [
25
+ new KiCadNetListOutputHandler_js_1.KiCadNetListOutputHandler(),
26
+ ];
27
+ return renderScriptCustom(scriptData, outputPath, options, parseHandlers, [DefaultPostAnnotationCallback_js_1.DefaultPostAnnotationCallback]);
28
+ }
29
+ exports.renderScript = renderScript;
30
+ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers, postAnnotationCallbacks) {
31
+ const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, lexerDiagnostics = false, lexerVerbose = false, lexerTokens = false, lexerMapping = false, lexerSummary = false, inputPath = '', bomOutputPath = undefined, environment } = options;
32
+ const errors = [];
33
+ const onErrorHandler = (message, context, error) => {
34
+ if (error && error instanceof utils_js_1.RuntimeExecutionError) {
35
+ errors.push(error);
36
+ }
37
+ else if (error && error instanceof antlr4ng_1.RecognitionException) {
38
+ if (context !== null) {
39
+ errors.push(new utils_js_1.ParseSyntaxError(message, context.start, context.stop));
40
+ }
41
+ else {
42
+ if (error.recognizer) {
43
+ const recognizer = error.recognizer;
44
+ errors.push(new utils_js_1.ParseSyntaxError(message, {
45
+ line: recognizer.currentTokenStartLine,
46
+ column: recognizer.currentTokenColumn
47
+ }));
48
+ }
49
+ else {
50
+ errors.push(new utils_js_1.ParseSyntaxError(message));
51
+ }
52
+ }
53
+ }
54
+ else {
55
+ errors.push(new utils_js_1.ParseError(message, context.start, context.stop));
56
+ }
57
+ };
58
+ const visitor = new visitor_js_1.ParserVisitor(true, onErrorHandler, environment);
59
+ environment.setCurrentFile(inputPath);
60
+ visitor.log(`current file: ${inputPath}`);
61
+ visitor.onImportFile = (visitor, filePath, fileData, errorHandler, fileLineOffset = 0) => {
62
+ visitor.enterFile(filePath);
63
+ errors.splice(0, errors.length);
64
+ const result = (0, parser_js_1.parseFileWithVisitor)(visitor, fileData, {
65
+ enableLexerDiagnostics: lexerDiagnostics,
66
+ enableLexerVerbose: lexerVerbose,
67
+ lineOffset: fileLineOffset,
68
+ });
69
+ const { throwError, tree, tokens } = result;
70
+ let { hasError, hasParseError } = result;
71
+ if (errors.length > 0) {
72
+ hasError = true;
73
+ hasParseError = true;
74
+ }
75
+ visitor.exitFile();
76
+ if (hasError || hasParseError) {
77
+ let importErrorMsg = "";
78
+ if (throwError) {
79
+ importErrorMsg = ": " + throwError.message;
80
+ }
81
+ throw new utils_js_1.ParseError(`Error parsing imported file: ${filePath}${importErrorMsg}`, undefined, undefined, filePath);
82
+ }
83
+ return { hasError, hasParseError, tree, tokens };
84
+ };
85
+ const dumpDirectory = environment.getRelativeToModule('/dump/');
86
+ if (dumpData) {
87
+ console.log('Dump data to:', dumpDirectory);
88
+ if (!environment.existsSync(dumpDirectory)) {
89
+ environment.mkdirSync(dumpDirectory);
90
+ }
91
+ }
92
+ if (inputPath !== '') {
93
+ visitor.enterFile(inputPath);
94
+ }
95
+ await visitor.resolveImportsAndLoad(inputPath, scriptData);
96
+ const { tree, parser, tokens, lexer, parserTimeTaken, lexerTimeTaken, throwError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData, {
97
+ enableLexerDiagnostics: lexerDiagnostics,
98
+ enableLexerVerbose: lexerVerbose,
99
+ enableLexerTokenStream: lexerTokens !== false || lexerMapping !== false,
100
+ });
101
+ (0, utils_js_1.printWarnings)(visitor.getWarnings());
102
+ showStats && console.log('Lexing took:', lexerTimeTaken);
103
+ showStats && console.log('Parsing took:', parserTimeTaken);
104
+ if (lexerDiagnostics && lexer.diagnosticCollector) {
105
+ console.log('\n');
106
+ if (lexerSummary) {
107
+ lexer.diagnosticCollector.printLexerOperationSummary();
108
+ }
109
+ if (lexerTokens !== false) {
110
+ const limit = typeof lexerTokens === 'number' ? lexerTokens : undefined;
111
+ lexer.diagnosticCollector.printTokenStream(limit);
112
+ }
113
+ if (lexerMapping !== false) {
114
+ if (typeof lexerMapping === 'string') {
115
+ const match = lexerMapping.match(/^(\d+)-(\d+)$/);
116
+ if (match) {
117
+ const startLine = parseInt(match[1], 10);
118
+ const endLine = parseInt(match[2], 10);
119
+ lexer.diagnosticCollector.printCharacterToTokenMapping(startLine, endLine);
120
+ }
121
+ else {
122
+ console.log('Invalid line range format. Use format like "1-10"');
123
+ }
124
+ }
125
+ else {
126
+ lexer.diagnosticCollector.printCharacterToTokenMapping();
127
+ }
128
+ }
129
+ lexer.diagnosticCollector.printReport();
130
+ const recommendations = lexer.diagnosticCollector.getRecommendations();
131
+ if (recommendations.length > 0) {
132
+ console.log('Performance Recommendations:');
133
+ recommendations.forEach((rec, idx) => {
134
+ console.log(` ${idx + 1}. ${rec}`);
135
+ });
136
+ console.log('');
137
+ }
138
+ }
139
+ try {
140
+ visitor.annotateComponents();
141
+ }
142
+ catch (err) {
143
+ throw new utils_js_1.RenderError(`Error during component annotation: ${err}`, 'annotation');
144
+ }
145
+ const componentLinks = visitor.getComponentCtxLinks();
146
+ const importedLibraries = Array.from(visitor.getScope().libraries.values());
147
+ for (let i = 0; i < postAnnotationCallbacks.length; i++) {
148
+ await postAnnotationCallbacks[i](options, scriptData, tree, tokens, componentLinks, importedLibraries, environment);
149
+ }
150
+ visitor.cacheLibraries();
151
+ if (dumpNets) {
152
+ const nets = visitor.dumpNets();
153
+ nets.forEach(item => console.log(item.join(" | ")));
154
+ }
155
+ dumpData && environment.writeFileSync(dumpDirectory + 'tree.lisp', tree.toStringTree(null, parser));
156
+ dumpData && environment.writeFileSync(dumpDirectory + 'raw-parser.txt', visitor.logger.dump());
157
+ if (throwError) {
158
+ errors.push(throwError);
159
+ }
160
+ let svgOutput = "";
161
+ if (errors.length === 0 && throwError === undefined) {
162
+ const { frameComponent } = visitor.applySheetFrameComponent();
163
+ const { sequence, nets } = visitor.getGraph();
164
+ if (enableBom && bomOutputPath) {
165
+ const documentVariable = visitor.getScope().variables.get('document');
166
+ const bomConfig = documentVariable.bom;
167
+ const bomData = (0, BomGeneration_js_1.generateBom)(bomConfig, visitor.getScope().getInstances());
168
+ const bomCsvOutput = (0, BomGeneration_js_1.generateBomCSV)(bomData);
169
+ await (0, BomGeneration_js_1.saveBomOutputCsv)(environment, bomCsvOutput, bomOutputPath);
170
+ console.log('Generated BOM file', bomOutputPath);
171
+ }
172
+ const tmpSequence = (0, utils_js_1.generateDebugSequenceAction)(sequence).map(item => (0, utils_js_1.sequenceActionString)(item));
173
+ dumpData && environment.writeFileSync(dumpDirectory + 'raw-sequence.txt', tmpSequence.join('\n'));
174
+ try {
175
+ let fileExtension = null;
176
+ let outputDefaultZoom = globals_js_1.defaultZoomScale;
177
+ if (outputPath) {
178
+ fileExtension = path_1.default.extname(outputPath).substring(1);
179
+ }
180
+ for (let i = 0; i < parseHandlers.length; i++) {
181
+ const handler = parseHandlers[i];
182
+ if (handler.beforeRender) {
183
+ const keepParsing = handler.parse(visitor, outputPath, fileExtension);
184
+ if (!keepParsing) {
185
+ return {
186
+ svgOutput: null,
187
+ errors
188
+ };
189
+ }
190
+ }
191
+ }
192
+ const logger = new logger_js_1.Logger();
193
+ const graphEngine = new graph_js_1.NetGraph(logger);
194
+ const layoutEngine = new layout_js_1.LayoutEngine(logger);
195
+ const layoutTimer = new utils_js_1.SimpleStopwatch();
196
+ let sheetFrames;
197
+ try {
198
+ const { graph, containerFrames } = graphEngine.generateLayoutGraph(sequence, nets);
199
+ sheetFrames = layoutEngine.runLayout(graph, containerFrames, nets);
200
+ if (enableErc) {
201
+ const ercResults = (0, rules_js_1.EvaluateERCRules)(visitor, graph, nets);
202
+ if (ercResults.length > 0) {
203
+ console.log(`ERC found ${ercResults.length} items:`);
204
+ ercResults.forEach((item, index) => {
205
+ console.log(`${(index + 1).toString().padStart(3)}. line ${item.start.line}, column ${item.start.column}: ${item.type} - ${item.message}`);
206
+ });
207
+ }
208
+ else {
209
+ console.log('No ERC issues found');
210
+ }
211
+ }
212
+ }
213
+ catch (err) {
214
+ throw new utils_js_1.RenderError(`Error during layout generation: ${err}`, 'layout');
215
+ }
216
+ layoutEngine.printWarnings();
217
+ showStats && console.log('Layout took:', layoutTimer.lap());
218
+ dumpData && environment.writeFileSync(dumpDirectory + 'raw-layout.txt', layoutEngine.logger.dump());
219
+ const generateSvgTimer = new utils_js_1.SimpleStopwatch();
220
+ const renderLogger = new logger_js_1.Logger();
221
+ let svgCanvas;
222
+ try {
223
+ svgCanvas = (0, render_js_1.renderSheetsToSVG)(sheetFrames, renderLogger);
224
+ }
225
+ catch (err) {
226
+ throw new utils_js_1.RenderError(`Error during SVG generation: ${err}`, 'svg_generation');
227
+ }
228
+ showStats && console.log('Render took:', generateSvgTimer.lap());
229
+ dumpData && environment.writeFileSync(dumpDirectory + 'raw-render.txt', renderLogger.dump());
230
+ try {
231
+ if (fileExtension === "pdf") {
232
+ outputDefaultZoom = 1;
233
+ }
234
+ svgOutput = (0, render_js_1.generateSvgOutput)(svgCanvas, outputDefaultZoom);
235
+ }
236
+ catch (err) {
237
+ throw new utils_js_1.RenderError(`Error generating SVG output: ${err}`, 'svg_output');
238
+ }
239
+ if (outputPath) {
240
+ if (fileExtension === 'svg') {
241
+ try {
242
+ environment.writeFileSync(outputPath, svgOutput);
243
+ }
244
+ catch (err) {
245
+ throw new utils_js_1.RenderError(`Error writing SVG file: ${err}`, 'file_output');
246
+ }
247
+ }
248
+ else if (fileExtension === 'pdf') {
249
+ let sheetSize = "A4";
250
+ let sheetSizeDefined = false;
251
+ if (frameComponent) {
252
+ sheetSize = frameComponent.getParam(Frame_js_1.FrameParamKeys.PaperSize);
253
+ sheetSizeDefined = true;
254
+ }
255
+ try {
256
+ const doc = new pdfkit_1.default({
257
+ layout: 'landscape',
258
+ size: sheetSize
259
+ });
260
+ const outputStream = environment.createWriteStream(outputPath);
261
+ (0, render_js_1.generatePdfOutput)(doc, svgCanvas, sheetSize, sheetSizeDefined, outputDefaultZoom);
262
+ doc.pipe(outputStream);
263
+ doc.end();
264
+ }
265
+ catch (err) {
266
+ throw new utils_js_1.RenderError(`Error generating PDF file: ${err}`, 'pdf_output');
267
+ }
268
+ }
269
+ else {
270
+ throw new utils_js_1.RenderError(`Invalid output format: ${fileExtension}`, 'file_output');
271
+ }
272
+ console.log('Generated file', outputPath);
273
+ }
274
+ }
275
+ catch (err) {
276
+ throw new utils_js_1.RenderError(`Error during rendering: ${err}`, 'output_generation');
277
+ }
278
+ }
279
+ return {
280
+ svgOutput,
281
+ errors
282
+ };
283
+ }
284
+ exports.renderScriptCustom = renderScriptCustom;
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const fs_1 = __importDefault(require("fs"));
7
- const helpers_js_1 = require("./helpers.js");
8
- const environment_js_1 = require("./environment.js");
7
+ const pipeline_js_1 = require("./pipeline.js");
8
+ const environment_js_1 = require("./environment/environment.js");
9
9
  const mainDir = './__tests__/testData/renderData/';
10
10
  const env = new environment_js_1.NodeScriptEnvironment();
11
11
  environment_js_1.NodeScriptEnvironment.setInstance(env);
@@ -25,7 +25,8 @@ async function regenerateTests(extra = "") {
25
25
  const outputPath = mainDir + 'svgs/' + file + extra + '.svg';
26
26
  env.setModuleDirectory(mainDir);
27
27
  env.setDefaultLibsPath(mainDir + '../../../libs/');
28
- await (0, helpers_js_1.renderScript)(scriptData, outputPath, {
28
+ await (0, pipeline_js_1.renderScript)(scriptData, outputPath, {
29
+ inputPath,
29
30
  dumpNets: false,
30
31
  dumpData: false,
31
32
  showStats: false,
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KiCadNetListOutputHandler = exports.ParseOutputHandler = void 0;
4
+ const export_js_1 = require("./export.js");
5
+ class ParseOutputHandler {
6
+ constructor() {
7
+ this.beforeRender = false;
8
+ this.afterRender = false;
9
+ }
10
+ }
11
+ exports.ParseOutputHandler = ParseOutputHandler;
12
+ class KiCadNetListOutputHandler extends ParseOutputHandler {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.beforeRender = true;
16
+ }
17
+ parse(visitor, outputPath, fileExtension) {
18
+ if (outputPath !== null && fileExtension === "net") {
19
+ const { tree: kiCadNetList, missingFootprints } = (0, export_js_1.generateKiCadNetList)(visitor.getNetList());
20
+ missingFootprints.forEach(entry => {
21
+ console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
22
+ });
23
+ visitor.environment.writeFileSync(outputPath, (0, export_js_1.printTree)(kiCadNetList));
24
+ console.log('Generated file', outputPath);
25
+ return false;
26
+ }
27
+ return true;
28
+ }
29
+ }
30
+ exports.KiCadNetListOutputHandler = KiCadNetListOutputHandler;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPaperSize = exports.isSupportedPaperSize = exports.PaperGridReferences = void 0;
4
+ const globals_js_1 = require("../globals.js");
5
+ const PaperSizes = {
6
+ 'A0': [1189, 841],
7
+ 'A1': [841, 594],
8
+ 'A2': [594, 420],
9
+ 'A3': [420, 297],
10
+ 'A4': [297, 210],
11
+ 'A5': [210, 148],
12
+ 'A6': [148, 105],
13
+ };
14
+ exports.PaperGridReferences = {
15
+ 'A0': [16, 24],
16
+ 'A1': [12, 16],
17
+ 'A2': [8, 12],
18
+ 'A3': [6, 8],
19
+ 'A4': [4, 6],
20
+ };
21
+ function isSupportedPaperSize(type) {
22
+ if (PaperSizes[type]) {
23
+ return true;
24
+ }
25
+ return false;
26
+ }
27
+ exports.isSupportedPaperSize = isSupportedPaperSize;
28
+ function getPaperSize(type, margin = globals_js_1.defaultPageMarginMM) {
29
+ if (PaperSizes[type]) {
30
+ const [width, height] = PaperSizes[type];
31
+ const useWidth = width - margin * 2;
32
+ const useHeight = height - margin * 2;
33
+ return {
34
+ width: Math.floor(useWidth * (1 / globals_js_1.MilsToMM)),
35
+ height: Math.floor(useHeight * (1 / globals_js_1.MilsToMM)),
36
+ widthMM: useWidth,
37
+ heightMM: useHeight,
38
+ originalWidthMM: width,
39
+ originalHeightMM: height,
40
+ };
41
+ }
42
+ else {
43
+ return getPaperSize('A4');
44
+ }
45
+ }
46
+ exports.getPaperSize = getPaperSize;