circuitscript 0.1.20 → 0.1.23
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 +22 -0
- package/dist/cjs/ComponentAnnotater.js +88 -0
- package/dist/cjs/RefdesAnnotationVisitor.js +197 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +202 -197
- package/dist/cjs/antlr/CircuitScriptParser.js +975 -833
- package/dist/cjs/environment.js +15 -1
- package/dist/cjs/execute.js +45 -2
- package/dist/cjs/helpers.js +20 -2
- package/dist/cjs/lexer.js +21 -9
- package/dist/cjs/main.js +13 -0
- package/dist/cjs/objects/ClassComponent.js +4 -1
- package/dist/cjs/objects/ExecutionScope.js +1 -0
- package/dist/cjs/parser.js +1 -0
- package/dist/cjs/visitor.js +122 -71
- package/dist/esm/BaseVisitor.js +22 -0
- package/dist/esm/ComponentAnnotater.js +84 -0
- package/dist/esm/RefdesAnnotationVisitor.js +196 -0
- package/dist/esm/antlr/CircuitScriptLexer.js +202 -197
- package/dist/esm/antlr/CircuitScriptParser.js +971 -831
- package/dist/esm/antlr/CircuitScriptVisitor.js +2 -0
- package/dist/esm/environment.js +15 -1
- package/dist/esm/execute.js +45 -2
- package/dist/esm/helpers.js +20 -2
- package/dist/esm/lexer.js +21 -9
- package/dist/esm/main.js +13 -0
- package/dist/esm/objects/ClassComponent.js +4 -1
- package/dist/esm/objects/ExecutionScope.js +1 -0
- package/dist/esm/parser.js +1 -0
- package/dist/esm/visitor.js +120 -69
- package/dist/types/BaseVisitor.d.ts +3 -0
- package/dist/types/ComponentAnnotater.d.ts +16 -0
- package/dist/types/RefdesAnnotationVisitor.d.ts +35 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +15 -14
- package/dist/types/antlr/CircuitScriptParser.d.ts +81 -60
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +4 -0
- package/dist/types/environment.d.ts +1 -0
- package/dist/types/execute.d.ts +8 -1
- package/dist/types/helpers.d.ts +4 -1
- package/dist/types/lexer.d.ts +1 -1
- package/dist/types/objects/ClassComponent.d.ts +9 -0
- package/dist/types/objects/ExecutionScope.d.ts +2 -1
- package/dist/types/objects/types.d.ts +1 -0
- package/dist/types/parser.d.ts +2 -1
- package/dist/types/visitor.d.ts +8 -1
- package/package.json +1 -1
package/dist/cjs/environment.js
CHANGED
|
@@ -14,6 +14,7 @@ class NodeScriptEnvironment {
|
|
|
14
14
|
this.useModuleDirectoryPath = null;
|
|
15
15
|
this.useDefaultLibsPath = null;
|
|
16
16
|
this.globalCreateSVGWindow = null;
|
|
17
|
+
this.cachedVersion = null;
|
|
17
18
|
this.supportedFonts = {
|
|
18
19
|
'Arial': 'Arial.ttf',
|
|
19
20
|
};
|
|
@@ -31,7 +32,20 @@ class NodeScriptEnvironment {
|
|
|
31
32
|
this.useDefaultLibsPath = path;
|
|
32
33
|
}
|
|
33
34
|
getPackageVersion() {
|
|
34
|
-
|
|
35
|
+
if (this.cachedVersion !== null) {
|
|
36
|
+
return this.cachedVersion;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const packageJsonPath = path_1.default.join(this.getToolsPath(), '../', 'package.json');
|
|
40
|
+
const packageJsonContent = fs_1.default.readFileSync(packageJsonPath, 'utf-8');
|
|
41
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
42
|
+
this.cachedVersion = packageJson.version || globals_js_1.TOOL_VERSION;
|
|
43
|
+
return this.cachedVersion;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.warn('Failed to read version from package.json, using fallback version:', error);
|
|
47
|
+
return globals_js_1.TOOL_VERSION;
|
|
48
|
+
}
|
|
35
49
|
}
|
|
36
50
|
getModuleDirectory() {
|
|
37
51
|
if (this.useModuleDirectoryPath !== null) {
|
package/dist/cjs/execute.js
CHANGED
|
@@ -24,6 +24,7 @@ class ExecutionContext {
|
|
|
24
24
|
this.__functionCache = new Map();
|
|
25
25
|
this.componentAngleFollowsWire = true;
|
|
26
26
|
this.warnings = [];
|
|
27
|
+
this.indexedStack = new Map();
|
|
27
28
|
this.name = name;
|
|
28
29
|
this.namespace = namespace;
|
|
29
30
|
this.netNamespace = netNamespace;
|
|
@@ -542,9 +543,39 @@ class ExecutionContext {
|
|
|
542
543
|
this.log('did not find block point');
|
|
543
544
|
return null;
|
|
544
545
|
}
|
|
546
|
+
getParentBreakContext() {
|
|
547
|
+
if (this.scope.breakStack.length > 0) {
|
|
548
|
+
return this.scope.breakStack[this.scope.breakStack.length - 1];
|
|
549
|
+
}
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
545
552
|
addBreakContext(ctx) {
|
|
546
553
|
this.log('add break context');
|
|
547
554
|
this.scope.breakStack.push(ctx);
|
|
555
|
+
this.indexedStack.set(ctx, {
|
|
556
|
+
index: 0,
|
|
557
|
+
funcCallIndex: new Map(),
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
setBreakContextIndex(index) {
|
|
561
|
+
const latestCtx = this.scope.breakStack[this.scope.breakStack.length - 1];
|
|
562
|
+
if (latestCtx) {
|
|
563
|
+
const current = this.indexedStack.get(latestCtx);
|
|
564
|
+
this.indexedStack.set(latestCtx, {
|
|
565
|
+
...current,
|
|
566
|
+
index,
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
resetBreakContextFunctionCalls() {
|
|
571
|
+
const latestCtx = this.scope.breakStack[this.scope.breakStack.length - 1];
|
|
572
|
+
if (latestCtx) {
|
|
573
|
+
const current = this.indexedStack.get(latestCtx);
|
|
574
|
+
this.indexedStack.set(latestCtx, {
|
|
575
|
+
index: current.index,
|
|
576
|
+
funcCallIndex: new Map(),
|
|
577
|
+
});
|
|
578
|
+
}
|
|
548
579
|
}
|
|
549
580
|
popBreakContext() {
|
|
550
581
|
this.log('pop break context');
|
|
@@ -667,9 +698,18 @@ class ExecutionContext {
|
|
|
667
698
|
__runFunc = this.__functionCache.get(functionName);
|
|
668
699
|
}
|
|
669
700
|
if (__runFunc !== null) {
|
|
701
|
+
let functionCallIndex = -1;
|
|
702
|
+
if (!this.scope.functionCounter.has(__runFunc)) {
|
|
703
|
+
this.scope.functionCounter.set(__runFunc, 0);
|
|
704
|
+
functionCallIndex = 0;
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
functionCallIndex = this.scope.functionCounter.get(__runFunc);
|
|
708
|
+
}
|
|
709
|
+
this.scope.functionCounter.set(__runFunc, functionCallIndex + 1);
|
|
670
710
|
this.log(`call function '${functionName}'`);
|
|
671
711
|
this.log(`net namespace: ${netNamespace}`);
|
|
672
|
-
const functionResult = __runFunc(functionParams, { netNamespace });
|
|
712
|
+
const functionResult = __runFunc(functionParams, { netNamespace, functionCallIndex });
|
|
673
713
|
this.log(`done call function '${functionName}'`);
|
|
674
714
|
return functionResult;
|
|
675
715
|
}
|
|
@@ -682,6 +722,7 @@ class ExecutionContext {
|
|
|
682
722
|
const { currentComponent, currentPin, currentWireId } = this.scope;
|
|
683
723
|
const tmpInstances = childScope.instances;
|
|
684
724
|
const tmpNets = childScope.getNets();
|
|
725
|
+
const mergedInstances = [];
|
|
685
726
|
for (const [instanceName, component] of tmpInstances) {
|
|
686
727
|
const newInstanceName = `${namespace}.${instanceName}`;
|
|
687
728
|
component.instanceName = newInstanceName;
|
|
@@ -694,6 +735,7 @@ class ExecutionContext {
|
|
|
694
735
|
else {
|
|
695
736
|
throw "Invalid instance name to merge into parent scope!";
|
|
696
737
|
}
|
|
738
|
+
mergedInstances.push(component);
|
|
697
739
|
}
|
|
698
740
|
const childScopeUniqueNets = new Set(tmpNets.map(([, , net]) => net));
|
|
699
741
|
childScopeUniqueNets.forEach(net => {
|
|
@@ -767,6 +809,7 @@ class ExecutionContext {
|
|
|
767
809
|
return accum;
|
|
768
810
|
}, []);
|
|
769
811
|
this.log('-- done merging scope --');
|
|
812
|
+
return mergedInstances;
|
|
770
813
|
}
|
|
771
814
|
addWire(segments) {
|
|
772
815
|
if (this.scope.currentComponent === null) {
|
|
@@ -890,7 +933,7 @@ class ExecutionContext {
|
|
|
890
933
|
idName = this.scope.currentComponent.instanceName;
|
|
891
934
|
if (this.scope.instances.has(idName)) {
|
|
892
935
|
const component = this.scope.instances.get(idName);
|
|
893
|
-
component.
|
|
936
|
+
component.setParam(paramName, value);
|
|
894
937
|
}
|
|
895
938
|
else if (this.scope.variables.has(idName)) {
|
|
896
939
|
throw "Not implemented yet!";
|
package/dist/cjs/helpers.js
CHANGED
|
@@ -24,6 +24,7 @@ const Frame_js_1 = require("./objects/Frame.js");
|
|
|
24
24
|
const big_js_1 = __importDefault(require("big.js"));
|
|
25
25
|
const logger_js_1 = require("./logger.js");
|
|
26
26
|
const graph_js_1 = require("./graph.js");
|
|
27
|
+
const RefdesAnnotationVisitor_js_1 = require("./RefdesAnnotationVisitor.js");
|
|
27
28
|
var JSModuleType;
|
|
28
29
|
(function (JSModuleType) {
|
|
29
30
|
JSModuleType["CommonJs"] = "cjs";
|
|
@@ -165,7 +166,7 @@ async function renderScript(scriptData, outputPath, options) {
|
|
|
165
166
|
}
|
|
166
167
|
exports.renderScript = renderScript;
|
|
167
168
|
async function renderScriptCustom(scriptData, outputPath, options, parseHandlers) {
|
|
168
|
-
const { dumpNets = false, dumpData = false, showStats = false, environment } = options;
|
|
169
|
+
const { dumpNets = false, dumpData = false, showStats = false, environment, inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
|
|
169
170
|
const errors = [];
|
|
170
171
|
const onErrorHandler = (message, context, error) => {
|
|
171
172
|
if (error && error instanceof utils_js_1.RuntimeExecutionError) {
|
|
@@ -209,7 +210,7 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
|
|
|
209
210
|
(0, fs_1.mkdirSync)(dumpDirectory);
|
|
210
211
|
}
|
|
211
212
|
}
|
|
212
|
-
const { tree, parser, parserTimeTaken, lexerTimeTaken, throwError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
|
|
213
|
+
const { tree, parser, tokens, parserTimeTaken, lexerTimeTaken, throwError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
|
|
213
214
|
(0, utils_js_1.printWarnings)(visitor.getWarnings());
|
|
214
215
|
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
215
216
|
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
@@ -219,6 +220,23 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
|
|
|
219
220
|
catch (err) {
|
|
220
221
|
throw new utils_js_1.RenderError(`Error during component annotation: ${err}`, 'annotation');
|
|
221
222
|
}
|
|
223
|
+
const componentLinks = visitor.getComponentCtxLinks();
|
|
224
|
+
const refdesVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
|
|
225
|
+
await refdesVisitor.visitAsync(tree);
|
|
226
|
+
if (inputPath && (updateSource || saveAnnotatedCopy !== undefined)) {
|
|
227
|
+
let usePath = inputPath;
|
|
228
|
+
if (saveAnnotatedCopy === true) {
|
|
229
|
+
const dir = path_1.default.dirname(inputPath);
|
|
230
|
+
const ext = path_1.default.extname(inputPath);
|
|
231
|
+
const basename = path_1.default.basename(inputPath, ext);
|
|
232
|
+
usePath = path_1.default.join(dir, `${basename}.annotated${ext}`);
|
|
233
|
+
}
|
|
234
|
+
else if (typeof saveAnnotatedCopy === 'string') {
|
|
235
|
+
usePath = saveAnnotatedCopy;
|
|
236
|
+
}
|
|
237
|
+
console.log('Annotations saved to ' + usePath);
|
|
238
|
+
(0, fs_1.writeFileSync)(usePath, refdesVisitor.getOutput());
|
|
239
|
+
}
|
|
222
240
|
if (dumpNets) {
|
|
223
241
|
const nets = visitor.dumpNets();
|
|
224
242
|
nets.forEach(item => console.log(item.join(" | ")));
|
package/dist/cjs/lexer.js
CHANGED
|
@@ -26,12 +26,14 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
|
|
|
26
26
|
this.tokens = this.tokens.filter(function (val) {
|
|
27
27
|
return val.type !== CircuitScriptParser_js_1.CircuitScriptParser.EOF;
|
|
28
28
|
});
|
|
29
|
-
this.
|
|
29
|
+
const fillerNewLine = this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, "");
|
|
30
|
+
this.emitToken(fillerNewLine);
|
|
31
|
+
fillerNewLine.__skip = true;
|
|
30
32
|
while (this.indents.length) {
|
|
31
33
|
this.emitToken(this.createDedent());
|
|
32
34
|
this.indents.pop();
|
|
33
35
|
}
|
|
34
|
-
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.EOF, "
|
|
36
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.EOF, ""));
|
|
35
37
|
}
|
|
36
38
|
const next = super.nextToken();
|
|
37
39
|
return this.tokens.length ? this.tokens.shift() : next;
|
|
@@ -42,16 +44,24 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
|
|
|
42
44
|
getCharIndex() {
|
|
43
45
|
return this.inputStream.index;
|
|
44
46
|
}
|
|
45
|
-
commonToken(type, text) {
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
commonToken(type, text, start = -1, stop = -1) {
|
|
48
|
+
if (start === -1 && stop === -1) {
|
|
49
|
+
stop = this.getCharIndex() - 1;
|
|
50
|
+
start = text.length ? stop - text.length + 1 : stop;
|
|
51
|
+
}
|
|
48
52
|
const token = antlr4ng_1.CommonToken.fromSource([this, this.inputStream], type, 0, start, stop);
|
|
49
53
|
let tokenTypeString = null;
|
|
50
54
|
if (type === CircuitScriptParser_js_1.CircuitScriptParser.INDENT) {
|
|
51
|
-
tokenTypeString =
|
|
55
|
+
tokenTypeString = 'indent';
|
|
52
56
|
}
|
|
53
57
|
else if (type === CircuitScriptParser_js_1.CircuitScriptParser.DEDENT) {
|
|
54
|
-
tokenTypeString =
|
|
58
|
+
tokenTypeString = 'dedent';
|
|
59
|
+
}
|
|
60
|
+
else if (type === CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE) {
|
|
61
|
+
tokenTypeString = 'newline';
|
|
62
|
+
}
|
|
63
|
+
else if (type === CircuitScriptParser_js_1.CircuitScriptParser.EOF) {
|
|
64
|
+
tokenTypeString = 'EOF';
|
|
55
65
|
}
|
|
56
66
|
if (tokenTypeString !== null) {
|
|
57
67
|
token.text = tokenTypeString;
|
|
@@ -89,7 +99,9 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
|
|
|
89
99
|
this.skip();
|
|
90
100
|
}
|
|
91
101
|
else {
|
|
92
|
-
this.
|
|
102
|
+
const start = this.getCharIndex() - this.text.length;
|
|
103
|
+
const stop = this.getCharIndex() - 1;
|
|
104
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, newLine, start, start));
|
|
93
105
|
const indent = this.getIndentationCount(spaces);
|
|
94
106
|
const previous = this.indents.length ? this.indents[this.indents.length - 1] : 0;
|
|
95
107
|
if (indent === previous) {
|
|
@@ -97,7 +109,7 @@ class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
|
|
|
97
109
|
}
|
|
98
110
|
else if (indent > previous) {
|
|
99
111
|
this.indents.push(indent);
|
|
100
|
-
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.INDENT, spaces));
|
|
112
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.INDENT, spaces, start + 1, stop));
|
|
101
113
|
}
|
|
102
114
|
else {
|
|
103
115
|
while (this.indents.length && this.indents[this.indents.length - 1] > indent) {
|
package/dist/cjs/main.js
CHANGED
|
@@ -20,6 +20,8 @@ async function main() {
|
|
|
20
20
|
.argument('[output path]', 'Output path')
|
|
21
21
|
.option('-i, --input text <input text>', 'Input text directly')
|
|
22
22
|
.option('-c, --current-directory <path>', 'Set current directory')
|
|
23
|
+
.option('-u, --update-source', 'Update source file with refdes annotation')
|
|
24
|
+
.option('-j, --annotated-path [file-path]', 'Save annotated source file at given path')
|
|
23
25
|
.option('-w, --watch', 'Watch for file changes')
|
|
24
26
|
.option('-n, --dump-nets', 'Dump out net information')
|
|
25
27
|
.option('-d, --dump-data', 'Dump data during parsing')
|
|
@@ -67,11 +69,22 @@ async function main() {
|
|
|
67
69
|
console.error("Error: No input provided");
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
72
|
+
let updateSource = false;
|
|
73
|
+
if (options.updateSource !== undefined) {
|
|
74
|
+
updateSource = options.updateSource;
|
|
75
|
+
}
|
|
76
|
+
let saveAnnotatedCopyPath = undefined;
|
|
77
|
+
if (options.annotatedPath !== undefined) {
|
|
78
|
+
saveAnnotatedCopyPath = options.annotatedPath;
|
|
79
|
+
}
|
|
70
80
|
const scriptOptions = {
|
|
71
81
|
dumpNets,
|
|
72
82
|
dumpData,
|
|
73
83
|
showStats: options.stats,
|
|
74
84
|
environment: env,
|
|
85
|
+
inputPath: inputFilePath,
|
|
86
|
+
updateSource,
|
|
87
|
+
saveAnnotatedCopy: saveAnnotatedCopyPath,
|
|
75
88
|
};
|
|
76
89
|
let outputPath = null;
|
|
77
90
|
if (args.length > 0 && args[1]) {
|
|
@@ -28,6 +28,9 @@ class ClassComponent {
|
|
|
28
28
|
this.useWireOrientationAngle = true;
|
|
29
29
|
this.didSetWireOrientationAngle = false;
|
|
30
30
|
this.assignedRefDes = null;
|
|
31
|
+
this.placeHolderRefDes = null;
|
|
32
|
+
this.ctxReferences = [];
|
|
33
|
+
this._creationIndex = -1;
|
|
31
34
|
this.instanceName = instanceName;
|
|
32
35
|
this.numPins = numPins;
|
|
33
36
|
}
|
|
@@ -106,7 +109,7 @@ class ClassComponent {
|
|
|
106
109
|
return this.parameters.get(key);
|
|
107
110
|
}
|
|
108
111
|
else {
|
|
109
|
-
throw 'Invalid parameter key';
|
|
112
|
+
throw 'Invalid parameter key: ' + key;
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
toString() {
|
package/dist/cjs/parser.js
CHANGED
package/dist/cjs/visitor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VisitorExecutionException = exports.ParserVisitor = void 0;
|
|
3
|
+
exports.VisitorExecutionException = exports.ComponentRefDesPrefixes = exports.ParserVisitor = void 0;
|
|
4
4
|
const ClassComponent_js_1 = require("./objects/ClassComponent.js");
|
|
5
5
|
const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
|
|
6
6
|
const PinDefinition_js_1 = require("./objects/PinDefinition.js");
|
|
@@ -13,9 +13,11 @@ const BaseVisitor_js_1 = require("./BaseVisitor.js");
|
|
|
13
13
|
const utils_js_2 = require("./utils.js");
|
|
14
14
|
const helpers_js_1 = require("./helpers.js");
|
|
15
15
|
const Frame_js_1 = require("./objects/Frame.js");
|
|
16
|
+
const ComponentAnnotater_js_1 = require("./ComponentAnnotater.js");
|
|
16
17
|
class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
17
18
|
constructor() {
|
|
18
19
|
super(...arguments);
|
|
20
|
+
this.componentCreationIndex = 0;
|
|
19
21
|
this.visitKeyword_assignment_expr = (ctx) => {
|
|
20
22
|
const id = ctx.ID().getText();
|
|
21
23
|
const value = this.visitResult(ctx.data_expr());
|
|
@@ -40,28 +42,53 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
40
42
|
}
|
|
41
43
|
this.setResult(ctx, pinId);
|
|
42
44
|
};
|
|
45
|
+
this.trackNewComponentCreated = (callback) => {
|
|
46
|
+
const preCreatedIndex = this.componentCreationIndex;
|
|
47
|
+
callback();
|
|
48
|
+
const postCreatedIndex = this.componentCreationIndex;
|
|
49
|
+
let creationFlag = false;
|
|
50
|
+
if (postCreatedIndex > preCreatedIndex) {
|
|
51
|
+
creationFlag = true;
|
|
52
|
+
}
|
|
53
|
+
return creationFlag;
|
|
54
|
+
};
|
|
43
55
|
this.visitAdd_component_expr = (ctx) => {
|
|
44
|
-
|
|
45
|
-
this.
|
|
56
|
+
let refComponent;
|
|
57
|
+
const creationFlag = this.trackNewComponentCreated(() => {
|
|
58
|
+
const [component, pinValue] = this.visitResult(ctx.data_expr_with_assignment());
|
|
59
|
+
this.getExecutor().addComponentExisting(component, pinValue);
|
|
60
|
+
refComponent = component;
|
|
61
|
+
});
|
|
62
|
+
this.linkComponentToCtx(ctx, refComponent, creationFlag);
|
|
46
63
|
};
|
|
47
64
|
this.visitAt_component_expr = (ctx) => {
|
|
48
|
-
|
|
49
|
-
this.
|
|
50
|
-
|
|
65
|
+
let refComponent;
|
|
66
|
+
const creationFlag = this.trackNewComponentCreated(() => {
|
|
67
|
+
const [component, pin] = this.visitResult(ctx.component_select_expr());
|
|
68
|
+
this.getExecutor().atComponent(component, pin, {
|
|
69
|
+
addSequence: true
|
|
70
|
+
});
|
|
71
|
+
refComponent = component;
|
|
51
72
|
});
|
|
73
|
+
this.linkComponentToCtx(ctx, refComponent, creationFlag);
|
|
52
74
|
return this.getExecutor().getCurrentPoint();
|
|
53
75
|
};
|
|
54
76
|
this.visitTo_component_expr = (ctx) => {
|
|
55
77
|
ctx.component_select_expr().forEach(item => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
let refComponent;
|
|
79
|
+
const creationFlag = this.trackNewComponentCreated(() => {
|
|
80
|
+
const [component, pin] = this.visitResult(item);
|
|
81
|
+
try {
|
|
82
|
+
this.getExecutor().toComponent(component, pin, {
|
|
83
|
+
addSequence: true
|
|
84
|
+
});
|
|
85
|
+
refComponent = component;
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
throw new utils_js_2.RuntimeExecutionError(err.message, ctx);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
this.linkComponentToCtx(item, refComponent, creationFlag);
|
|
65
92
|
});
|
|
66
93
|
return this.getExecutor().getCurrentPoint();
|
|
67
94
|
};
|
|
@@ -332,6 +359,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
332
359
|
try {
|
|
333
360
|
const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
|
|
334
361
|
this.setResult(ctx, createdComponent);
|
|
362
|
+
createdComponent._creationIndex = this.componentCreationIndex++;
|
|
335
363
|
}
|
|
336
364
|
catch (error) {
|
|
337
365
|
this.throwWithContext(ctx, error.message);
|
|
@@ -822,7 +850,28 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
822
850
|
const resolveNet = this.createNetResolver(this.executionStack);
|
|
823
851
|
const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
|
|
824
852
|
const __runFunc = (passedInParameters, options) => {
|
|
825
|
-
const
|
|
853
|
+
const executor = this.getExecutor();
|
|
854
|
+
const parentBreakContext = executor.getParentBreakContext();
|
|
855
|
+
executor.addBreakContext(ctx);
|
|
856
|
+
let useIndex = -1;
|
|
857
|
+
if (parentBreakContext === null) {
|
|
858
|
+
useIndex = options.functionCallIndex;
|
|
859
|
+
}
|
|
860
|
+
else {
|
|
861
|
+
const parentEntry = executor.indexedStack.get(parentBreakContext);
|
|
862
|
+
const { funcCallIndex } = parentEntry;
|
|
863
|
+
if (!funcCallIndex.has(ctx)) {
|
|
864
|
+
funcCallIndex.set(ctx, 0);
|
|
865
|
+
useIndex = 0;
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
useIndex = funcCallIndex.get(ctx) + 1;
|
|
869
|
+
funcCallIndex.set(ctx, useIndex);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
executor.setBreakContextIndex(useIndex);
|
|
873
|
+
const functionCounterIndex = functionCounter['counter'];
|
|
874
|
+
const executionContextName = `${functionName}-${functionCounterIndex}`;
|
|
826
875
|
const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
|
|
827
876
|
functionCounter['counter'] += 1;
|
|
828
877
|
newExecutor.resolveNet = resolveNet;
|
|
@@ -830,7 +879,23 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
830
879
|
const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
|
|
831
880
|
const lastExecution = executionStack.pop();
|
|
832
881
|
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
833
|
-
nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
882
|
+
const mergedComponents = nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
883
|
+
const scope = this.getScope();
|
|
884
|
+
const indexedStack = [];
|
|
885
|
+
if (scope.breakStack.length > 0) {
|
|
886
|
+
const executor = this.getExecutor();
|
|
887
|
+
scope.breakStack.forEach(stackCtx => {
|
|
888
|
+
const entry = executor.indexedStack.get(stackCtx);
|
|
889
|
+
const { index } = entry;
|
|
890
|
+
indexedStack.push([stackCtx, index]);
|
|
891
|
+
});
|
|
892
|
+
mergedComponents.forEach(component => {
|
|
893
|
+
component.ctxReferences.forEach(ref => {
|
|
894
|
+
ref.indexedStack = [...indexedStack, ...ref.indexedStack];
|
|
895
|
+
});
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
executor.popBreakContext();
|
|
834
899
|
return [lastExecution, returnValue];
|
|
835
900
|
};
|
|
836
901
|
this.getExecutor().createFunction(functionName, __runFunc, ctx, uniqueFunctionID);
|
|
@@ -874,10 +939,21 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
874
939
|
executor.log('end at block pin expressions');
|
|
875
940
|
executor.atComponent(currentComponent, currentPin);
|
|
876
941
|
};
|
|
942
|
+
this.visitAt_block_header = (ctx) => {
|
|
943
|
+
const ctxAtComponent = ctx.at_component_expr();
|
|
944
|
+
this.visit(ctxAtComponent);
|
|
945
|
+
const [currentComponent,] = this.getExecutor().getCurrentPoint();
|
|
946
|
+
this.componentCtxLinks.delete(ctxAtComponent);
|
|
947
|
+
this.componentCtxLinks.set(ctx, currentComponent);
|
|
948
|
+
ctx.annotation_comment_expr().forEach(ctx => {
|
|
949
|
+
this.visit(ctx);
|
|
950
|
+
});
|
|
951
|
+
};
|
|
877
952
|
this.visitAt_block = (ctx) => {
|
|
878
953
|
const executor = this.getExecutor();
|
|
879
954
|
executor.log('entering at block');
|
|
880
|
-
|
|
955
|
+
const ctxAtBlockComponent = ctx.at_block_header();
|
|
956
|
+
this.visit(ctxAtBlockComponent);
|
|
881
957
|
const [currentComponent, currentPin] = executor.getCurrentPoint();
|
|
882
958
|
executor.scope.scopeLevel += 1;
|
|
883
959
|
ctx.at_block_expressions().forEach(expression => {
|
|
@@ -1037,10 +1113,14 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1037
1113
|
const dataExpr = ctx.data_expr();
|
|
1038
1114
|
let keepLooping = true;
|
|
1039
1115
|
this.log('enter while loop');
|
|
1040
|
-
this.getExecutor()
|
|
1116
|
+
const executor = this.getExecutor();
|
|
1117
|
+
executor.addBreakContext(ctx);
|
|
1118
|
+
let counter = 0;
|
|
1041
1119
|
while (keepLooping) {
|
|
1042
1120
|
const result = this.visitResult(dataExpr);
|
|
1043
1121
|
if (result) {
|
|
1122
|
+
executor.setBreakContextIndex(counter);
|
|
1123
|
+
executor.resetBreakContextFunctionCalls();
|
|
1044
1124
|
this.visit(ctx.expressions_block());
|
|
1045
1125
|
keepLooping = true;
|
|
1046
1126
|
const currentResult = this.getResult(ctx) ?? {};
|
|
@@ -1055,6 +1135,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1055
1135
|
continueSignal: false
|
|
1056
1136
|
});
|
|
1057
1137
|
}
|
|
1138
|
+
counter++;
|
|
1058
1139
|
}
|
|
1059
1140
|
else {
|
|
1060
1141
|
keepLooping = false;
|
|
@@ -1068,7 +1149,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1068
1149
|
const forVariableNames = ctx.ID().map(item => item.getText());
|
|
1069
1150
|
let listItems = this.visitResult(ctx.data_expr());
|
|
1070
1151
|
listItems = (0, utils_js_1.unwrapValue)(listItems);
|
|
1071
|
-
this.getExecutor()
|
|
1152
|
+
const executor = this.getExecutor();
|
|
1153
|
+
executor.addBreakContext(ctx);
|
|
1072
1154
|
let keepLooping = true;
|
|
1073
1155
|
let counter = 0;
|
|
1074
1156
|
while (keepLooping) {
|
|
@@ -1080,6 +1162,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1080
1162
|
useValueArray.forEach((value, index) => {
|
|
1081
1163
|
this.getScope().setVariable(forVariableNames[index], value);
|
|
1082
1164
|
});
|
|
1165
|
+
executor.setBreakContextIndex(counter);
|
|
1166
|
+
executor.resetBreakContextFunctionCalls();
|
|
1083
1167
|
this.visit(ctx.expressions_block());
|
|
1084
1168
|
keepLooping = true;
|
|
1085
1169
|
const currentResult = this.getResult(ctx) ?? {};
|
|
@@ -1101,7 +1185,19 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1101
1185
|
keepLooping = false;
|
|
1102
1186
|
}
|
|
1103
1187
|
}
|
|
1104
|
-
|
|
1188
|
+
executor.popBreakContext();
|
|
1189
|
+
};
|
|
1190
|
+
this.visitAnnotation_comment_expr = (ctx) => {
|
|
1191
|
+
const refdesID = ctx.ID().getText();
|
|
1192
|
+
const currentComponent = this.getScope().currentComponent;
|
|
1193
|
+
if (currentComponent !== null) {
|
|
1194
|
+
if (refdesID.indexOf('_') === -1) {
|
|
1195
|
+
currentComponent.setParam('refdes', refdesID);
|
|
1196
|
+
}
|
|
1197
|
+
else {
|
|
1198
|
+
currentComponent.placeHolderRefDes = refdesID;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1105
1201
|
};
|
|
1106
1202
|
this.pinTypes = [
|
|
1107
1203
|
PinTypes_js_1.PinTypes.Any,
|
|
@@ -1346,7 +1442,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1346
1442
|
}
|
|
1347
1443
|
annotateComponents() {
|
|
1348
1444
|
this.log('===== annotate components =====');
|
|
1349
|
-
const annotater = new ComponentAnnotater();
|
|
1445
|
+
const annotater = new ComponentAnnotater_js_1.ComponentAnnotater();
|
|
1350
1446
|
const instances = this.getScope().instances;
|
|
1351
1447
|
const toAnnotate = [];
|
|
1352
1448
|
for (const [, instance] of instances) {
|
|
@@ -1355,8 +1451,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1355
1451
|
continue;
|
|
1356
1452
|
}
|
|
1357
1453
|
if (instance.assignedRefDes === null) {
|
|
1358
|
-
if (instance.
|
|
1359
|
-
const refdes = instance.
|
|
1454
|
+
if (instance.hasParam('refdes')) {
|
|
1455
|
+
const refdes = instance.getParam('refdes');
|
|
1360
1456
|
if (refdes) {
|
|
1361
1457
|
instance.assignedRefDes = refdes;
|
|
1362
1458
|
annotater.trackRefDes(refdes);
|
|
@@ -1368,10 +1464,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1368
1464
|
}
|
|
1369
1465
|
}
|
|
1370
1466
|
toAnnotate.forEach(instance => {
|
|
1371
|
-
const
|
|
1372
|
-
instance.typeProp === null
|
|
1373
|
-
&& this.log('Instance has no type:', instance.instanceName, ' assuming connector');
|
|
1374
|
-
const newRefDes = annotater.getAnnotation(useTypeProp);
|
|
1467
|
+
const newRefDes = annotater.getAnnotation(instance);
|
|
1375
1468
|
if (newRefDes !== null) {
|
|
1376
1469
|
instance.assignedRefDes = newRefDes;
|
|
1377
1470
|
this.log(newRefDes, '-', instance.instanceName);
|
|
@@ -1456,7 +1549,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1456
1549
|
}
|
|
1457
1550
|
}
|
|
1458
1551
|
exports.ParserVisitor = ParserVisitor;
|
|
1459
|
-
|
|
1552
|
+
exports.ComponentRefDesPrefixes = {
|
|
1460
1553
|
res: 'R',
|
|
1461
1554
|
cap: 'C',
|
|
1462
1555
|
ind: 'L',
|
|
@@ -1467,48 +1560,6 @@ const ComponentRefDesPrefixes = {
|
|
|
1467
1560
|
ic: 'U',
|
|
1468
1561
|
'?': '?',
|
|
1469
1562
|
};
|
|
1470
|
-
class ComponentAnnotater {
|
|
1471
|
-
constructor() {
|
|
1472
|
-
this.counter = {};
|
|
1473
|
-
this.existingRefDes = [];
|
|
1474
|
-
for (const key in ComponentRefDesPrefixes) {
|
|
1475
|
-
this.counter[key] = 1;
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
getAnnotation(type) {
|
|
1479
|
-
if (this.counter[type] === undefined && type.length <= 2) {
|
|
1480
|
-
for (const [, value] of Object.entries(ComponentRefDesPrefixes)) {
|
|
1481
|
-
if (value === type) {
|
|
1482
|
-
throw "Refdes prefix is already in use!";
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
1486
|
-
ComponentRefDesPrefixes[type] = type;
|
|
1487
|
-
this.counter[type] = 1;
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
1491
|
-
return null;
|
|
1492
|
-
}
|
|
1493
|
-
let attempts = 100;
|
|
1494
|
-
let proposedName = "";
|
|
1495
|
-
while (attempts >= 0) {
|
|
1496
|
-
proposedName = ComponentRefDesPrefixes[type] + this.counter[type];
|
|
1497
|
-
this.counter[type]++;
|
|
1498
|
-
if (this.existingRefDes.indexOf(proposedName) === -1) {
|
|
1499
|
-
break;
|
|
1500
|
-
}
|
|
1501
|
-
attempts--;
|
|
1502
|
-
}
|
|
1503
|
-
if (attempts === 0) {
|
|
1504
|
-
throw "Annotation failed!";
|
|
1505
|
-
}
|
|
1506
|
-
return proposedName;
|
|
1507
|
-
}
|
|
1508
|
-
trackRefDes(name) {
|
|
1509
|
-
this.existingRefDes.push(name);
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
1563
|
class VisitorExecutionException {
|
|
1513
1564
|
constructor(context, errorMessage) {
|
|
1514
1565
|
this.errorMessage = errorMessage;
|