circuitscript 0.3.1 → 0.4.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 (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} +10 -84
  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 -467
  21. package/dist/cjs/importResolver.js +102 -0
  22. package/dist/cjs/index.js +7 -6
  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 +158 -212
  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} +10 -84
  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 -456
  70. package/dist/esm/importResolver.js +96 -0
  71. package/dist/esm/index.js +7 -6
  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 +160 -214
  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} +7 -9
  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 +7 -6
  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
@@ -1,19 +1,23 @@
1
1
  import { Big } from 'big.js';
2
- import { Import_specificContext } from "./antlr/CircuitScriptParser.js";
3
- import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor.js";
2
+ import { Import_specific_or_allContext } from "./antlr/CircuitScriptParser.js";
3
+ import { CircuitScriptParserVisitor } from "./antlr/CircuitScriptParserVisitor.js";
4
4
  import { ExecutionContext } from "./execute.js";
5
5
  import { Logger } from "./logger.js";
6
6
  import { ClassComponent } from "./objects/ClassComponent.js";
7
7
  import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition.js";
8
- import { PinTypes } from "./objects/PinTypes.js";
9
8
  import { Direction, AnyReference, UndeclaredReference, ImportedLibrary, ImportFunctionHandling as ImportFunctionHandling } from "./objects/types.js";
10
- import { BaseNamespace, ComponentTypes, DoubleDelimiter1, GlobalDocumentName, ReferenceTypes, TrailerArrayIndex } from './globals.js';
9
+ import { BaseNamespace, ComponentTypes, DoubleDelimiter1, GlobalDocumentName, PinTypesList, ReferenceTypes, TrailerArrayIndex } from './globals.js';
11
10
  import { isReference, unwrapValue as unwrapValue } from "./utils.js";
12
11
  import { linkBuiltInMethods } from './builtinMethods.js';
13
12
  import { resolveToNumericValue, RuntimeExecutionError, throwWithContext } from './utils.js';
14
13
  import { SequenceAction } from './objects/ExecutionScope.js';
15
14
  import { PinId } from './objects/PinDefinition.js';
