circuitscript 0.3.2 → 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.
- package/dist/cjs/BaseVisitor.js +394 -262
- package/dist/cjs/LexerDiagnosticListener.js +375 -0
- package/dist/cjs/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
- package/dist/cjs/annotate/DefaultPostAnnotationCallback.js +126 -0
- package/dist/cjs/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
- package/dist/cjs/annotate/utils.js +70 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +279 -286
- package/dist/cjs/antlr/CircuitScriptParser.js +1954 -3535
- package/dist/cjs/antlr/CircuitScriptParserVisitor.js +7 -0
- package/dist/cjs/cache/deserializer.js +34 -0
- package/dist/cjs/cache/hash.js +8 -0
- package/dist/cjs/cache/serializer.js +122 -0
- package/dist/cjs/cache/storage.js +45 -0
- package/dist/cjs/cache/types.js +4 -0
- package/dist/cjs/{environment.js → environment/environment.js} +18 -6
- package/dist/cjs/environment/esm-environment.js +21 -0
- package/dist/cjs/environment/helpers.js +8 -0
- package/dist/cjs/execute.js +49 -15
- package/dist/cjs/globals.js +9 -1
- package/dist/cjs/helpers.js +3 -485
- package/dist/cjs/importResolver.js +102 -0
- package/dist/cjs/index.js +7 -6
- package/dist/cjs/lexer.js +48 -12
- package/dist/cjs/main.js +14 -4
- package/dist/cjs/objects/ClassComponent.js +1 -1
- package/dist/cjs/objects/ExecutionScope.js +0 -1
- package/dist/cjs/objects/types.js +17 -1
- package/dist/cjs/parser.js +18 -4
- package/dist/cjs/pipeline.js +284 -0
- package/dist/cjs/regenerate-tests.js +4 -3
- package/dist/cjs/render/KiCadNetListOutputHandler.js +30 -0
- package/dist/cjs/render/PaperSizes.js +46 -0
- package/dist/cjs/{draw_symbols.js → render/draw_symbols.js} +58 -36
- package/dist/cjs/{export.js → render/export.js} +2 -2
- package/dist/cjs/{geometry.js → render/geometry.js} +5 -5
- package/dist/cjs/{graph.js → render/graph.js} +7 -7
- package/dist/cjs/{layout.js → render/layout.js} +8 -8
- package/dist/cjs/{render.js → render/render.js} +9 -8
- package/dist/cjs/rules-check/no-connect-on-connected-pin.js +1 -1
- package/dist/cjs/rules-check/unconnected-pins.js +1 -1
- package/dist/cjs/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
- package/dist/cjs/semantic-tokens/getSemanticTokens.js +55 -0
- package/dist/cjs/sizing.js +2 -2
- package/dist/cjs/utils.js +2 -2
- package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +6 -0
- package/dist/cjs/validate/SymbolValidatorVisitor.js +34 -39
- package/dist/cjs/validate/validateScript.js +54 -0
- package/dist/cjs/validate.js +5 -4
- package/dist/cjs/visitor.js +140 -204
- package/dist/esm/BaseVisitor.js +396 -264
- package/dist/esm/LexerDiagnosticListener.js +371 -0
- package/dist/esm/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
- package/dist/esm/annotate/DefaultPostAnnotationCallback.js +122 -0
- package/dist/esm/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
- package/dist/esm/annotate/utils.js +66 -0
- package/dist/esm/antlr/CircuitScriptLexer.js +279 -286
- package/dist/esm/antlr/CircuitScriptParser.js +1962 -3522
- package/dist/esm/antlr/{CircuitScriptVisitor.js → CircuitScriptParserVisitor.js} +14 -35
- package/dist/esm/cache/deserializer.js +30 -0
- package/dist/esm/cache/hash.js +4 -0
- package/dist/esm/cache/serializer.js +118 -0
- package/dist/esm/cache/storage.js +39 -0
- package/dist/esm/cache/types.js +1 -0
- package/dist/esm/{environment.js → environment/environment.js} +18 -6
- package/dist/esm/environment/esm-environment.js +17 -0
- package/dist/esm/environment/helpers.js +4 -0
- package/dist/esm/execute.js +49 -15
- package/dist/esm/globals.js +8 -0
- package/dist/esm/helpers.js +5 -474
- package/dist/esm/importResolver.js +96 -0
- package/dist/esm/index.js +7 -6
- package/dist/esm/lexer.js +51 -12
- package/dist/esm/main.js +13 -3
- package/dist/esm/objects/ClassComponent.js +1 -1
- package/dist/esm/objects/ExecutionScope.js +0 -1
- package/dist/esm/objects/types.js +21 -1
- package/dist/esm/parser.js +19 -5
- package/dist/esm/pipeline.js +276 -0
- package/dist/esm/regenerate-tests.js +3 -2
- package/dist/esm/render/KiCadNetListOutputHandler.js +20 -0
- package/dist/esm/render/PaperSizes.js +41 -0
- package/dist/esm/{draw_symbols.js → render/draw_symbols.js} +58 -36
- package/dist/esm/{export.js → render/export.js} +2 -2
- package/dist/esm/{geometry.js → render/geometry.js} +5 -5
- package/dist/esm/{graph.js → render/graph.js} +7 -7
- package/dist/esm/{layout.js → render/layout.js} +8 -8
- package/dist/esm/{render.js → render/render.js} +8 -7
- package/dist/esm/rules-check/no-connect-on-connected-pin.js +1 -1
- package/dist/esm/rules-check/unconnected-pins.js +1 -1
- package/dist/esm/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
- package/dist/esm/semantic-tokens/getSemanticTokens.js +51 -0
- package/dist/esm/sizing.js +2 -2
- package/dist/esm/utils.js +2 -2
- package/dist/esm/validate/SymbolValidatorResolveVisitor.js +3 -0
- package/dist/esm/validate/SymbolValidatorVisitor.js +36 -41
- package/dist/esm/validate/validateScript.js +50 -0
- package/dist/esm/validate.js +4 -3
- package/dist/esm/visitor.js +142 -206
- package/dist/libs/std.cst +15 -19
- package/dist/types/BaseVisitor.d.ts +25 -18
- package/dist/types/BomGeneration.d.ts +1 -1
- package/dist/types/LexerDiagnosticListener.d.ts +85 -0
- package/dist/types/{ComponentAnnotater.d.ts → annotate/ComponentAnnotater.d.ts} +1 -1
- package/dist/types/annotate/DefaultPostAnnotationCallback.d.ts +7 -0
- package/dist/types/{RefdesAnnotationVisitor.d.ts → annotate/RefdesAnnotationVisitor.d.ts} +6 -8
- package/dist/types/annotate/utils.d.ts +6 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +71 -70
- package/dist/types/antlr/CircuitScriptParser.d.ts +357 -515
- package/dist/types/antlr/{CircuitScriptVisitor.d.ts → CircuitScriptParserVisitor.d.ts} +27 -69
- package/dist/types/cache/deserializer.d.ts +5 -0
- package/dist/types/cache/hash.d.ts +1 -0
- package/dist/types/cache/serializer.d.ts +3 -0
- package/dist/types/cache/storage.d.ts +4 -0
- package/dist/types/cache/types.d.ts +20 -0
- package/dist/types/{environment.d.ts → environment/environment.d.ts} +5 -4
- package/dist/types/environment/esm-environment.d.ts +4 -0
- package/dist/types/environment/helpers.d.ts +2 -0
- package/dist/types/execute.d.ts +3 -2
- package/dist/types/globals.d.ts +1 -0
- package/dist/types/helpers.d.ts +31 -36
- package/dist/types/importResolver.d.ts +4 -0
- package/dist/types/index.d.ts +7 -6
- package/dist/types/lexer.d.ts +9 -5
- package/dist/types/objects/ClassComponent.d.ts +1 -1
- package/dist/types/objects/ExecutionScope.d.ts +1 -4
- package/dist/types/objects/types.d.ts +16 -2
- package/dist/types/parser.d.ts +9 -2
- package/dist/types/pipeline.d.ts +9 -0
- package/dist/types/render/KiCadNetListOutputHandler.d.ts +10 -0
- package/dist/types/render/PaperSizes.d.ts +12 -0
- package/dist/types/{draw_symbols.d.ts → render/draw_symbols.d.ts} +4 -4
- package/dist/types/{export.d.ts → render/export.d.ts} +1 -1
- package/dist/types/{geometry.d.ts → render/geometry.d.ts} +2 -2
- package/dist/types/{graph.d.ts → render/graph.d.ts} +6 -6
- package/dist/types/{layout.d.ts → render/layout.d.ts} +10 -10
- package/dist/types/{render.d.ts → render/render.d.ts} +1 -1
- package/dist/types/{SemanticTokenVisitor.d.ts → semantic-tokens/SemanticTokenVisitor.d.ts} +6 -6
- package/dist/types/semantic-tokens/getSemanticTokens.d.ts +6 -0
- package/dist/types/sizing.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -1
- package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +3 -0
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +8 -8
- package/dist/types/validate/validateScript.d.ts +3 -0
- package/dist/types/visitor.d.ts +8 -14
- package/libs/std.cst +15 -19
- package/package.json +3 -6
- package/dist/cjs/antlr/CircuitScriptVisitor.js +0 -7
package/dist/esm/BaseVisitor.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { Big } from 'big.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
125
|
-
|
|
126
|
-
|
|
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 =
|
|
146
|
+
visitScript = (ctx) => {
|
|
129
147
|
this.log('===', 'start', '===');
|
|
130
148
|
this.allowParseImports = true;
|
|
131
149
|
for (const ctxImport of ctx.import_expr()) {
|
|
132
|
-
|
|
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
|
-
|
|
158
|
+
importCommon(ctx, handling) {
|
|
141
159
|
const specificImports = [];
|
|
142
|
-
if (ctx instanceof
|
|
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 =
|
|
150
|
-
const ctxImportAnnotation = ctx.
|
|
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 =
|
|
163
|
-
|
|
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
|
-
|
|
166
|
-
|
|
190
|
+
visitCallableExpr = (ctx) => {
|
|
191
|
+
this.passResult(ctx, ctx.callable_expr());
|
|
167
192
|
};
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
|
|
263
|
-
|
|
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
|
-
|
|
266
|
-
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
|
|
300
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
passedNetNamespace = this.visitResult(netNameSpaceExpr);
|
|
475
|
+
let parameters = [];
|
|
476
|
+
const ctxParameters = ctx.parameters();
|
|
477
|
+
if (ctxParameters) {
|
|
478
|
+
parameters = this.visitResult(ctxParameters);
|
|
398
479
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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
|
-
|
|
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
|
-
|
|
611
|
+
visitValueExpr = (ctx) => {
|
|
612
|
+
this.passResult(ctx, ctx.value_expr());
|
|
613
|
+
};
|
|
614
|
+
visitAtomExpr = (ctx) => {
|
|
558
615
|
let value = null;
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
|
|
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
|
|
565
|
-
|
|
566
|
-
|
|
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.
|
|
625
|
+
if ((reference.trailers && reference.trailers.length > 0)
|
|
626
|
+
|| reference.type === ReferenceTypes.function) {
|
|
571
627
|
value = reference;
|
|
572
628
|
}
|
|
573
629
|
else {
|
|
574
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
748
|
-
|
|
749
|
-
|
|
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
|
-
|
|
762
|
-
|
|
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
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) => {
|