circuitscript 0.0.21 → 0.0.24

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 (163) hide show
  1. package/dist/cjs/antlr/CircuitScriptLexer.js +288 -0
  2. package/dist/cjs/antlr/CircuitScriptParser.js +4905 -0
  3. package/dist/cjs/antlr/CircuitScriptVisitor.js +6 -0
  4. package/{src/draw_symbols.ts → dist/cjs/draw_symbols.js} +303 -614
  5. package/dist/cjs/execute.js +780 -0
  6. package/{src/export.ts → dist/cjs/export.js} +34 -56
  7. package/dist/cjs/fonts.js +4 -0
  8. package/dist/cjs/geometry.js +430 -0
  9. package/dist/cjs/globals.js +60 -0
  10. package/dist/cjs/helpers.js +99 -0
  11. package/dist/cjs/index.js +29 -0
  12. package/{src/layout.ts → dist/cjs/layout.js} +413 -1002
  13. package/dist/cjs/lexer.js +114 -0
  14. package/dist/cjs/logger.js +17 -0
  15. package/dist/cjs/main.js +87 -0
  16. package/dist/cjs/objects/ClassComponent.js +142 -0
  17. package/dist/cjs/objects/ExecutionScope.js +134 -0
  18. package/dist/cjs/objects/Frame.js +22 -0
  19. package/{src/objects/Net.ts → dist/cjs/objects/Net.js} +9 -24
  20. package/dist/cjs/objects/ParamDefinition.js +42 -0
  21. package/dist/cjs/objects/PinDefinition.js +31 -0
  22. package/dist/cjs/objects/PinTypes.js +11 -0
  23. package/dist/cjs/objects/Wire.js +9 -0
  24. package/dist/cjs/objects/types.js +9 -0
  25. package/dist/cjs/parser.js +299 -0
  26. package/dist/cjs/regenerate-tests.js +23 -0
  27. package/dist/cjs/render.js +155 -0
  28. package/{src/server.ts → dist/cjs/server.js} +15 -21
  29. package/dist/cjs/sizing.js +105 -0
  30. package/{src/utils.ts → dist/cjs/utils.js} +25 -35
  31. package/{src/visitor.ts → dist/cjs/visitor.js} +392 -948
  32. package/{build/src/antlr/CircuitScriptLexer.js → dist/esm/antlr/CircuitScriptLexer.mjs} +90 -91
  33. package/{build/src/antlr/CircuitScriptParser.js → dist/esm/antlr/CircuitScriptParser.mjs} +138 -136
  34. package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +11 -11
  35. package/{build/src/execute.js → dist/esm/execute.mjs} +9 -8
  36. package/{build/src/export.js → dist/esm/export.mjs} +2 -2
  37. package/{build/src/geometry.js → dist/esm/geometry.mjs} +3 -7
  38. package/{build/src/helpers.js → dist/esm/helpers.mjs} +27 -7
  39. package/dist/esm/index.mjs +13 -0
  40. package/{build/src/layout.js → dist/esm/layout.mjs} +11 -11
  41. package/{build/src/lexer.js → dist/esm/lexer.mjs} +2 -2
  42. package/{build/src/main.js → dist/esm/main.mjs} +5 -5
  43. package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +3 -3
  44. package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
  45. package/dist/esm/parser.mjs +269 -0
  46. package/{build/src/regenerate-tests.js → dist/esm/regenerate-tests.mjs} +1 -1
  47. package/{build/src/render.js → dist/esm/render.mjs} +7 -24
  48. package/{build/src/sizing.js → dist/esm/sizing.mjs} +22 -8
  49. package/{build/src/visitor.js → dist/esm/visitor.mjs} +10 -29
  50. package/dist/types/antlr/CircuitScriptLexer.d.ts +71 -0
  51. package/dist/types/antlr/CircuitScriptParser.d.ts +675 -0
  52. package/dist/types/antlr/CircuitScriptVisitor.d.ts +115 -0
  53. package/dist/types/draw_symbols.d.ts +162 -0
  54. package/dist/types/execute.d.ts +85 -0
  55. package/dist/types/export.d.ts +2 -0
  56. package/dist/types/fonts.d.ts +1 -0
  57. package/dist/types/geometry.d.ts +84 -0
  58. package/dist/types/globals.d.ts +50 -0
  59. package/dist/types/helpers.d.ts +9 -0
  60. package/dist/types/index.d.ts +13 -0
  61. package/dist/types/layout.d.ts +147 -0
  62. package/dist/types/lexer.d.ts +19 -0
  63. package/dist/types/logger.d.ts +6 -0
  64. package/dist/types/main.d.ts +2 -0
  65. package/dist/types/objects/ClassComponent.d.ts +40 -0
  66. package/dist/types/objects/ExecutionScope.d.ts +64 -0
  67. package/dist/types/objects/Frame.d.ts +15 -0
  68. package/dist/types/objects/Net.d.ts +10 -0
  69. package/dist/types/objects/ParamDefinition.d.ts +20 -0
  70. package/dist/types/objects/PinDefinition.d.ts +24 -0
  71. package/dist/types/objects/PinTypes.d.ts +7 -0
  72. package/dist/types/objects/Wire.d.ts +11 -0
  73. package/dist/types/objects/types.d.ts +49 -0
  74. package/dist/types/parser.d.ts +38 -0
  75. package/dist/types/regenerate-tests.d.ts +1 -0
  76. package/dist/types/render.d.ts +10 -0
  77. package/dist/types/server.d.ts +1 -0
  78. package/dist/types/sizing.d.ts +15 -0
  79. package/dist/types/utils.d.ts +19 -0
  80. package/dist/types/visitor.d.ts +135 -0
  81. package/package.json +30 -12
  82. package/.editorconfig +0 -15
  83. package/.eslintignore +0 -1
  84. package/.eslintrc.json +0 -27
  85. package/.gitlab-ci.yml +0 -81
  86. package/.prettierignore +0 -8
  87. package/.prettierrc +0 -16
  88. package/__tests__/expectedResults.ts +0 -657
  89. package/__tests__/helpers.ts +0 -82
  90. package/__tests__/parseScripts.ts +0 -593
  91. package/__tests__/renderData/script1.cst +0 -58
  92. package/__tests__/renderData/script1.cst.svg +0 -1
  93. package/__tests__/renderData/script2.cst +0 -16
  94. package/__tests__/renderData/script2.cst.svg +0 -1
  95. package/__tests__/renderData/script3.cst +0 -30
  96. package/__tests__/renderData/script3.cst.svg +0 -1
  97. package/__tests__/renderData/script4.cst +0 -54
  98. package/__tests__/renderData/script4.cst.svg +0 -1
  99. package/__tests__/renderData/script5.cst +0 -23
  100. package/__tests__/renderData/script5.cst.svg +0 -1
  101. package/__tests__/renderData/script6.cst +0 -28
  102. package/__tests__/renderData/script6.cst.svg +0 -1
  103. package/__tests__/renderData/script7.cst +0 -26
  104. package/__tests__/renderData/script7.cst.svg +0 -1
  105. package/__tests__/renderData/script8.cst +0 -37
  106. package/__tests__/renderData/script8.cst.svg +0 -1
  107. package/__tests__/testCLI.ts +0 -68
  108. package/__tests__/testMathOps.ts +0 -36
  109. package/__tests__/testMergeWires.ts +0 -141
  110. package/__tests__/testParse.ts +0 -263
  111. package/__tests__/testRender.ts +0 -38
  112. package/build/src/parser.js +0 -69
  113. package/documentation.md +0 -238
  114. package/examples/example_arduino_uno.cst +0 -1146
  115. package/examples/example_garden_pump.cst +0 -567
  116. package/examples/lib.cst +0 -185
  117. package/fonts/Inter-Bold.ttf +0 -0
  118. package/fonts/Inter-Regular.ttf +0 -0
  119. package/fonts/OpenSans-Regular.ttf +0 -0
  120. package/fonts/Roboto-Regular.ttf +0 -0
  121. package/jest.config.js +0 -23
  122. package/libs/lib.cst +0 -185
  123. package/refresh.html +0 -42
  124. package/server.cjs +0 -50
  125. package/src/antlr/CircuitScript.g4 +0 -209
  126. package/src/antlr/CircuitScriptLexer.ts +0 -317
  127. package/src/antlr/CircuitScriptParser.ts +0 -4979
  128. package/src/antlr/CircuitScriptVisitor.ts +0 -420
  129. package/src/execute.ts +0 -1227
  130. package/src/fonts.ts +0 -1
  131. package/src/geometry.ts +0 -638
  132. package/src/globals.ts +0 -67
  133. package/src/helpers.ts +0 -114
  134. package/src/lexer.ts +0 -151
  135. package/src/logger.ts +0 -17
  136. package/src/main.ts +0 -105
  137. package/src/objects/ClassComponent.ts +0 -223
  138. package/src/objects/ExecutionScope.ts +0 -201
  139. package/src/objects/Frame.ts +0 -20
  140. package/src/objects/ParamDefinition.ts +0 -49
  141. package/src/objects/PinDefinition.ts +0 -49
  142. package/src/objects/PinTypes.ts +0 -7
  143. package/src/objects/Wire.ts +0 -19
  144. package/src/objects/types.ts +0 -66
  145. package/src/parser.ts +0 -106
  146. package/src/regenerate-tests.ts +0 -25
  147. package/src/render.ts +0 -260
  148. package/src/sizing.ts +0 -96
  149. package/tsconfig.json +0 -26
  150. package/tsconfig.release.json +0 -8
  151. /package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +0 -0
  152. /package/{build/src/fonts.js → dist/esm/fonts.mjs} +0 -0
  153. /package/{build/src/globals.js → dist/esm/globals.mjs} +0 -0
  154. /package/{build/src/logger.js → dist/esm/logger.mjs} +0 -0
  155. /package/{build/src/objects/ExecutionScope.js → dist/esm/objects/ExecutionScope.mjs} +0 -0
  156. /package/{build/src/objects/Frame.js → dist/esm/objects/Frame.mjs} +0 -0
  157. /package/{build/src/objects/Net.js → dist/esm/objects/Net.mjs} +0 -0
  158. /package/{build/src/objects/ParamDefinition.js → dist/esm/objects/ParamDefinition.mjs} +0 -0
  159. /package/{build/src/objects/PinTypes.js → dist/esm/objects/PinTypes.mjs} +0 -0
  160. /package/{build/src/objects/Wire.js → dist/esm/objects/Wire.mjs} +0 -0
  161. /package/{build/src/objects/types.js → dist/esm/objects/types.mjs} +0 -0
  162. /package/{build/src/server.js → dist/esm/server.mjs} +0 -0
  163. /package/{build/src/utils.js → dist/esm/utils.mjs} +0 -0
