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.
Files changed (45) hide show
  1. package/dist/cjs/BaseVisitor.js +22 -0
  2. package/dist/cjs/ComponentAnnotater.js +88 -0
  3. package/dist/cjs/RefdesAnnotationVisitor.js +197 -0
  4. package/dist/cjs/antlr/CircuitScriptLexer.js +202 -197
  5. package/dist/cjs/antlr/CircuitScriptParser.js +975 -833
  6. package/dist/cjs/environment.js +15 -1
  7. package/dist/cjs/execute.js +45 -2
  8. package/dist/cjs/helpers.js +20 -2
  9. package/dist/cjs/lexer.js +21 -9
  10. package/dist/cjs/main.js +13 -0
  11. package/dist/cjs/objects/ClassComponent.js +4 -1
  12. package/dist/cjs/objects/ExecutionScope.js +1 -0
  13. package/dist/cjs/parser.js +1 -0
  14. package/dist/cjs/visitor.js +122 -71
  15. package/dist/esm/BaseVisitor.js +22 -0
  16. package/dist/esm/ComponentAnnotater.js +84 -0
  17. package/dist/esm/RefdesAnnotationVisitor.js +196 -0
  18. package/dist/esm/antlr/CircuitScriptLexer.js +202 -197
  19. package/dist/esm/antlr/CircuitScriptParser.js +971 -831
  20. package/dist/esm/antlr/CircuitScriptVisitor.js +2 -0
  21. package/dist/esm/environment.js +15 -1
  22. package/dist/esm/execute.js +45 -2
  23. package/dist/esm/helpers.js +20 -2
  24. package/dist/esm/lexer.js +21 -9
  25. package/dist/esm/main.js +13 -0
  26. package/dist/esm/objects/ClassComponent.js +4 -1
  27. package/dist/esm/objects/ExecutionScope.js +1 -0
  28. package/dist/esm/parser.js +1 -0
  29. package/dist/esm/visitor.js +120 -69
  30. package/dist/types/BaseVisitor.d.ts +3 -0
  31. package/dist/types/ComponentAnnotater.d.ts +16 -0
  32. package/dist/types/RefdesAnnotationVisitor.d.ts +35 -0
  33. package/dist/types/antlr/CircuitScriptLexer.d.ts +15 -14
  34. package/dist/types/antlr/CircuitScriptParser.d.ts +81 -60
  35. package/dist/types/antlr/CircuitScriptVisitor.d.ts +4 -0
  36. package/dist/types/environment.d.ts +1 -0
  37. package/dist/types/execute.d.ts +8 -1
  38. package/dist/types/helpers.d.ts +4 -1
  39. package/dist/types/lexer.d.ts +1 -1
  40. package/dist/types/objects/ClassComponent.d.ts +9 -0
  41. package/dist/types/objects/ExecutionScope.d.ts +2 -1
  42. package/dist/types/objects/types.d.ts +1 -0
  43. package/dist/types/parser.d.ts +2 -1
  44. package/dist/types/visitor.d.ts +8 -1
  45. package/package.json +1 -1
@@ -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
+ }