circuitscript 0.1.19 → 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.
Files changed (50) 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 +964 -831
  6. package/dist/cjs/environment.js +15 -1
  7. package/dist/cjs/execute.js +45 -2
  8. package/dist/cjs/graph.js +23 -2
  9. package/dist/cjs/helpers.js +21 -4
  10. package/dist/cjs/layout.js +3 -0
  11. package/dist/cjs/lexer.js +21 -9
  12. package/dist/cjs/main.js +13 -0
  13. package/dist/cjs/objects/ClassComponent.js +4 -1
  14. package/dist/cjs/objects/ExecutionScope.js +1 -0
  15. package/dist/cjs/parser.js +1 -0
  16. package/dist/cjs/visitor.js +119 -71
  17. package/dist/esm/BaseVisitor.js +22 -0
  18. package/dist/esm/ComponentAnnotater.js +84 -0
  19. package/dist/esm/RefdesAnnotationVisitor.js +196 -0
  20. package/dist/esm/antlr/CircuitScriptLexer.js +202 -197
  21. package/dist/esm/antlr/CircuitScriptParser.js +960 -829
  22. package/dist/esm/antlr/CircuitScriptVisitor.js +2 -0
  23. package/dist/esm/environment.js +15 -1
  24. package/dist/esm/execute.js +45 -2
  25. package/dist/esm/graph.js +23 -2
  26. package/dist/esm/helpers.js +21 -4
  27. package/dist/esm/layout.js +4 -0
  28. package/dist/esm/lexer.js +21 -9
  29. package/dist/esm/main.js +13 -0
  30. package/dist/esm/objects/ClassComponent.js +4 -1
  31. package/dist/esm/objects/ExecutionScope.js +1 -0
  32. package/dist/esm/parser.js +1 -0
  33. package/dist/esm/visitor.js +117 -69
  34. package/dist/types/BaseVisitor.d.ts +3 -0
  35. package/dist/types/ComponentAnnotater.d.ts +16 -0
  36. package/dist/types/RefdesAnnotationVisitor.d.ts +35 -0
  37. package/dist/types/antlr/CircuitScriptLexer.d.ts +15 -14
  38. package/dist/types/antlr/CircuitScriptParser.d.ts +80 -60
  39. package/dist/types/antlr/CircuitScriptVisitor.d.ts +4 -0
  40. package/dist/types/environment.d.ts +1 -0
  41. package/dist/types/execute.d.ts +8 -1
  42. package/dist/types/helpers.d.ts +6 -3
  43. package/dist/types/layout.d.ts +2 -0
  44. package/dist/types/lexer.d.ts +1 -1
  45. package/dist/types/objects/ClassComponent.d.ts +9 -0
  46. package/dist/types/objects/ExecutionScope.d.ts +2 -1
  47. package/dist/types/objects/types.d.ts +1 -0
  48. package/dist/types/parser.d.ts +2 -1
  49. package/dist/types/visitor.d.ts +8 -1
  50. package/package.json +1 -1
