circuitscript 0.1.20 → 0.1.22
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 +964 -831
- package/dist/cjs/environment.js +15 -1
- package/dist/cjs/execute.js +45 -2
- package/dist/cjs/helpers.js +21 -4
- 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 +119 -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 +960 -829
- 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 +21 -4
- 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 +117 -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 +80 -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 +6 -3
- 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/esm/BaseVisitor.js
CHANGED
|
@@ -23,6 +23,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
23
23
|
acceptedDirections = [Direction.Up, Direction.Down,
|
|
24
24
|
Direction.Right, Direction.Left];
|
|
25
25
|
resultData = new Map;
|
|
26
|
+
componentCtxLinks = new Map;
|
|
26
27
|
pinTypesList = [
|
|
27
28
|
PinTypes.Any,
|
|
28
29
|
PinTypes.Input,
|
|
@@ -564,6 +565,27 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
564
565
|
getResult(ctx) {
|
|
565
566
|
return this.resultData.get(ctx);
|
|
566
567
|
}
|
|
568
|
+
linkComponentToCtx(ctx, instance, creationFlag = true) {
|
|
569
|
+
const scope = this.getScope();
|
|
570
|
+
const indexedStack = [];
|
|
571
|
+
if (scope.breakStack.length > 0) {
|
|
572
|
+
const executor = this.getExecutor();
|
|
573
|
+
scope.breakStack.forEach(stackCtx => {
|
|
574
|
+
const entry = executor.indexedStack.get(stackCtx);
|
|
575
|
+
const { index } = entry;
|
|
576
|
+
indexedStack.push([stackCtx, index]);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
instance.ctxReferences.push({
|
|
580
|
+
ctx,
|
|
581
|
+
indexedStack,
|
|
582
|
+
creationFlag
|
|
583
|
+
});
|
|
584
|
+
this.componentCtxLinks.set(ctx, instance);
|
|
585
|
+
}
|
|
586
|
+
getComponentCtxLinks() {
|
|
587
|
+
return this.componentCtxLinks;
|
|
588
|
+
}
|
|
567
589
|
visitResult(ctx) {
|
|
568
590
|
this.visit(ctx);
|
|
569
591
|
return this.getResult(ctx);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ComponentRefDesPrefixes } from './visitor.js';
|
|
2
|
+
export class ComponentAnnotater {
|
|
3
|
+
counter = {};
|
|
4
|
+
indexedContextPrefix = new Map();
|
|
5
|
+
existingRefDes = [];
|
|
6
|
+
constructor() {
|
|
7
|
+
for (const key in ComponentRefDesPrefixes) {
|
|
8
|
+
this.counter[key] = 1;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
getAnnotation(instance) {
|
|
12
|
+
const type = instance.typeProp ?? 'conn';
|
|
13
|
+
if (this.counter[type] === undefined && type.length <= 2) {
|
|
14
|
+
for (const [, value] of Object.entries(ComponentRefDesPrefixes)) {
|
|
15
|
+
if (value === type) {
|
|
16
|
+
throw "Refdes prefix is already in use!";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
20
|
+
ComponentRefDesPrefixes[type] = type;
|
|
21
|
+
this.counter[type] = 1;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
let prefix = '';
|
|
28
|
+
let resultRefdes = '';
|
|
29
|
+
const { ctxReferences } = instance;
|
|
30
|
+
if (ctxReferences.length > 0) {
|
|
31
|
+
const firstReference = ctxReferences[0];
|
|
32
|
+
const { ctx: useCtx, indexedStack, creationFlag } = firstReference;
|
|
33
|
+
if (indexedStack.length > 0 && creationFlag) {
|
|
34
|
+
const indexes = indexedStack.map(item => {
|
|
35
|
+
return item[1] + 1;
|
|
36
|
+
});
|
|
37
|
+
if (!this.indexedContextPrefix.has(useCtx)) {
|
|
38
|
+
if (instance.placeHolderRefDes) {
|
|
39
|
+
prefix = instance.placeHolderRefDes.replaceAll('_', '');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const { index: nextIndex, proposedName } = this.getNextRefdesCounter(ComponentRefDesPrefixes[type], this.counter[type]);
|
|
43
|
+
this.counter[type] = nextIndex;
|
|
44
|
+
prefix = proposedName;
|
|
45
|
+
}
|
|
46
|
+
this.existingRefDes.push(prefix);
|
|
47
|
+
this.indexedContextPrefix.set(useCtx, prefix);
|
|
48
|
+
}
|
|
49
|
+
const prefixParts = [this.indexedContextPrefix.get(useCtx), ...indexes];
|
|
50
|
+
resultRefdes = prefixParts.join('_');
|
|
51
|
+
if (this.existingRefDes.indexOf(resultRefdes) !== -1) {
|
|
52
|
+
console.log('Warning: Refdes already used:', resultRefdes);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const refdesCounter = this.getNextRefdesCounter(ComponentRefDesPrefixes[type], this.counter[type]);
|
|
57
|
+
this.counter[type] = refdesCounter.index;
|
|
58
|
+
resultRefdes = refdesCounter.proposedName;
|
|
59
|
+
}
|
|
60
|
+
this.existingRefDes.push(resultRefdes);
|
|
61
|
+
return resultRefdes;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
getNextRefdesCounter(prefix, startingIndex) {
|
|
65
|
+
let attempts = 100;
|
|
66
|
+
let proposedName = "";
|
|
67
|
+
let index = startingIndex;
|
|
68
|
+
while (attempts >= 0) {
|
|
69
|
+
proposedName = prefix + index;
|
|
70
|
+
index++;
|
|
71
|
+
if (this.existingRefDes.indexOf(proposedName) === -1) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
attempts--;
|
|
75
|
+
}
|
|
76
|
+
if (attempts === 0) {
|
|
77
|
+
throw "Annotation failed";
|
|
78
|
+
}
|
|
79
|
+
return { index, proposedName };
|
|
80
|
+
}
|
|
81
|
+
trackRefDes(name) {
|
|
82
|
+
this.existingRefDes.push(name);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { CircuitScriptParser } from './antlr/CircuitScriptParser.js';
|
|
2
|
+
import { BaseVisitor } from './BaseVisitor.js';
|
|
3
|
+
export class RefdesAnnotationVisitor extends BaseVisitor {
|
|
4
|
+
sourceText;
|
|
5
|
+
tokenStream;
|
|
6
|
+
modifications = new Map();
|
|
7
|
+
resultText = '';
|
|
8
|
+
debug = false;
|
|
9
|
+
componentCtxLinks;
|
|
10
|
+
constructor(silent, sourceText, tokenStream, componentCtxLinks) {
|
|
11
|
+
super(true);
|
|
12
|
+
this.sourceText = sourceText;
|
|
13
|
+
this.tokenStream = tokenStream;
|
|
14
|
+
this.componentCtxLinks = componentCtxLinks;
|
|
15
|
+
}
|
|
16
|
+
getOriginalText(ctx) {
|
|
17
|
+
if (!ctx.start || !ctx.stop) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
const startIndex = ctx.start.start;
|
|
21
|
+
const stopIndex = ctx.stop.stop;
|
|
22
|
+
return this.sourceText.substring(startIndex, stopIndex + 1);
|
|
23
|
+
}
|
|
24
|
+
visitScript = async (ctx) => {
|
|
25
|
+
const result = this.runExpressions(this.getExecutor(), ctx.expression());
|
|
26
|
+
this.setResult(ctx, result);
|
|
27
|
+
this.getExecutor().closeOpenPathBlocks();
|
|
28
|
+
this.resultText = this.generateModifiedText();
|
|
29
|
+
};
|
|
30
|
+
visitAdd_component_expr = (ctx) => {
|
|
31
|
+
this.addRefdesAnnotationComment(ctx);
|
|
32
|
+
};
|
|
33
|
+
visitAt_component_expr = (ctx) => {
|
|
34
|
+
this.addRefdesAnnotationComment(ctx);
|
|
35
|
+
};
|
|
36
|
+
visitComponent_select_expr = (ctx) => {
|
|
37
|
+
this.addRefdesAnnotationComment(ctx);
|
|
38
|
+
};
|
|
39
|
+
visitAt_block_header = (ctx) => {
|
|
40
|
+
this.addRefdesAnnotationComment(ctx);
|
|
41
|
+
};
|
|
42
|
+
visitAt_block = (ctx) => {
|
|
43
|
+
this.visit(ctx.at_block_header());
|
|
44
|
+
ctx.at_block_expressions().forEach(expression => {
|
|
45
|
+
this.visit(expression);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
visitTo_component_expr = (ctx) => {
|
|
49
|
+
const allRefdes = [];
|
|
50
|
+
ctx.component_select_expr().forEach(itemCtx => {
|
|
51
|
+
const tmpRefdes = this.generateRefdesAnnotationComment(itemCtx);
|
|
52
|
+
if (tmpRefdes !== null) {
|
|
53
|
+
allRefdes.push(tmpRefdes);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
if (allRefdes.length > 0) {
|
|
57
|
+
const originalText = this.getOriginalText(ctx);
|
|
58
|
+
const annotation = ' #= ' + allRefdes.join(',');
|
|
59
|
+
this.modifications.set(ctx, originalText + annotation);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
visitFunction_def_expr = (ctx) => {
|
|
63
|
+
this.runExpressions(this.getExecutor(), ctx.function_expr());
|
|
64
|
+
};
|
|
65
|
+
visitFunction_return_expr = (ctx) => {
|
|
66
|
+
};
|
|
67
|
+
visitFrame_expr = (ctx) => {
|
|
68
|
+
this.visit(ctx.expressions_block());
|
|
69
|
+
};
|
|
70
|
+
visitFunction_call_expr = (ctx) => {
|
|
71
|
+
};
|
|
72
|
+
visitParameters = (ctx) => {
|
|
73
|
+
};
|
|
74
|
+
addedRefdesAnnotations = [];
|
|
75
|
+
generateRefdesAnnotationComment(ctx) {
|
|
76
|
+
if (this.componentCtxLinks.has(ctx)) {
|
|
77
|
+
const instance = this.componentCtxLinks.get(ctx);
|
|
78
|
+
const alreadyHaveRefdesAnnotation = instance.assignedRefDes !== null ?
|
|
79
|
+
(this.addedRefdesAnnotations.indexOf(instance.assignedRefDes) !== -1) : false;
|
|
80
|
+
if (!instance.hasParam('refdes')
|
|
81
|
+
&& instance.placeHolderRefDes === null
|
|
82
|
+
&& instance.assignedRefDes
|
|
83
|
+
&& !alreadyHaveRefdesAnnotation) {
|
|
84
|
+
let useRefDes = instance.assignedRefDes;
|
|
85
|
+
let isPlaceholderRefdes = false;
|
|
86
|
+
const { ctxReferences } = instance;
|
|
87
|
+
if (ctxReferences.length > 0) {
|
|
88
|
+
const firstReference = ctxReferences[0];
|
|
89
|
+
const { indexedStack: loopStack = [] } = firstReference;
|
|
90
|
+
if (loopStack.length > 0) {
|
|
91
|
+
isPlaceholderRefdes = true;
|
|
92
|
+
const parts = instance.assignedRefDes.split('_');
|
|
93
|
+
useRefDes = parts[0] + '_';
|
|
94
|
+
}
|
|
95
|
+
if (this.addedRefdesAnnotations.indexOf(instance.assignedRefDes) === -1
|
|
96
|
+
&& !isPlaceholderRefdes) {
|
|
97
|
+
this.addedRefdesAnnotations.push(instance.assignedRefDes);
|
|
98
|
+
}
|
|
99
|
+
return useRefDes;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
addRefdesAnnotationComment(ctx) {
|
|
106
|
+
const refdes = this.generateRefdesAnnotationComment(ctx);
|
|
107
|
+
if (refdes !== null) {
|
|
108
|
+
const originalText = this.getOriginalText(ctx);
|
|
109
|
+
const annotation = ' #= ' + refdes;
|
|
110
|
+
this.modifications.set(ctx, originalText + annotation);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
getOutput() {
|
|
114
|
+
return this.resultText;
|
|
115
|
+
}
|
|
116
|
+
generateModifiedText() {
|
|
117
|
+
const output = [];
|
|
118
|
+
const allTokens = this.tokenStream.getTokens();
|
|
119
|
+
const processedTokens = new Set();
|
|
120
|
+
let lastSourcePos = 0;
|
|
121
|
+
const contextTokenRanges = this.buildContextTokenRanges();
|
|
122
|
+
for (let i = 0; i < allTokens.length; i++) {
|
|
123
|
+
const token = allTokens[i];
|
|
124
|
+
if (processedTokens.has(i)) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const tokenText = this.sourceText.substring(token.start, token.stop + 1);
|
|
128
|
+
this.log(i, `token: [${tokenText}], length: ${tokenText.length}, text: [${token.text}]`);
|
|
129
|
+
if (token.type === CircuitScriptParser.DEDENT
|
|
130
|
+
|| token.type === CircuitScriptParser.EOF
|
|
131
|
+
|| (token.type === CircuitScriptParser.NEWLINE && token.__skip)) {
|
|
132
|
+
this.log('--skip dedent/EOF token');
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const ctx = this.findContextForToken(token, contextTokenRanges);
|
|
136
|
+
if (ctx) {
|
|
137
|
+
const isFirstTokenInContext = token.tokenIndex === ctx.start?.tokenIndex;
|
|
138
|
+
if (isFirstTokenInContext) {
|
|
139
|
+
if (token.start > lastSourcePos) {
|
|
140
|
+
output.push(this.sourceText.substring(lastSourcePos, token.start));
|
|
141
|
+
}
|
|
142
|
+
if (this.modifications.has(ctx)) {
|
|
143
|
+
output.push(this.modifications.get(ctx));
|
|
144
|
+
this.markTokensAsProcessed(ctx, processedTokens);
|
|
145
|
+
if (ctx.stop) {
|
|
146
|
+
lastSourcePos = ctx.stop.stop + 1;
|
|
147
|
+
}
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (token.start > lastSourcePos) {
|
|
153
|
+
output.push(this.sourceText.substring(lastSourcePos, token.start));
|
|
154
|
+
}
|
|
155
|
+
if (tokenText.length > 0) {
|
|
156
|
+
output.push(tokenText);
|
|
157
|
+
}
|
|
158
|
+
processedTokens.add(i);
|
|
159
|
+
lastSourcePos = token.stop + 1;
|
|
160
|
+
}
|
|
161
|
+
if (lastSourcePos < this.sourceText.length) {
|
|
162
|
+
output.push(this.sourceText.substring(lastSourcePos));
|
|
163
|
+
}
|
|
164
|
+
return output.join('');
|
|
165
|
+
}
|
|
166
|
+
buildContextTokenRanges() {
|
|
167
|
+
const ranges = new Map();
|
|
168
|
+
for (const ctx of this.modifications.keys()) {
|
|
169
|
+
if (ctx.start && ctx.stop) {
|
|
170
|
+
ranges.set(ctx, [ctx.start.tokenIndex, ctx.stop.tokenIndex]);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return ranges;
|
|
174
|
+
}
|
|
175
|
+
findContextForToken(token, contextRanges) {
|
|
176
|
+
for (const [ctx, [start, end]] of contextRanges) {
|
|
177
|
+
if (token.tokenIndex >= start && token.tokenIndex <= end) {
|
|
178
|
+
return ctx;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
markTokensAsProcessed(ctx, processedTokens) {
|
|
184
|
+
if (!ctx.start || !ctx.stop) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
for (let i = ctx.start.tokenIndex; i <= ctx.stop.tokenIndex; i++) {
|
|
188
|
+
processedTokens.add(i);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
log(...message) {
|
|
192
|
+
if (this.debug) {
|
|
193
|
+
console.log(...message);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|