package/src/helpers.ts DELETED
@@ -1,114 +0,0 @@
1
- import { writeFileSync } from "fs";
2
- import { generateKiCADNetList } from "./export.js";
3
- import { LayoutEngine } from "./layout.js";
4
- import { SequenceAction } from "./objects/ExecutionScope.js";
5
- import { parseFileWithVisitor } from "./parser.js";
6
- import { generateSVG2 } from "./render.js";
7
- import { SimpleStopwatch } from "./utils.js";
8
- import { MainVisitor } from "./visitor.js";
9
-
10
- export function renderScript(scriptData: string, outputPath: string, options): string {
11
-
12
- const {
13
- currentDirectory = null,
14
- defaultLibsPath,
15
- dumpNets = false,
16
- dumpData = false,
17
- kicadNetlistPath = null,
18
- showStats = false} = options;
19
-
20
- const visitor = new MainVisitor(true);
21
-
22
- visitor.onImportFile = visitor.createImportFileHandler(currentDirectory, defaultLibsPath);
23
-
24
- visitor.print('reading file');
25
- visitor.print('done reading file');
26
-
27
- const { tree, parser,
28
- hasParseError, hasError,
29
- parserTimeTaken,
30
- lexerTimeTaken } = parseFileWithVisitor(visitor, scriptData);
31
-
32
- showStats && console.log('Lexing took:', lexerTimeTaken);
33
- showStats && console.log('Parsing took:', parserTimeTaken);
34
- dumpNets && console.log(visitor.dumpNets());
35
-
36
- dumpData && writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
37
- dumpData && writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
38
-
39
- if (hasError || hasParseError) {
40
- console.log('Error while parsing');
41
- return null;
42
- }
43
-
44
- try {
45
- visitor.annotateComponents();
46
- } catch (err) {
47
- console.log('Error during annotation: ', err);
48
- }
49
-
50
- if (kicadNetlistPath) {
51
- const kicadNetList = generateKiCADNetList(visitor.getNetList());
52
- writeFileSync(kicadNetlistPath, kicadNetList);
53
- console.log('Generated KiCad netlist file');
54
- }
55
-
56
-
57
- // await writeFile('dump/raw-netlist.json', JSON.stringify(visitor.dump2(), null, 2));
58
-
59
- const { sequence, nets } = visitor.getGraph();
60
-
61
- // const tmpInstances = visitor.getExecutor().scope.instances;
62
- // for (const [instanceName, instance] of tmpInstances){
63
- // console.log(instanceName);
64
- // console.log(instance.pinNets);
65
- // }
66
-
67
-
68
- const tmpSequence = sequence.map(item => {
69
- const tmp = [...item];
70
-
71
- const action = tmp[0];
72
-
73
- if (action === SequenceAction.Wire) {
74
- tmp[2] = tmp[2].map(item2 => {
75
- return [item2.direction, item2.value].join(",");
76
- }).join(" ");
77
- } else if (action === SequenceAction.Frame) {
78
- tmp[1] = item[1].frameId;
79
-
80
- } else if (action !== SequenceAction.WireJump) {
81
- tmp[1] = item[1].instanceName;
82
- }
83
-
84
- return tmp.join(" | ");
85
- });
86
-
87
- dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
88
- let svgOutput: string = null;
89
-
90
- try {
91
- const layoutEngine = new LayoutEngine();
92
- const layoutTimer = new SimpleStopwatch();
93
-
94
- const graph = layoutEngine.runLayout(sequence, nets);
95
-
96
- layoutEngine.printWarnings();
97
-
98
- showStats && console.log('Layout took:', layoutTimer.lap());
99
-
100
- dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
101
-
102
- const generateSvgTimer = new SimpleStopwatch();
103
- svgOutput = generateSVG2(graph);
104
- showStats && console.log('Render took:', generateSvgTimer.lap());
105
-
106
- if (outputPath) {
107
- writeFileSync(outputPath, svgOutput);
108
- }
109
- } catch (err) {
110
- console.log('Error during render: ', err);
111
- }
112
-
113
- return svgOutput;
114
- }
package/src/lexer.ts DELETED
@@ -1,151 +0,0 @@
1
- /**
2
- * Adapted from:
3
- * https://github.com/antlr/grammars-v4/blob/master/python/python3/TypeScript/Python3LexerBase.ts
4
- */
5
-
6
- import { CommonToken, CharStream, Token } from "antlr4";
7
- import CircuitScriptParser from "./antlr/CircuitScriptParser.js";
8
- import CircuitScriptLexer from "./antlr/CircuitScriptLexer.js";
9
-
10
- export class MainLexer extends CircuitScriptLexer {
11
-
12
- // A queue where extra tokens are pushed on (see the NEWLINE lexer rule).
13
- tokens: any[];
14
-
15
- // The stack that keeps track of the indentation level.
16
- indents: any[];
17
-
18
- // The amount of opened braces, brackets and parenthesis.
19
- opened: number;
20
-
21
- constructor(input: CharStream) {
22
- super(input);
23
- this.tokens = [];
24
- this.indents = [];
25
- this.opened = 0;
26
- }
27
-
28
- reset(): void {
29
- this.tokens = [];
30
- this.indents = [];
31
- this.opened = 0;
32
-
33
- super.reset();
34
- }
35
-
36
- emitToken(token: Token): void {
37
- super.emitToken(token);
38
- this.tokens.push(token);
39
- }
40
-
41
- nextToken(): Token {
42
- // Check if the end-of-file is ahead and there are still some DEDENTS expected.
43
- if (this._input.LA(1) === CircuitScriptParser.EOF && this.indents.length) {
44
- // Remove any trailing EOF tokens from our buffer.
45
- this.tokens = this.tokens.filter(function (val) {
46
- return val.type !== CircuitScriptParser.EOF;
47
- });
48
- // First emit an extra line break that serves as the end of the statement.
49
- this.emitToken(this.commonToken(CircuitScriptParser.NEWLINE, "\n"));
50
- // Now emit as much DEDENT tokens as needed.
51
- while (this.indents.length) {
52
- this.emitToken(this.createDedent());
53
- this.indents.pop();
54
- }
55
- // Put the EOF back on the token stream.
56
- this.emitToken(this.commonToken(CircuitScriptParser.EOF, "<EOF>"));
57
- }
58
- const next = super.nextToken();
59
- return this.tokens.length ? this.tokens.shift() : next;
60
- }
61
-
62
- createDedent(): Token {
63
- return this.commonToken(CircuitScriptParser.DEDENT, "");
64
- }
65
-
66
- getCharIndex(): number {
67
- return this._input.index;
68
- }
69
-
70
- commonToken(type: number, text: string): Token {
71
- const stop = this.getCharIndex() - 1;
72
- const start = text.length ? stop - text.length + 1 : stop;
73
- const token = new CommonToken([this, this._input], type, 0, start, stop);
74
-
75
- let tokenTypeString: string;
76
- if (type === CircuitScriptParser.INDENT) {
77
- tokenTypeString = "indent";
78
- } else if (type === CircuitScriptParser.DEDENT) {
79
- tokenTypeString = "dedent";
80
- }
81
-
82
- if (tokenTypeString) {
83
- token.text = tokenTypeString;
84
- }
85
-
86
- return token;
87
- }
88
-
89
- getIndentationCount(whitespace: string): number {
90
- let count = 0;
91
- for (let i = 0; i < whitespace.length; i++) {
92
- if (whitespace[i] === '\t') {
93
- count += 8 - count % 8;
94
- } else {
95
- count++;
96
- }
97
- }
98
- return count;
99
- }
100
-
101
- atStartOfInput(): boolean {
102
- return this.getCharIndex() === 0;
103
- }
104
-
105
- openBrace(): void {
106
- this.opened++;
107
- }
108
-
109
- closeBrace(): void {
110
- this.opened--;
111
- }
112
-
113
- onNewLine(): void {
114
- const newLine = this.text.replace(/[^\r\n]+/g, '');
115
- const spaces = this.text.replace(/[\r\n]+/g, '');
116
-
117
- // Strip newlines inside open clauses except if we are near EOF. We keep NEWLINEs near EOF to
118
- // satisfy the final newline needed by the single_put rule used by the REPL.
119
- const next = this._input.LA(1);
120
- const nextnext = this._input.LA(2);
121
-
122
- if (this.opened > 0 || (nextnext != -1 /* EOF */ &&
123
- (next === 13 /* '\r' */ || next === 10 /* '\n' */ || next === 35 /* '#' */))) {
124
-
125
- // If we're inside a list or on a blank line, ignore all indents,
126
- // dedents and line breaks.
127
- this.skip();
128
-
129
- } else {
130
- this.emitToken(this.commonToken(CircuitScriptParser.NEWLINE, newLine));
131
-
132
- const indent = this.getIndentationCount(spaces);
133
- const previous = this.indents.length ? this.indents[this.indents.length - 1] : 0;
134
-
135
- if (indent === previous) {
136
- // skip indents of the same size as the present indent-size
137
- this.skip();
138
- } else if (indent > previous) {
139
- this.indents.push(indent);
140
- this.emitToken(this.commonToken(CircuitScriptParser.INDENT, spaces));
141
- } else {
142
- // Possibly emit more than 1 DEDENT token.
143
- while (this.indents.length && this.indents[this.indents.length - 1] > indent) {
144
- this.emitToken(this.createDedent());
145
- this.indents.pop();
146
- }
147
- }
148
- }
149
- }
150
- }
151
-
package/src/logger.ts DELETED
@@ -1,17 +0,0 @@
1
- export class Logger {
2
-
3
- logs: string[] = [];
4
-
5
- constructor() {
6
- this.add((new Date()).toISOString());
7
- this.add('starting logger...');
8
- }
9
-
10
- add(message: string): void {
11
- this.logs.push((new Date()).toISOString()+" | " + message);
12
- }
13
-
14
- dump(): string {
15
- return this.logs.join('\n');
16
- }
17
- }
package/src/main.ts DELETED
@@ -1,105 +0,0 @@
1
- #! /usr/bin/env node
2
-
3
- import { program } from 'commander';
4
- import figlet from 'figlet';
5
- import path from 'path';
6
- import { fileURLToPath } from 'url';
7
- import { readFileSync, watch } from 'fs';
8
-
9
- import { prepareSizing } from './sizing.js';
10
- import { renderScript } from './helpers.js';
11
-
12
- export default async function main(): Promise<void> {
13
- const toolSrcPath = fileURLToPath(import.meta.url);
14
-
15
- const toolDirectory = path.dirname(toolSrcPath) + '/../../';
16
- const fontsPath = toolDirectory + '/fonts';
17
- const defaultLibsPath = toolDirectory + '/libs';
18
-
19
- const packageJson = JSON.parse(readFileSync(toolDirectory + 'package.json').toString());;
20
- const {version} = packageJson;
21
-
22
- program
23
- .description('generate graphical output from circuitscript files')
24
- .version(version)
25
- .option('-i, --input text <input text>', 'Input text directly')
26
- .option('-f, --input-file <path>', 'Input file')
27
- .option('-o, --output <path>', 'Output path')
28
- .option('-c, --current-directory <path>', 'Set current directory')
29
- .option('-k, --kicad-netlist <filename>', 'Create KiCad netlist')
30
- .option('-w, --watch', 'Watch for file changes')
31
- .option('-n, --dump-nets', 'Dump out net information')
32
- .option('-d, --dump-data', 'Dump data during parsing')
33
- .option('-s, --stats', 'Show stats during generation')
34
- ;
35
-
36
- program.addHelpText('before', figlet.textSync('circuitscript', {
37
- font: 'Small Slant'
38
- }));
39
-
40
- if (process.argv.length < 3){
41
- program.help();
42
- }
43
-
44
- program.parse();
45
-
46
- const options = program.opts();
47
-
48
- const watchFileChanges = options.watch;
49
- const outputPath = options.output ?? null;
50
- const dumpNets = options.dumpNets;
51
- const dumpData = options.dumpData;
52
- const kicadNetlist = options.kicadNetlist;
53
-
54
- let currentDirectory = options.currentDirectory ?? null;
55
-
56
- if (watchFileChanges) {
57
- console.log('watching for file changes...');
58
- }
59
-
60
- await prepareSizing(fontsPath);
61
-
62
- let inputFilePath: string = null;
63
-
64
- let scriptData: string;
65
- if (options.input) {
66
- scriptData = options.input;
67
- } else {
68
- inputFilePath = options.inputFile; // this should be provided
69
- scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
70
-
71
- if (currentDirectory === null) {
72
- currentDirectory = path.dirname(inputFilePath);
73
- }
74
- }
75
-
76
- const renderOptions = {
77
- currentDirectory,
78
- defaultLibsPath,
79
- dumpNets,
80
- dumpData,
81
- kicadNetlistPath: kicadNetlist,
82
- showStats: options.stats,
83
- }
84
-
85
- const output = renderScript(scriptData, outputPath,
86
- renderOptions);
87
-
88
- if (outputPath === null && output){
89
- console.log(output);
90
- }
91
-
92
- if (watchFileChanges) {
93
- watch(inputFilePath, event => {
94
- if (event === 'change') {
95
- const scriptData = readFileSync(inputFilePath,
96
- {encoding: 'utf-8'});
97
-
98
- renderScript(scriptData, outputPath, renderOptions);
99
- console.log('done');
100
- }
101
- });
102
- }
103
- }
104
-
105
- main();
@@ -1,223 +0,0 @@
1
- import { SymbolDrawingCommands } from '../draw_symbols.js';
2
- import { Net } from './Net.js';
3
- import { PinDefinition, PinIdType } from './PinDefinition.js';
4
- import { PinTypes } from './PinTypes.js';
5
- import { WireSegment } from './Wire.js';
6
-
7
- export class ClassComponent {
8
-
9
- // A component has an instance_name to identify it
10
- // num_pins: The maximum number of pins that are avaible from this component
11
- // Note: the pin number starts from 1
12
-
13
- instanceName: string;
14
- numPins: number;
15
-
16
- parameters: Map<string, number | string> = new Map();
17
-
18
- // Maps pin indexes to the pin definition
19
- pins: Map<number, PinDefinition> = new Map();
20
-
21
- // Maps pin indexes to the nets.
22
- pinNets: Map<number, Net> = new Map();
23
-
24
- pinWires: Map<number, WireSegment[]> = new Map();
25
-
26
- // The cached values are used for easier comparison/equality check.
27
- _cachedPins: string;
28
- _cachedParams: string;
29
-
30
- className: string;
31
-
32
- // For nets, labels and gnds, this can be used to identify different
33
- // copies of the same symbol on the schematic
34
- _copyID?: number = null;
35
- _copyFrom?: ClassComponent = null;
36
-
37
- // This determines how pins are arrange on the component/symbol.
38
- arrangeProps: Map<string, number[]> | null = null;
39
-
40
- // Used to identify what graphic to draw for this symbol
41
- displayProp: string | SymbolDrawingCommands | null = null;
42
-
43
- widthProp: number | null = null;
44
-
45
- typeProp: string | null = null;
46
-
47
- styles: { [key: string]: number | string } = {};
48
-
49
- assignedRefDes: string | null = null;
50
-
51
- constructor(instanceName: string, numPins: number, className: string) {
52
- this.instanceName = instanceName;
53
- this.numPins = numPins;
54
- this.className = className;
55
- }
56
-
57
- setupPins(): void {
58
- // Let pin index start from 1.
59
- for (let i = 1; i < this.numPins + 1; i++) {
60
- const pinIndex = i;
61
- this.pins.set(
62
- pinIndex,
63
- new PinDefinition(
64
- pinIndex,
65
- PinIdType.Int,
66
- pinIndex.toString(),
67
- PinTypes.Any,
68
- ),
69
- );
70
- }
71
-
72
- this.refreshPinsCache();
73
- }
74
-
75
- getDefaultPin(): number {
76
- // Return id of the default pin
77
- return 1;
78
- }
79
-
80
- hasPin(pinId: number | string): boolean {
81
- if (typeof pinId === 'number') {
82
- return this.pins.has(pinId);
83
- } else {
84
- // assume is string
85
- for (const [, pinDef] of this.pins) {
86
- if (
87
- pinDef.name === pinId ||
88
- pinDef.altNames.indexOf(pinId) !== -1
89
- ) {
90
- return true;
91
- }
92
- }
93
- }
94
-
95
- return false;
96
- }
97
-
98
- getPin(pinId: number | string): number {
99
- // Given a pinId, which is either a number of string,
100
- // this returns the pin index in the component.
101
- // If the pinId does not match, then a -1 is returned.
102
-
103
- if (typeof pinId === 'number') {
104
- return pinId;
105
- } else {
106
- // assume is string
107
- for (const [pin, pinDef] of this.pins) {
108
- if (
109
- pinDef.name === pinId ||
110
- pinDef.altNames.indexOf(pinId) !== -1
111
- ) {
112
- return pin;
113
- }
114
- }
115
-
116
- return -1;
117
- }
118
- }
119
-
120
- getNextPinAfter(pinIndex: number): number {
121
- if (pinIndex + 1 <= this.numPins) {
122
- return pinIndex + 1;
123
- } else {
124
- // No more next pin, so just wrap around.
125
- // Might not be the right behaviour...
126
- return 1;
127
- }
128
- }
129
-
130
- setParam(key: string, value: number | string): void {
131
- this.parameters.set(key, value);
132
- this.refreshParamCache();
133
- }
134
-
135
- private refreshParamCache(): void {
136
- this._cachedParams =
137
- JSON.stringify(Object.fromEntries(this.parameters));
138
- }
139
-
140
- private refreshPinsCache(): void {
141
- this._cachedPins = JSON.stringify(Object.fromEntries(this.pins));
142
- }
143
-
144
- refreshCache(): void {
145
- this.refreshParamCache();
146
- this.refreshPinsCache();
147
- }
148
-
149
- getParam(key: string): number | string {
150
- if (this.parameters.has(key)) {
151
- return this.parameters.get(key);
152
- } else {
153
- throw 'Invalid parameter key';
154
- }
155
- }
156
-
157
- toString(): string {
158
- return this.instanceName;
159
- }
160
-
161
- static simple(
162
- instanceName: string,
163
- numPins: number,
164
- className: string,
165
- ): ClassComponent {
166
- const component = new ClassComponent(instanceName, numPins, className);
167
- component.setupPins();
168
- return component;
169
- }
170
-
171
- isEqual(other: ClassComponent): boolean {
172
- // Use manual comparison as this is faster than lodash.
173
- // Make sure that all important props are added.
174
- return this.instanceName === other.instanceName
175
- && this.numPins === other.numPins
176
- && this.className === other.className
177
- && this._copyID === other._copyID
178
- && this.arrangeProps === other.arrangeProps
179
- && this.displayProp === other.displayProp
180
- && this.widthProp === other.widthProp
181
- && this.typeProp === other.typeProp
182
- && this._cachedPins === other._cachedPins
183
- && this._cachedParams === other._cachedParams;
184
- }
185
-
186
- clone(): ClassComponent {
187
- // returns new copy
188
- const component = new ClassComponent(
189
- this.instanceName, this.numPins, this.className);
190
-
191
- component._copyID = this._copyID;
192
- component.arrangeProps = this.arrangeProps;
193
- component.widthProp = this.widthProp;
194
- component.typeProp = this.typeProp;
195
-
196
-
197
- if (this.displayProp) {
198
- if (typeof this.displayProp === "string") {
199
- component.displayProp = this.displayProp;
200
- } else if (this.displayProp instanceof SymbolDrawingCommands) {
201
- // Do a proper clone, otherwise, cloned objects will share the
202
- // same drawing object.
203
- component.displayProp =
204
- (this.displayProp as SymbolDrawingCommands).clone();
205
- }
206
- }
207
-
208
- for (const [key, value] of this.parameters) {
209
- component.parameters.set(key, value);
210
- }
211
-
212
- for (const [key, value] of this.pins) {
213
- component.pins.set(key, value);
214
- }
215
-
216
- for (const key in this.styles) {
217
- component.styles[key] = this.styles[key];
218
- }
219
-
220
- component.refreshCache();
221
- return component;
222
- }
223
- }