@@ -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
- return globals_js_1.TOOL_VERSION;
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) {
@@ -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.parameters.set(paramName, value);
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/graph.js CHANGED
@@ -51,6 +51,7 @@ class NetGraph {
51
51
  const baseFrame = new layout_js_1.RenderFrame(new Frame_js_1.Frame(Frame_js_1.FixedFrameIds.BaseFrame));
52
52
  const frameStack = [baseFrame];
53
53
  const containerFrames = [baseFrame];
54
+ const nodeFrames = new Map();
54
55
  sequence.forEach((sequenceStep, index) => {
55
56
  const action = sequenceStep[0];
56
57
  let tmpComponent;
@@ -60,6 +61,10 @@ class NetGraph {
60
61
  this.print(...sequenceStep);
61
62
  const [, component, pin] = sequenceStep;
62
63
  const tmpInstanceName = component.instanceName;
64
+ if (action === ExecutionScope_js_1.SequenceAction.At) {
65
+ previousNode = null;
66
+ previousPin = null;
67
+ }
63
68
  if (!graph.hasNode(tmpInstanceName)) {
64
69
  this.print('create instance', tmpInstanceName);
65
70
  const { displayProp = null } = component;
@@ -83,8 +88,15 @@ class NetGraph {
83
88
  tmpComponent = new layout_js_1.RenderComponent(component, useWidth, useHeight);
84
89
  tmpComponent.symbol = tmpSymbol;
85
90
  graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, index]);
86
- const currentFrame = frameStack[frameStack.length - 1];
87
- currentFrame && currentFrame.innerItems.push(tmpComponent);
91
+ let useFrame = frameStack[frameStack.length - 1];
92
+ if (nodeFrames.has(previousNode)) {
93
+ const previousNodeFrame = nodeFrames.get(previousNode);
94
+ if (previousNodeFrame !== useFrame) {
95
+ useFrame = previousNodeFrame;
96
+ }
97
+ }
98
+ useFrame && useFrame.innerItems.push(tmpComponent);
99
+ nodeFrames.set(tmpInstanceName, useFrame);
88
100
  }
89
101
  if (action === ExecutionScope_js_1.SequenceAction.To && previousNode && previousPin) {
90
102
  this.setGraphEdge(graph, previousNode, tmpInstanceName, makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, index));
@@ -116,6 +128,7 @@ class NetGraph {
116
128
  wire.netName = useNet.toString();
117
129
  const wireName = getWireName(wire.id);
118
130
  graph.setNode(wireName, [RenderItemType.Wire, wire, index]);
131
+ let tmpPreviousNode = previousNode;
119
132
  this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, index));
120
133
  previousNode = wireName;
121
134
  previousPin = 1;
@@ -132,6 +145,14 @@ class NetGraph {
132
145
  }
133
146
  return tmp;
134
147
  });
148
+ let useFrame = frameStack[frameStack.length - 1];
149
+ if (nodeFrames.has(tmpPreviousNode)) {
150
+ const previousNodeFrame = nodeFrames.get(tmpPreviousNode);
151
+ if (previousNodeFrame !== useFrame) {
152
+ useFrame = previousNodeFrame;
153
+ }
154
+ }
155
+ nodeFrames.set(wireName, useFrame);
135
156
  this.print(ExecutionScope_js_1.SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
136
157
  break;
137
158
  }
@@ -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,22 @@ 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
+ (0, fs_1.writeFileSync)(usePath, refdesVisitor.getOutput());
238
+ }
222
239
  if (dumpNets) {
223
240
  const nets = visitor.dumpNets();
224
241
  nets.forEach(item => console.log(item.join(" | ")));
@@ -343,9 +360,9 @@ exports.ParseOutputHandler = ParseOutputHandler;
343
360
  class KiCadNetListOutputHandler extends ParseOutputHandler {
344
361
  constructor() {
345
362
  super(...arguments);
346
- this.beforeRender = true;
363
+ this.afterRender = true;
347
364
  }
348
- parse(visitor, outputPath, fileExtension) {
365
+ parse(visitor, outputPath, fileExtension, extra = null) {
349
366
  if (outputPath !== null && fileExtension === "net") {
350
367
  const { tree: kiCadNetList, missingFootprints } = (0, export_js_1.generateKiCadNetList)(visitor.getNetList());
351
368
  missingFootprints.forEach(entry => {
@@ -1241,6 +1241,8 @@ class RenderFrame extends RenderObject {
1241
1241
  this.containsTitle = false;
1242
1242
  this.frame = frame;
1243
1243
  this.renderType = type;
1244
+ this.frameId = RenderFrame.FrameIdCounter;
1245
+ RenderFrame.FrameIdCounter++;
1244
1246
  }
1245
1247
  toString() {
1246
1248
  let name = "";
@@ -1255,6 +1257,7 @@ class RenderFrame extends RenderObject {
1255
1257
  }
1256
1258
  }
1257
1259
  exports.RenderFrame = RenderFrame;
1260
+ RenderFrame.FrameIdCounter = 0;
1258
1261
  var RenderFrameType;
1259
1262
  (function (RenderFrameType) {
1260
1263
  RenderFrameType[RenderFrameType["Container"] = 1] = "Container";
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.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, "\n"));
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, "<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
- const stop = this.getCharIndex() - 1;
47
- const start = text.length ? stop - text.length + 1 : stop;
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 = "indent";
55
+ tokenTypeString = 'indent';
52
56
  }
53
57
  else if (type === CircuitScriptParser_js_1.CircuitScriptParser.DEDENT) {
54
- tokenTypeString = "dedent";
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.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, newLine));
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() {
@@ -9,6 +9,7 @@ class ExecutionScope {
9
9
  this.nets = [];
10
10
  this.instances = new Map();
11
11
  this.functions = new Map();
12
+ this.functionCounter = new Map();
12
13
  this.variables = new Map();
13
14
  this.symbols = new Map();
14
15
  this.blockStack = new Map();
@@ -38,6 +38,7 @@ async function parseFileWithVisitor(visitor, data) {
38
38
  const parserTimeTaken = parserTimer.lap();
39
39
  return {
40
40
  tree, parser,
41
+ tokens,
41
42
  hasParseError: false,
42
43
  hasError: false,
43
44
  parserTimeTaken,