16
- export class BaseVisitor extends CircuitScriptVisitor {
15
+ import { computeContentHash } from './cache/hash.js';
16
+ import { readCache, writeCache } from './cache/storage.js';
17
+ import { serializeLibraryScope } from './cache/serializer.js';
18
+ import { deserializeLibraryScope } from './cache/deserializer.js';
19
+ import { resolveAllImportFilepaths } from './importResolver.js';
20
+ export class BaseVisitor extends CircuitScriptParserVisitor {
17
21
  startingContext;
18
22
  executionStack;
19
23
  filePathStack = [];
@@ -26,18 +30,15 @@ export class BaseVisitor extends CircuitScriptVisitor {
26
30
  Direction.Right, Direction.Left];
27
31
  resultData = new Map;
28
32
  componentCtxLinks = new Map;
29
- pinTypesList = [
30
- PinTypes.Any,
31
- PinTypes.Input,
32
- PinTypes.Output,
33
- PinTypes.IO,
34
- PinTypes.Power,
35
- ];
36
33
  onErrorHandler = null;
37
34
  environment;
38
35
  importedFiles = [];
39
36
  warnings = [];
40
- onImportFile = async (visitor, filePath, fileData, onErrorHandler) => {
37
+ loadedFiles = new Map();
38
+ enableCacheImports = true;
39
+ enableCachedImportsRead = false || this.enableCacheImports;
40
+ enableCachedImportsWrite = false || this.enableCacheImports;
41
+ onImportFile = (visitor, filePath, fileData, onErrorHandler, fileLineOffset) => {
41
42
  throw "Import file not implemented";
42
43
  };
43
44
  refdesFileAnnotations = new Map();
@@ -121,15 +122,32 @@ export class BaseVisitor extends CircuitScriptVisitor {
121
122
  log2(message) {
122
123
  this.getExecutor().log(message);
123
124
  }
124
- async visitAsync(ctx) {
125
- const result = await ctx.accept(this);
126
- return result;
125
+ async resolveImportsAndLoad(inputPath, scriptData) {
126
+ this.log('resolve and load imports');
127
+ const importedFiles = await resolveAllImportFilepaths(inputPath, scriptData, this.environment);
128
+ this.log('resolved all referenced imports');
129
+ const loadedFiles = new Map();
130
+ for (const importFilePath of importedFiles) {
131
+ this.log(`reading file: ${importFilePath}`);
132
+ const importFileData = await this.environment.readFile(importFilePath);
133
+ loadedFiles.set(importFilePath, importFileData);
134
+ }
135
+ if (this.filePathStack.length > 0) {
136
+ const mainRefdesFile = this.getPathRefdesFile(this.filePathStack[0]);
137
+ const fileExists = await this.environment.exists(mainRefdesFile);
138
+ if (fileExists) {
139
+ this.log('.refdes.json file exists, reading it');
140
+ const mainRefdesFileData = await this.environment.readFile(mainRefdesFile);
141
+ loadedFiles.set(mainRefdesFile, mainRefdesFileData);
142
+ }
143
+ }
144
+ this.loadedFiles = loadedFiles;
127
145
  }
128
- visitScript = async (ctx) => {
146
+ visitScript = (ctx) => {
129
147
  this.log('===', 'start', '===');
130
148
  this.allowParseImports = true;
131
149
  for (const ctxImport of ctx.import_expr()) {
132
- await this.visit(ctxImport);
150
+ this.visit(ctxImport);
133
151
  }
134
152
  this.allowParseImports = false;
135
153
  const result = this.runExpressions(this.getExecutor(), ctx.expression());
@@ -137,17 +155,17 @@ export class BaseVisitor extends CircuitScriptVisitor {
137
155
  this.getExecutor().closeOpenPathBlocks();
138
156
  this.log('===', 'end', '===');
139
157
  };
140
- async importCommon(ctx, handling) {
158
+ importCommon(ctx, handling) {
141
159
  const specificImports = [];
142
- if (ctx instanceof Import_specificContext) {
160
+ if (ctx instanceof Import_specific_or_allContext) {
143
161
  const tmpSpecificImports = ctx._funcNames.map(item => {
144
162
  return item.text;
145
163
  });
146
164
  specificImports.push(...tmpSpecificImports);
147
165
  }
148
- const id = ctx._libraryName.text;
149
- const importedFile = await this.handleImportFile(id, handling, true, ctx, specificImports);
150
- const ctxImportAnnotation = ctx.import_annotation_expr();
166
+ const id = ctx._libraryName.text.slice(1, -1);
167
+ const importedFile = this.handleImportFile(id, handling, true, ctx, specificImports);
168
+ const ctxImportAnnotation = ctx.annotation_comment_expr();
151
169
  if (ctxImportAnnotation) {
152
170
  const textValue = ctxImportAnnotation.getText().replace('#=', '');
153
171
  const { importedLibrary } = importedFile;
@@ -159,148 +177,225 @@ export class BaseVisitor extends CircuitScriptVisitor {
159
177
  }
160
178
  }
161
179
  }
162
- visitImport_simple = async (ctx) => {
163
- await this.importCommon(ctx, ImportFunctionHandling.AllWithNamespace);
180
+ visitImport_simple = (ctx) => {
181
+ this.importCommon(ctx, ImportFunctionHandling.AllWithNamespace);
182
+ };
183
+ visitImport_specific_or_all = (ctx) => {
184
+ let importType = ImportFunctionHandling.SpecificMergeIntoNamespace;
185
+ if (ctx._all) {
186
+ importType = ImportFunctionHandling.AllMergeIntoNamespace;
187
+ }
188
+ this.importCommon(ctx, importType);
164
189
  };
165
- visitImport_all_simple = async (ctx) => {
166
- await this.importCommon(ctx, ImportFunctionHandling.AllMergeIntoNamespace);
190
+ visitCallableExpr = (ctx) => {
191
+ this.passResult(ctx, ctx.callable_expr());
167
192
  };
168
- visitImport_specific = async (ctx) => {
169
- await this.importCommon(ctx, ImportFunctionHandling.SpecificMergeIntoNamespace);
193
+ visitCallable_expr = (ctx) => {
194
+ const ctxParams = this.getResult(ctx);
195
+ const { keepReference = false } = ctxParams ?? {};
196
+ const executor = this.getExecutor();
197
+ let passedNetNamespace = null;
198
+ const netNameSpaceExpr = ctx.net_namespace_expr();
199
+ if (netNameSpaceExpr) {
200
+ passedNetNamespace = this.visitResult(netNameSpaceExpr);
201
+ }
202
+ const firstId = ctx.ID(0);
203
+ const atomId = firstId.getText();
204
+ let currentReference;
205
+ if (PinTypesList.indexOf(atomId) !== -1 && ctx.trailer().length === 0) {
206
+ currentReference = new AnyReference({
207
+ found: true,
208
+ value: atomId,
209
+ type: ReferenceTypes.pinType,
210
+ });
211
+ }
212
+ else {
213
+ this.log('resolve variable ctx: ' + ctx.getText(), 'atomId', atomId);
214
+ currentReference = executor.resolveVariable(this.executionStack, atomId);
215
+ this.log('reference:', currentReference.name, 'found:', currentReference.found);
216
+ }
217
+ if (currentReference !== undefined && currentReference.found) {
218
+ ctx.trailer().forEach(ctxTrailer => {
219
+ this.setResult(ctxTrailer, {
220
+ reference: currentReference,
221
+ netNamespace: passedNetNamespace
222
+ });
223
+ currentReference = this.visitResult(ctxTrailer);
224
+ });
225
+ }
226
+ let resultValue = currentReference;
227
+ if (!keepReference) {
228
+ if (currentReference.type !== ReferenceTypes.pinType) {
229
+ resultValue = unwrapValue(resultValue);
230
+ }
231
+ }
232
+ this.setResult(ctx, resultValue);
233
+ this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
234
+ };
235
+ visitTrailer = (ctx) => {
236
+ const { reference, netNamespace } = this.getResult(ctx);
237
+ const ctxLParam = ctx.LParen();
238
+ const ctxID = ctx.ID();
239
+ const ctxDataExpr = ctx.data_expr();
240
+ const useValue = reference.value;
241
+ let nextReference;
242
+ if (ctxID) {
243
+ reference.trailers.push(ctxID.getText());
244
+ const useRootValue = reference.rootValue ?? reference.value;
245
+ const useTrailerIndex = reference.trailerIndex ?? 0;
246
+ nextReference = this.getExecutor().resolveTrailers(reference.type, useRootValue, reference.trailers);
247
+ nextReference.name =
248
+ [reference.name,
249
+ ...reference.trailers.slice(useTrailerIndex)].join('.');
250
+ }
251
+ else if (ctxDataExpr) {
252
+ const arrayIndex = this.visitResult(ctxDataExpr);
253
+ if (arrayIndex instanceof NumericValue) {
254
+ const arrayIndexValue = arrayIndex.toNumber();
255
+ const foundValue = useValue[arrayIndexValue];
256
+ const refType = foundValue instanceof ClassComponent
257
+ ? ReferenceTypes.instance : ReferenceTypes.variable;
258
+ nextReference = new AnyReference({
259
+ found: true,
260
+ type: refType,
261
+ value: foundValue,
262
+ trailers: [[TrailerArrayIndex, arrayIndexValue]],
263
+ rootValue: useValue
264
+ });
265
+ }
266
+ }
267
+ else if (ctxLParam) {
268
+ nextReference = this.handleFunctionCall(reference, netNamespace, ctx);
269
+ }
270
+ this.setResult(ctx, nextReference);
170
271
  };
171
272
  visitAssignment_expr = (ctx) => {
172
- const ctxAtom = ctx.atom_expr();
173
- const ctxFuncCallRef = ctx.function_call_expr();
174
- let leftSideReference;
175
- let lhsCtx;
176
- if (ctxAtom) {
177
- leftSideReference = this.getReference(ctx.atom_expr());
178
- lhsCtx = ctxAtom;
179
- }
180
- else if (ctxFuncCallRef) {
181
- this.setResult(ctxFuncCallRef, { keepReference: true });
182
- leftSideReference = this.visitResult(ctxFuncCallRef);
183
- lhsCtx = ctxFuncCallRef;
184
- }
185
- const rhsCtx = ctx.data_expr();
186
- const rhsCtxResult = this.visitResult(rhsCtx);
187
- if (isReference(rhsCtxResult) && !rhsCtxResult.found) {
188
- this.throwWithContext(rhsCtx, rhsCtx.getText() + ' is not defined');
189
- }
190
- const rhsValue = unwrapValue(rhsCtxResult);
191
- const trailers = leftSideReference.trailers ?? [];
192
- const sequenceParts = [];
193
- if (trailers.length === 0) {
194
- this.getScope().setVariable(leftSideReference.name, rhsValue);
195
- let itemType = '';
196
- if (rhsValue instanceof ClassComponent) {
197
- itemType = ReferenceTypes.instance;
198
- this.log2(`assigned '${leftSideReference.name}' to ClassComponent`);
273
+ if (ctx.Assign()) {
274
+ const lhsCtx = ctx.callable_expr();
275
+ this.setResult(lhsCtx, { keepReference: true });
276
+ const leftSideReference = this.visitResult(lhsCtx);
277
+ const rhsCtx = ctx.data_expr();
278
+ const rhsCtxResult = this.visitResult(rhsCtx);
279
+ if (isReference(rhsCtxResult) && !rhsCtxResult.found) {
280
+ this.throwWithContext(rhsCtx, rhsCtx.getText() + ' is not defined');
199
281
  }
200
- else {
201
- itemType = ReferenceTypes.variable;
282
+ const rhsValue = unwrapValue(rhsCtxResult);
283
+ const { trailers = [] } = leftSideReference;
284
+ const sequenceParts = [];
285
+ if (trailers.length === 0) {
202
286
  this.getScope().setVariable(leftSideReference.name, rhsValue);
203
- this.log2(`assigned variable ${leftSideReference.name} to ${rhsValue}`);
287
+ let itemType = '';
288
+ if (rhsValue instanceof ClassComponent) {
289
+ itemType = ReferenceTypes.instance;
290
+ this.log2(`assigned '${leftSideReference.name}' to ClassComponent`);
291
+ }
292
+ else {
293
+ itemType = ReferenceTypes.variable;
294
+ this.getScope().setVariable(leftSideReference.name, rhsValue);
295
+ this.log2(`assigned variable ${leftSideReference.name} to ${rhsValue}`);
296
+ }
297
+ sequenceParts.push(...[itemType, leftSideReference.name, rhsValue]);
204
298
  }
205
- sequenceParts.push(...[itemType, leftSideReference.name, rhsValue]);
206
- }
207
- else {
208
- if (leftSideReference.rootValue instanceof ClassComponent) {
209
- this.setInstanceParam(leftSideReference.rootValue, trailers, rhsValue);
210
- this.log2(`assigned component param ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
211
- sequenceParts.push(...['instance', [leftSideReference.rootValue, trailers], rhsValue]);
212
- if (leftSideReference.rootValue.typeProp === ComponentTypes.net) {
213
- const net = this.getScope().getNet(leftSideReference.rootValue, new PinId(1));
214
- if (net) {
215
- const trailerValue = trailers.join(".");
216
- net.params.set(trailerValue, rhsValue);
299
+ else {
300
+ if (leftSideReference.rootValue instanceof ClassComponent) {
301
+ this.setInstanceParam(leftSideReference.rootValue, trailers, rhsValue);
302
+ this.log2(`assigned component param ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
303
+ sequenceParts.push(...['instance', [leftSideReference.rootValue, trailers], rhsValue]);
304
+ if (leftSideReference.rootValue.typeProp === ComponentTypes.net) {
305
+ const net = this.getScope().getNet(leftSideReference.rootValue, new PinId(1));
306
+ if (net) {
307
+ const trailerValue = trailers.join(".");
308
+ net.params.set(trailerValue, rhsValue);
309
+ }
217
310
  }
218
311
  }
219
- }
220
- else if (leftSideReference.rootValue instanceof Object) {
221
- if (Array.isArray(trailers[0]) && trailers[0][0] === TrailerArrayIndex) {
222
- if (Array.isArray(leftSideReference.rootValue)) {
223
- const arrayIndexValue = trailers[0][1];
224
- leftSideReference.rootValue[arrayIndexValue] = rhsValue;
225
- this.log2(`assigned array index ${leftSideReference.rootValue} index: ${arrayIndexValue} value: ${rhsValue}`);
312
+ else if (leftSideReference.rootValue instanceof Object) {
313
+ if (Array.isArray(trailers[0]) && trailers[0][0] === TrailerArrayIndex) {
314
+ if (Array.isArray(leftSideReference.rootValue)) {
315
+ const arrayIndexValue = trailers[0][1];
316
+ leftSideReference.rootValue[arrayIndexValue] = rhsValue;
317
+ this.log2(`assigned array index ${leftSideReference.rootValue} index: ${arrayIndexValue} value: ${rhsValue}`);
318
+ }
319
+ else {
320
+ this.throwWithContext(lhsCtx, "Invalid array");
321
+ }
226
322
  }
227
323
  else {
228
- this.throwWithContext(lhsCtx, "Invalid array");
324
+ let expandedValue = leftSideReference.rootValue;
325
+ trailers.slice(0, -1).forEach(trailer => {
326
+ expandedValue = expandedValue[trailer];
327
+ });
328
+ const lastTrailer = trailers.slice(-1)[0];
329
+ expandedValue[lastTrailer] = rhsValue;
330
+ this.log2(`assigned object ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
229
331
  }
332
+ sequenceParts.push(...['variable', [leftSideReference.rootValue, trailers], rhsValue]);
230
333
  }
231
- else {
232
- let expandedValue = leftSideReference.rootValue;
233
- trailers.slice(0, -1).forEach(trailer => {
234
- expandedValue = expandedValue[trailer];
235
- });
236
- const lastTrailer = trailers.slice(-1)[0];
237
- expandedValue[lastTrailer] = rhsValue;
238
- this.log2(`assigned object ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
239
- }
240
- sequenceParts.push(...['variable', [leftSideReference.rootValue, trailers], rhsValue]);
241
334
  }
242
- }
243
- if (sequenceParts.length > 0) {
244
- this.getScope().sequence.push([
245
- SequenceAction.Assign, ...sequenceParts
246
- ]);
247
- }
248
- this.setResult(ctx, rhsValue);
249
- };
250
- visitOperator_assignment_expr = (ctx) => {
251
- const reference = this.getReference(ctx.atom_expr());
252
- const value = this.visitResult(ctx.data_expr());
253
- if (!reference.found) {
254
- this.throwWithContext(ctx, 'Undefined reference: ' + reference.name);
255
- }
256
- const trailers = reference.trailers ?? [];
257
- let currentValue = null;
258
- if (trailers.length === 0) {
259
- currentValue = this.getExecutor().scope.variables.get(reference.name);
335
+ if (sequenceParts.length > 0) {
336
+ this.getScope().sequence.push([
337
+ SequenceAction.Assign, ...sequenceParts
338
+ ]);
339
+ }
340
+ this.setResult(ctx, rhsValue);
260
341
  }
261
342
  else {
262
- if (reference.value instanceof ClassComponent) {
263
- currentValue = this.getInstanceParam(reference.value, trailers);
343
+ const ctxCallable = ctx.callable_expr();
344
+ this.setResult(ctxCallable, { keepReference: true });
345
+ const reference = this.visitResult(ctx.callable_expr());
346
+ const value = this.visitResult(ctx.data_expr());
347
+ if (!reference.found) {
348
+ this.throwWithContext(ctx, 'Undefined reference: ' + reference.name);
264
349
  }
265
- else if (reference.value instanceof Object) {
266
- currentValue = reference.value[trailers.join('.')];
350
+ const trailers = reference.trailers ?? [];
351
+ let currentValue = null;
352
+ if (trailers.length === 0) {
353
+ currentValue = this.getExecutor().scope.variables.get(reference.name);
267
354
  }
268
- }
269
- if (currentValue === null) {
270
- this.throwWithContext(ctx, 'Operator assignment failed: could not get value');
271
- }
272
- let newValue = 0;
273
- const operator = new NumberOperator();
274
- if (ctx.AdditionAssign()) {
275
- newValue = operator.addition(currentValue, value);
276
- }
277
- else if (ctx.MinusAssign()) {
278
- newValue = operator.subtraction(currentValue, value);
279
- }
280
- else if (ctx.MultiplyAssign()) {
281
- newValue = operator.multiply(currentValue, value);
282
- }
283
- else if (ctx.DivideAssign()) {
284
- newValue = operator.divide(currentValue, value);
285
- }
286
- else if (ctx.ModulusAssign()) {
287
- newValue = operator.modulus(currentValue, value);
288
- }
289
- else {
290
- this.throwWithContext(ctx, 'Operator assignment failed: could not perform operator');
291
- }
292
- if (trailers.length === 0) {
293
- this.getExecutor().scope.setVariable(reference.name, newValue);
294
- }
295
- else {
296
- if (reference.value instanceof ClassComponent) {
297
- this.setInstanceParam(reference.value, trailers, newValue);
355
+ else {
356
+ if (reference.value instanceof ClassComponent) {
357
+ currentValue = this.getInstanceParam(reference.value, trailers);
358
+ }
359
+ else if (reference.value instanceof Object) {
360
+ currentValue = reference.value[trailers.join('.')];
361
+ }
362
+ }
363
+ if (currentValue === null) {
364
+ this.throwWithContext(ctx, 'Operator assignment failed: could not get value');
298
365
  }
299
- else if (reference.value instanceof Object) {
300
- reference.value[trailers.join('.')] = newValue;
366
+ let newValue = 0;
367
+ const operator = new NumberOperator();
368
+ if (ctx.AdditionAssign()) {
369
+ newValue = operator.addition(currentValue, value);
301
370
  }
371
+ else if (ctx.MinusAssign()) {
372
+ newValue = operator.subtraction(currentValue, value);
373
+ }
374
+ else if (ctx.MultiplyAssign()) {
375
+ newValue = operator.multiply(currentValue, value);
376
+ }
377
+ else if (ctx.DivideAssign()) {
378
+ newValue = operator.divide(currentValue, value);
379
+ }
380
+ else if (ctx.ModulusAssign()) {
381
+ newValue = operator.modulus(currentValue, value);
382
+ }
383
+ else {
384
+ this.throwWithContext(ctx, 'Operator assignment failed: could not perform operator');
385
+ }
386
+ if (trailers.length === 0) {
387
+ this.getExecutor().scope.setVariable(reference.name, newValue);
388
+ }
389
+ else {
390
+ if (reference.value instanceof ClassComponent) {
391
+ this.setInstanceParam(reference.value, trailers, newValue);
392
+ }
393
+ else if (reference.value instanceof Object) {
394
+ reference.value[trailers.join('.')] = newValue;
395
+ }
396
+ }
397
+ this.setResult(ctx, newValue);
302
398
  }
303
- this.setResult(ctx, newValue);
304
399
  };
305
400
  getReference(ctx) {
306
401
  const atomStr = ctx.getText();
@@ -354,7 +449,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
354
449
  const firstId = ctx.ID(0);
355
450
  const atomId = firstId.getText();
356
451
  let currentReference;
357
- if (this.pinTypesList.indexOf(atomId) !== -1) {
452
+ if (PinTypesList.indexOf(atomId) !== -1) {
358
453
  currentReference = new AnyReference({
359
454
  found: true,
360
455
  value: atomId,
@@ -375,93 +470,52 @@ export class BaseVisitor extends CircuitScriptVisitor {
375
470
  this.setResult(ctx, currentReference);
376
471
  this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
377
472
  };
378
- visitFunctionCallExpr = (ctx) => {
379
- const result = this.visitResult(ctx.function_call_expr());
380
- this.setResult(ctx, result);
381
- };
382
- visitFunction_call_expr = (ctx) => {
383
- const ctxParams = this.getResult(ctx);
384
- const { keepReference = false } = ctxParams ?? {};
385
- this.handleFunctionCall(ctx);
386
- if (!keepReference) {
387
- const functionResultReference = this.getResult(ctx);
388
- this.setResult(ctx, functionResultReference.value);
389
- }
390
- };
391
- handleFunctionCall(ctx) {
473
+ handleFunctionCall(currentReference, passedNetNamespace, ctx) {
392
474
  const executor = this.getExecutor();
393
- const atomId = ctx.ID().getText();
394
- let passedNetNamespace = null;
395
- const netNameSpaceExpr = ctx.net_namespace_expr();
396
- if (netNameSpaceExpr) {
397
- passedNetNamespace = this.visitResult(netNameSpaceExpr);
475
+ let parameters = [];
476
+ const ctxParameters = ctx.parameters();
477
+ if (ctxParameters) {
478
+ parameters = this.visitResult(ctxParameters);
398
479
  }
399
- let currentReference = executor.resolveVariable(this.executionStack, atomId);
400
- if (ctx.trailer_expr().length > 0) {
401
- if (!currentReference.found) {
402
- this.log(`could not resolve function: ${atomId}`);
403
- this.throwWithContext(ctx, "could not resolve function: " + atomId);
404
- }
405
- currentReference.trailers = [];
406
- ctx.trailer_expr().forEach(item => {
407
- if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
408
- if (currentReference.type === ReferenceTypes.variable) {
409
- if (currentReference.value instanceof AnyReference && currentReference.value.type === ReferenceTypes.function) {
410
- currentReference = currentReference.value;
411
- }
412
- }
413
- let parameters = [];
414
- const ctxParameters = item.parameters();
415
- if (ctxParameters) {
416
- parameters = this.visitResult(ctxParameters);
417
- }
418
- const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
419
- try {
420
- const isLibraryFunction = currentReference.rootValue
421
- && currentReference.rootValue instanceof ImportedLibrary;
422
- if (isLibraryFunction) {
423
- this.log('create new library context');
424
- const importedLibrary = currentReference.rootValue;
425
- const { context: importedLibraryContext } = importedLibrary;
426
- this.enterFile(importedLibrary.libraryFilePath);
427
- const newExecutor = this.handleEnterContext(this.getExecutor(), this.executionStack, importedLibraryContext.name, ctx, {
428
- netNamespace: executor.netNamespace,
429
- namespace: importedLibrary.libraryNamespace
430
- }, [], [], false);
431
- this.log('copy library context scope');
432
- importedLibraryContext.scope.copyTo(newExecutor.scope);
433
- }
434
- const [, functionResult] = executor.callFunction(currentReference, parameters, this.executionStack, useNetNamespace);
435
- if (isLibraryFunction) {
436
- this.log('pop library context scope');
437
- this.handlePopContext(this.getExecutor(), this.executionStack, "", false);
438
- this.exitFile();
439
- }
440
- if (isReference(functionResult)) {
441
- currentReference = functionResult;
442
- }
443
- else {
444
- currentReference = new AnyReference({
445
- found: true,
446
- value: functionResult,
447
- trailers: [],
448
- type: (functionResult instanceof ClassComponent) ?
449
- ReferenceTypes.instance : ReferenceTypes.value,
450
- });
451
- }
452
- }
453
- catch (err) {
454
- this.throwWithContext(ctx, err);
455
- }
456
- }
457
- else {
458
- const ctxTrailer = item.trailer_expr2();
459
- this.setResult(ctxTrailer, currentReference);
460
- currentReference = this.visitResult(ctxTrailer);
461
- }
462
- });
480
+ const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
481
+ try {
482
+ const isLibraryFunction = currentReference.rootValue
483
+ && currentReference.rootValue instanceof ImportedLibrary;
484
+ if (isLibraryFunction) {
485
+ this.log('create new library context');
486
+ const importedLibrary = currentReference.rootValue;
487
+ const { context: importedLibraryContext } = importedLibrary;
488
+ this.enterFile(importedLibrary.libraryFilePath);
489
+ const newExecutor = this.handleEnterContext(this.getExecutor(), this.executionStack, importedLibraryContext.name, ctx, {
490
+ netNamespace: executor.netNamespace,
491
+ namespace: importedLibrary.libraryNamespace
492
+ }, [], [], false);
493
+ this.log('copy library context scope');
494
+ importedLibraryContext.scope.copyTo(newExecutor.scope);
495
+ }
496
+ const [, functionResult] = executor.callFunction(currentReference, parameters, this.executionStack, useNetNamespace);
497
+ if (isLibraryFunction) {
498
+ this.log('pop library context scope');
499
+ this.handlePopContext(this.getExecutor(), this.executionStack, "", false);
500
+ this.exitFile();
501
+ }
502
+ if (isReference(functionResult)) {
503
+ currentReference = functionResult;
504
+ }
505
+ else {
506
+ currentReference = new AnyReference({
507
+ found: true,
508
+ value: functionResult,
509
+ trailers: [],
510
+ type: (functionResult instanceof ClassComponent) ?
511
+ ReferenceTypes.instance : ReferenceTypes.value,
512
+ });
513
+ }
463
514
  }
464
- this.setResult(ctx, currentReference);
515
+ catch (err) {
516
+ this.throwWithContext(ctx, err);
517
+ }
518
+ return currentReference;
465
519
  }
466
520
  handleEnterContext(executor, executionStack, contextName, ctx, options, funcDefinedParameters, passedInParameters, isBreakContext = true) {
467
521
  if (isBreakContext) {
@@ -554,30 +608,26 @@ export class BaseVisitor extends CircuitScriptVisitor {
554
608
  }
555
609
  this.setResult(ctx, result);
556
610
  };
557
- visitValueAtomExpr = (ctx) => {
611
+ visitValueExpr = (ctx) => {
612
+ this.passResult(ctx, ctx.value_expr());
613
+ };
614
+ visitAtomExpr = (ctx) => {
558
615
  let value = null;
559
- const ctxValueExpr = ctx.value_expr();
560
- const ctxAtomExpr = ctx.atom_expr();
561
- if (ctxValueExpr) {
562
- value = this.visitResult(ctxValueExpr);
616
+ const reference = this.visitResult(ctx.atom_expr());
617
+ if (!reference.found) {
618
+ value = new UndeclaredReference(reference);
563
619
  }
564
- else if (ctxAtomExpr) {
565
- const reference = this.visitResult(ctxAtomExpr);
566
- if (!reference.found) {
567
- value = new UndeclaredReference(reference);
620
+ else {
621
+ if (reference.type && reference.type === ReferenceTypes.pinType) {
622
+ value = reference;
568
623
  }
569
624
  else {
570
- if (reference.type && reference.type === ReferenceTypes.pinType) {
625
+ if ((reference.trailers && reference.trailers.length > 0)
626
+ || reference.type === ReferenceTypes.function) {
571
627
  value = reference;
572
628
  }
573
629
  else {
574
- if ((reference.trailers && reference.trailers.length > 0)
575
- || reference.type === ReferenceTypes.function) {
576
- value = reference;
577
- }
578
- else {
579
- value = reference.value;
580
- }
630
+ value = reference.value;
581
631
  }
582
632
  }
583
633
  }
@@ -601,6 +651,11 @@ export class BaseVisitor extends CircuitScriptVisitor {
601
651
  });
602
652
  this.setResult(ctx, result);
603
653
  };
654
+ visitKeyword_assignment_expr = (ctx) => {
655
+ const id = ctx.ID().getText();
656
+ const value = this.visitResult(ctx.data_expr());
657
+ this.setResult(ctx, [id, value]);
658
+ };
604
659
  visitParameters = (ctx) => {
605
660
  const dataExpressions = ctx.data_expr();
606
661
  const keywordAssignmentExpressions = ctx.keyword_assignment_expr();
@@ -653,7 +708,10 @@ export class BaseVisitor extends CircuitScriptVisitor {
653
708
  this.setResult(ctx, array);
654
709
  };
655
710
  visitArrayExpr = (ctx) => {
656
- this.setResult(ctx, this.visitResult(ctx.array_expr()));
711
+ const array = ctx.data_expr().map(item => {
712
+ return this.visitResult(item);
713
+ });
714
+ this.setResult(ctx, array);
657
715
  };
658
716
  visitArrayIndexExpr = (ctx) => {
659
717
  const ctxArray = ctx.data_expr(0);
@@ -706,11 +764,27 @@ export class BaseVisitor extends CircuitScriptVisitor {
706
764
  this.visit(ctx);
707
765
  return this.getResult(ctx);
708
766
  }
709
- async handleImportFile(name, importHandling, throwErrors = true, ctx = null, specificImports = []) {
767
+ passResult(ctx, innerCtx) {
768
+ const params = this.getResult(ctx);
769
+ if (params) {
770
+ this.setResult(innerCtx, params);
771
+ }
772
+ this.setResult(ctx, this.visitResult(innerCtx));
773
+ }
774
+ handleImportFile(name, importHandling, throwErrors = true, ctx = null, specificImports = []) {
710
775
  name = name.trim();
711
776
  const importAlready = this.importedFiles.find(item => {
712
777
  return item.id === name;
713
778
  });
779
+ let importStatement;
780
+ if (ctx !== null) {
781
+ const start = ctx.start;
782
+ const inputStream = start.inputStream;
783
+ importStatement = [
784
+ start.line, start.column,
785
+ inputStream.getTextFromRange(start.start, ctx.stop.stop)
786
+ ];
787
+ }
714
788
  if (importAlready) {
715
789
  const { importedLibrary: tmpImportedLibrary } = importAlready;
716
790
  const alreadyImportedFlag = tmpImportedLibrary.importHandlingFlag;
@@ -739,14 +813,17 @@ export class BaseVisitor extends CircuitScriptVisitor {
739
813
  let hasError = false;
740
814
  let hasParseError = false;
741
815
  let pathExists = false;
742
- const tmpFilePath = this.environment.getRelativeToCurrentFolder(name + ".cst");
816
+ const tmpFilePath = this.environment.getAbsPathRelativeToCurrentFolder(name + ".cst");
817
+ const relativeFilePath = this.environment.relative(this.environment.getCurrentDirectory(), tmpFilePath);
743
818
  this.log('importing path:', tmpFilePath);
744
819
  let fileData = null;
745
820
  let filePathUsed = null;
746
821
  try {
747
- filePathUsed = tmpFilePath;
748
- fileData = await this.environment.readFile(tmpFilePath, { encoding: 'utf8' });
749
- pathExists = true;
822
+ filePathUsed = relativeFilePath;
823
+ if (this.loadedFiles.has(relativeFilePath)) {
824
+ fileData = this.loadedFiles.get(relativeFilePath);
825
+ pathExists = true;
826
+ }
750
827
  }
751
828
  catch (err) {
752
829
  this.log('failed to read file');
@@ -758,8 +835,10 @@ export class BaseVisitor extends CircuitScriptVisitor {
758
835
  const tmpFilePath2 = this.environment.getRelativeToDefaultLibs(name + ".cst");
759
836
  this.log('checking default libs: ' + tmpFilePath2);
760
837
  filePathUsed = tmpFilePath2;
761
- fileData = await this.environment.readFile(tmpFilePath2, { encoding: 'utf8' });
762
- pathExists = true;
838
+ if (this.loadedFiles.has(tmpFilePath2)) {
839
+ fileData = this.loadedFiles.get(tmpFilePath2);
840
+ pathExists = true;
841
+ }
763
842
  }
764
843
  catch (err) {
765
844
  this.log('failed to read file');
@@ -774,16 +853,46 @@ export class BaseVisitor extends CircuitScriptVisitor {
774
853
  const executionContextName = name;
775
854
  const netNamespace = executor.netNamespace;
776
855
  const libraryNamespace = `${BaseNamespace}${name}.`;
777
- this.enterNewChildContext(executionStack, executor, executionContextName, {
856
+ const importContext = this.enterNewChildContext(executionStack, executor, executionContextName, {
778
857
  netNamespace,
779
858
  namespace: libraryNamespace,
780
859
  }, [], []);
781
- const importResult = await this.onImportFile(this, filePathUsed, fileData, this.onErrorHandler);
782
- hasError = importResult.hasError;
783
- hasParseError = importResult.hasParseError;
784
- const importContext = executionStack.pop();
785
- this.log(`import handling flag: ${importHandling}`);
786
- importedLibrary = new ImportedLibrary(name, libraryNamespace, filePathUsed, importResult.tree, importResult.tokens, importContext, importHandling, specificImports);
860
+ let loadedFromCache = false;
861
+ let contentHash = '';
862
+ if (this.enableCachedImportsRead) {
863
+ try {
864
+ contentHash = computeContentHash(fileData);
865
+ const cachedIR = readCache(filePathUsed, contentHash);
866
+ if (cachedIR !== null) {
867
+ this.log('cache hit for:', filePathUsed);
868
+ const parseAndVisit = (miniScript, lineOffset) => {
869
+ return this.onImportFile(this, filePathUsed, miniScript, this.onErrorHandler, lineOffset);
870
+ };
871
+ importedLibrary = deserializeLibraryScope(cachedIR, name, libraryNamespace, filePathUsed, importHandling, specificImports, importContext, parseAndVisit, () => {
872
+ executionStack.push(importContext);
873
+ return importContext;
874
+ }, () => {
875
+ executionStack.pop();
876
+ }, contentHash);
877
+ loadedFromCache = true;
878
+ this.log('Done reading from import cache');
879
+ }
880
+ }
881
+ catch (err) {
882
+ this.log('Error while reading cache: ', err);
883
+ loadedFromCache = false;
884
+ }
885
+ }
886
+ if (!loadedFromCache) {
887
+ const importResult = this.onImportFile(this, filePathUsed, fileData, this.onErrorHandler);
888
+ hasError = importResult.hasError;
889
+ hasParseError = importResult.hasParseError;
890
+ this.log(`import handling flag: ${importHandling}`);
891
+ importedLibrary = new ImportedLibrary(name, libraryNamespace, filePathUsed, importResult.tree, importResult.tokens, importContext, importHandling, specificImports, contentHash, importStatement);
892
+ importedLibrary.parseError = hasError || hasParseError;
893
+ importedLibrary.writeToCache = true;
894
+ }
895
+ executionStack.pop();
787
896
  if (specificImports.length > 0) {
788
897
  this.log('specific import: ' + specificImports.join(', '));
789
898
  }
@@ -792,7 +901,8 @@ export class BaseVisitor extends CircuitScriptVisitor {
792
901
  importedLibrary.context.scope.libraries.forEach((lib, key) => {
793
902
  scope.libraries.set(key, lib);
794
903
  });
795
- await this.checkLibraryHasRefdesFile(filePathUsed);
904
+ executor.mergeScope(importedLibrary.context.scope, importedLibrary.libraryNamespace);
905
+ this.checkLibraryInRefdesFile(filePathUsed);
796
906
  }
797
907
  }
798
908
  catch (err) {
@@ -825,10 +935,32 @@ export class BaseVisitor extends CircuitScriptVisitor {
825
935
  this.importedFiles.push(newImportedFile);
826
936
  return newImportedFile;
827
937
  }
828
- async checkLibraryHasRefdesFile(filePath) {
938
+ cacheLibraries() {
939
+ this.log('caching libraries');
940
+ const libraries = this.getScope().libraries;
941
+ for (const [libName, library] of libraries) {
942
+ this.log(`checking write flag for library ${library.libraryName}: ${library.writeToCache}`);
943
+ if (library.writeToCache && !library.parseError) {
944
+ try {
945
+ const { fileHash } = library;
946
+ const ir = serializeLibraryScope(library, fileHash);
947
+ writeCache(library.libraryFilePath, fileHash, ir);
948
+ this.log(`created cache for library: ${libName}`);
949
+ }
950
+ catch (err) {
951
+ this.log(`failed to cache library: ${libName}`);
952
+ throw new RuntimeExecutionError(`Failed to cache library: ${libName}`);
953
+ }
954
+ }
955
+ }
956
+ }
957
+ checkLibraryInRefdesFile(filePath) {
829
958
  return;
830
959
  }
831
- getRefdesFileAnnotation(filePath, startLine, startColumn, stopLine, stopColumn) {
960
+ getPathRefdesFile(filePath) {
961
+ return '';
962
+ }
963
+ getRefdesFileAnnotationKey(filePath, startLine, startColumn, stopLine, stopColumn) {
832
964
  return `${filePath}:${startLine}:${startColumn}:${stopLine}:${stopColumn}`;
833
965
  }
834
966
  visitRoundedBracketsExpr = (ctx) => {