circuitscript 0.0.22 → 0.0.25
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 +487 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +302 -0
- package/dist/cjs/antlr/CircuitScriptParser.js +5128 -0
- package/dist/cjs/antlr/CircuitScriptVisitor.js +7 -0
- package/dist/cjs/draw_symbols.js +819 -0
- package/dist/cjs/execute.js +778 -0
- package/{src/export.ts → dist/cjs/export.js} +34 -56
- package/dist/cjs/fonts.js +4 -0
- package/dist/cjs/geometry.js +450 -0
- package/dist/cjs/globals.js +60 -0
- package/dist/cjs/helpers.js +269 -0
- package/dist/cjs/index.js +31 -0
- package/{src/layout.ts → dist/cjs/layout.js} +421 -1002
- package/dist/cjs/lexer.js +111 -0
- package/dist/cjs/logger.js +17 -0
- package/dist/cjs/main.js +82 -0
- package/dist/cjs/objects/ClassComponent.js +145 -0
- package/dist/cjs/objects/ExecutionScope.js +135 -0
- package/dist/cjs/objects/Frame.js +22 -0
- package/{src/objects/Net.ts → dist/cjs/objects/Net.js} +9 -24
- package/dist/cjs/objects/ParamDefinition.js +42 -0
- package/dist/cjs/objects/PinDefinition.js +31 -0
- package/dist/cjs/objects/PinTypes.js +11 -0
- package/dist/cjs/objects/Wire.js +9 -0
- package/dist/cjs/objects/types.js +15 -0
- package/dist/cjs/parser.js +70 -0
- package/dist/cjs/regenerate-tests.js +23 -0
- package/dist/cjs/render.js +155 -0
- package/{src/server.ts → dist/cjs/server.js} +15 -21
- package/dist/cjs/sizing.js +105 -0
- package/{src/utils.ts → dist/cjs/utils.js} +25 -35
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +844 -0
- package/dist/esm/BaseVisitor.mjs +488 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +276 -0
- package/dist/esm/antlr/CircuitScriptParser.mjs +5038 -0
- package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +8 -3
- package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +78 -33
- package/{build/src/execute.js → dist/esm/execute.mjs} +59 -60
- package/{build/src/export.js → dist/esm/export.mjs} +2 -2
- package/{build/src/geometry.js → dist/esm/geometry.mjs} +31 -15
- package/dist/esm/helpers.mjs +252 -0
- package/dist/esm/index.mjs +15 -0
- package/{build/src/layout.js → dist/esm/layout.mjs} +19 -11
- package/{build/src/lexer.js → dist/esm/lexer.mjs} +10 -10
- package/{build/src/main.js → dist/esm/main.mjs} +9 -14
- package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +6 -3
- package/{build/src/objects/ExecutionScope.js → dist/esm/objects/ExecutionScope.mjs} +1 -0
- package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
- package/dist/esm/objects/types.mjs +12 -0
- package/dist/esm/parser.mjs +64 -0
- package/{build/src/regenerate-tests.js → dist/esm/regenerate-tests.mjs} +1 -1
- package/{build/src/render.js → dist/esm/render.mjs} +7 -24
- package/{build/src/sizing.js → dist/esm/sizing.mjs} +22 -8
- package/{src/main.ts → dist/esm/validate.mjs} +31 -62
- package/dist/esm/visitor.mjs +838 -0
- package/dist/types/BaseVisitor.d.ts +69 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/{build/src → dist/types}/antlr/CircuitScriptLexer.d.ts +28 -27
- package/dist/types/antlr/CircuitScriptParser.d.ts +719 -0
- package/{build/src → dist/types}/antlr/CircuitScriptVisitor.d.ts +69 -59
- package/{build/src → dist/types}/draw_symbols.d.ts +11 -2
- package/{build/src → dist/types}/execute.d.ts +6 -9
- package/{build/src → dist/types}/geometry.d.ts +5 -1
- package/dist/types/helpers.d.ts +40 -0
- package/dist/types/index.d.ts +15 -0
- package/{build/src → dist/types}/layout.d.ts +10 -10
- package/{build/src → dist/types}/lexer.d.ts +2 -2
- package/{build/src → dist/types}/objects/ClassComponent.d.ts +2 -2
- package/{build/src → dist/types}/objects/ExecutionScope.d.ts +4 -1
- package/{build/src → dist/types}/objects/PinDefinition.d.ts +1 -1
- package/{build/src → dist/types}/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +25 -0
- package/{build/src → dist/types}/render.d.ts +1 -1
- package/{build/src → dist/types}/sizing.d.ts +3 -1
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +80 -0
- package/libs/lib.cst +0 -2
- package/package.json +38 -15
- package/.editorconfig +0 -15
- package/.eslintignore +0 -1
- package/.eslintrc.json +0 -27
- package/.gitlab-ci.yml +0 -81
- package/.prettierignore +0 -8
- package/.prettierrc +0 -16
- package/__tests__/expectedResults.ts +0 -657
- package/__tests__/helpers.ts +0 -82
- package/__tests__/parseScripts.ts +0 -593
- package/__tests__/renderData/script1.cst +0 -58
- package/__tests__/renderData/script1.cst.svg +0 -1
- package/__tests__/renderData/script2.cst +0 -16
- package/__tests__/renderData/script2.cst.svg +0 -1
- package/__tests__/renderData/script3.cst +0 -30
- package/__tests__/renderData/script3.cst.svg +0 -1
- package/__tests__/renderData/script4.cst +0 -54
- package/__tests__/renderData/script4.cst.svg +0 -1
- package/__tests__/renderData/script5.cst +0 -23
- package/__tests__/renderData/script5.cst.svg +0 -1
- package/__tests__/renderData/script6.cst +0 -28
- package/__tests__/renderData/script6.cst.svg +0 -1
- package/__tests__/renderData/script7.cst +0 -26
- package/__tests__/renderData/script7.cst.svg +0 -1
- package/__tests__/renderData/script8.cst +0 -37
- package/__tests__/renderData/script8.cst.svg +0 -1
- package/__tests__/testCLI.ts +0 -68
- package/__tests__/testMathOps.ts +0 -36
- package/__tests__/testMergeWires.ts +0 -141
- package/__tests__/testParse.ts +0 -263
- package/__tests__/testRender.ts +0 -38
- package/build/src/antlr/CircuitScriptLexer.js +0 -287
- package/build/src/antlr/CircuitScriptParser.d.ts +0 -674
- package/build/src/antlr/CircuitScriptParser.js +0 -4841
- package/build/src/helpers.d.ts +0 -1
- package/build/src/helpers.js +0 -73
- package/build/src/objects/types.js +0 -6
- package/build/src/parser.js +0 -69
- package/build/src/visitor.d.ts +0 -133
- package/build/src/visitor.js +0 -1154
- package/documentation.md +0 -238
- package/examples/example_arduino_uno.cst +0 -1146
- package/examples/example_garden_pump.cst +0 -567
- package/examples/lib.cst +0 -185
- package/jest.config.js +0 -23
- package/refresh.html +0 -42
- package/server.cjs +0 -50
- package/src/antlr/CircuitScript.g4 +0 -209
- package/src/antlr/CircuitScriptLexer.ts +0 -317
- package/src/antlr/CircuitScriptParser.ts +0 -4979
- package/src/antlr/CircuitScriptVisitor.ts +0 -420
- package/src/draw_symbols.ts +0 -1085
- package/src/execute.ts +0 -1227
- package/src/fonts.ts +0 -1
- package/src/geometry.ts +0 -638
- package/src/globals.ts +0 -67
- package/src/helpers.ts +0 -114
- package/src/lexer.ts +0 -151
- package/src/logger.ts +0 -17
- package/src/objects/ClassComponent.ts +0 -223
- package/src/objects/ExecutionScope.ts +0 -201
- package/src/objects/Frame.ts +0 -20
- package/src/objects/ParamDefinition.ts +0 -49
- package/src/objects/PinDefinition.ts +0 -49
- package/src/objects/PinTypes.ts +0 -7
- package/src/objects/Wire.ts +0 -19
- package/src/objects/types.ts +0 -66
- package/src/parser.ts +0 -106
- package/src/regenerate-tests.ts +0 -25
- package/src/render.ts +0 -260
- package/src/sizing.ts +0 -96
- package/src/visitor.ts +0 -1691
- package/tsconfig.json +0 -27
- package/tsconfig.release.json +0 -8
- /package/{build/src/fonts.js → dist/esm/fonts.mjs} +0 -0
- /package/{build/src/globals.js → dist/esm/globals.mjs} +0 -0
- /package/{build/src/logger.js → dist/esm/logger.mjs} +0 -0
- /package/{build/src/objects/Frame.js → dist/esm/objects/Frame.mjs} +0 -0
- /package/{build/src/objects/Net.js → dist/esm/objects/Net.mjs} +0 -0
- /package/{build/src/objects/ParamDefinition.js → dist/esm/objects/ParamDefinition.mjs} +0 -0
- /package/{build/src/objects/PinTypes.js → dist/esm/objects/PinTypes.mjs} +0 -0
- /package/{build/src/objects/Wire.js → dist/esm/objects/Wire.mjs} +0 -0
- /package/{build/src/server.js → dist/esm/server.mjs} +0 -0
- /package/{build/src/utils.js → dist/esm/utils.mjs} +0 -0
- /package/{build/src → dist/types}/export.d.ts +0 -0
- /package/{build/src → dist/types}/fonts.d.ts +0 -0
- /package/{build/src → dist/types}/globals.d.ts +0 -0
- /package/{build/src → dist/types}/logger.d.ts +0 -0
- /package/{build/src → dist/types}/main.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Frame.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Net.d.ts +0 -0
- /package/{build/src → dist/types}/objects/ParamDefinition.d.ts +0 -0
- /package/{build/src → dist/types}/objects/PinTypes.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Wire.d.ts +0 -0
- /package/{build/src → dist/types}/regenerate-tests.d.ts +0 -0
- /package/{build/src → dist/types}/server.d.ts +0 -0
- /package/{build/src → dist/types}/utils.d.ts +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
|
-
}
|
|
@@ -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
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { ClassComponent } from './ClassComponent.js';
|
|
2
|
-
import { Net } from './Net.js';
|
|
3
|
-
import { CFunction, ComponentPinNet, ComponentPinNetPair, ValueType } from './types.js';
|
|
4
|
-
import { LayoutDirection } from '../globals.js';
|
|
5
|
-
import { Wire, WireSegment } from './Wire.js';
|
|
6
|
-
import { Frame } from './Frame.js';
|
|
7
|
-
|
|
8
|
-
export class ExecutionScope {
|
|
9
|
-
scopeId: number;
|
|
10
|
-
private nets: ComponentPinNetPair[] = [];
|
|
11
|
-
|
|
12
|
-
instances: Map<string, ClassComponent> = new Map();
|
|
13
|
-
|
|
14
|
-
functions: Map<string, CFunction> = new Map();
|
|
15
|
-
|
|
16
|
-
variables: Map<string, ValueType | ClassComponent> = new Map();
|
|
17
|
-
|
|
18
|
-
blockStack: Map<number, any> = new Map();
|
|
19
|
-
|
|
20
|
-
wires: Wire[] = [];
|
|
21
|
-
frames: Frame[] = [];
|
|
22
|
-
|
|
23
|
-
indentLevel = 0;
|
|
24
|
-
netCounter = 1;
|
|
25
|
-
unnamedCounter = 1;
|
|
26
|
-
|
|
27
|
-
currentComponent: ClassComponent | null = null;
|
|
28
|
-
currentPin: number | null = null;
|
|
29
|
-
|
|
30
|
-
currentWireId = -1;
|
|
31
|
-
currentFrameId = -1;
|
|
32
|
-
|
|
33
|
-
netGnd: Net | null = null;
|
|
34
|
-
|
|
35
|
-
// This is the main gnd net of the circuit scope
|
|
36
|
-
componentGnd: ClassComponent | null = null;
|
|
37
|
-
|
|
38
|
-
// This is the first component in the circuit scope
|
|
39
|
-
componentRoot: ClassComponent | null = null;
|
|
40
|
-
|
|
41
|
-
// Tracks the counter for copies of each component instance
|
|
42
|
-
// Copies are the same component electrically, but different symbols.
|
|
43
|
-
copyIDs: Map<string, number> = new Map();
|
|
44
|
-
|
|
45
|
-
// Determines how components are added/joined on the graph graphically.
|
|
46
|
-
// This is very important in "building" up the graph
|
|
47
|
-
// according to the user's order.
|
|
48
|
-
sequence: any[] = [];
|
|
49
|
-
|
|
50
|
-
constructor(scopeId: number) {
|
|
51
|
-
this.scopeId = scopeId;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
static scopeId = 0;
|
|
55
|
-
|
|
56
|
-
static create(): ExecutionScope {
|
|
57
|
-
const scope = new ExecutionScope(ExecutionScope.scopeId);
|
|
58
|
-
ExecutionScope.scopeId += 1;
|
|
59
|
-
return scope;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private findNet(component: ClassComponent, pin: number): ComponentPinNetPair {
|
|
63
|
-
return this.nets.find(([tmpComponent, tmpPin]) => {
|
|
64
|
-
// Use manual equality, much faster than using lodash
|
|
65
|
-
return tmpComponent.isEqual(component) && tmpPin === pin;
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
getNetWithName(name: string): Net {
|
|
70
|
-
const found = this.nets.find(([,, net]) => {
|
|
71
|
-
return net.name === name;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
return found ? found[2]: null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
hasNet(component: ClassComponent, pin: number): boolean {
|
|
78
|
-
return this.findNet(component, pin) !== undefined;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
getNet(component: ClassComponent, pin: number): Net {
|
|
82
|
-
const result = this.findNet(component, pin);
|
|
83
|
-
if (result) {
|
|
84
|
-
return result[2]; // net
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
setNet(component: ClassComponent, pin: number, net: Net): void {
|
|
91
|
-
const pair = this.findNet(component, pin);
|
|
92
|
-
const result = this.nets.indexOf(pair);
|
|
93
|
-
|
|
94
|
-
if (result === -1) {
|
|
95
|
-
this.nets.push([component, pin, net]);
|
|
96
|
-
} else {
|
|
97
|
-
this.nets[result][2] = net;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
component.pinNets.set(pin, net);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
removeNet(component: ClassComponent, pin: number): void {
|
|
104
|
-
const pair = this.findNet(component, pin);
|
|
105
|
-
const result = this.nets.indexOf(pair);
|
|
106
|
-
|
|
107
|
-
if (result !== -1) {
|
|
108
|
-
this.nets.splice(result, 1);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
component.pinNets.delete(pin);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
getNets(): ComponentPinNetPair[] {
|
|
115
|
-
return this.nets;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
dumpNets(): ComponentPinNet[] {
|
|
119
|
-
const sortedNet = [...this.nets].sort((a, b) => {
|
|
120
|
-
const netA = a[2];
|
|
121
|
-
const netB = b[2];
|
|
122
|
-
|
|
123
|
-
const netAId = netA.namespace + netA.name;
|
|
124
|
-
const netBId = netB.namespace + b[2].name;
|
|
125
|
-
|
|
126
|
-
if (netAId > netBId) {
|
|
127
|
-
return 1;
|
|
128
|
-
} else if (netAId < netBId) {
|
|
129
|
-
return -1;
|
|
130
|
-
} else {
|
|
131
|
-
return 0;
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
return sortedNet.map(([component, pin, net]) => {
|
|
136
|
-
return [net.namespace + net.name, component.instanceName, pin];
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
printNets(): void {
|
|
141
|
-
this.dumpNets().forEach(item => {
|
|
142
|
-
const [netName, instanceName, pin] = item;
|
|
143
|
-
console.log(netName.padEnd(10), '=>', instanceName, pin);
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
setActive(type: ActiveObject, item: any): void {
|
|
148
|
-
// Reset the state and ensure that only one of the
|
|
149
|
-
// active object is selected.
|
|
150
|
-
|
|
151
|
-
this.clearActive();
|
|
152
|
-
|
|
153
|
-
if (type === ActiveObject.Wire) {
|
|
154
|
-
this.currentWireId = item;
|
|
155
|
-
} else if (type === ActiveObject.Frame) {
|
|
156
|
-
this.currentFrameId = item;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
clearActive(): void {
|
|
161
|
-
// Clears any current selected wire or frame
|
|
162
|
-
this.currentWireId = -1;
|
|
163
|
-
this.currentFrameId = -1;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export enum SequenceAction {
|
|
168
|
-
// Link current insertion point to component pin
|
|
169
|
-
To = 'to',
|
|
170
|
-
|
|
171
|
-
// Move insertion point at component pin
|
|
172
|
-
At = 'at',
|
|
173
|
-
|
|
174
|
-
// Link current insertion point with wire of given segments
|
|
175
|
-
Wire = 'wire',
|
|
176
|
-
|
|
177
|
-
// Jump to wire with target ID. Pin 0 of wire is the start of the
|
|
178
|
-
// wire, pin 1 is the other end of the wire.
|
|
179
|
-
WireJump = 'wire-jump',
|
|
180
|
-
|
|
181
|
-
// Creates a new frame group
|
|
182
|
-
Frame = 'frame',
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export enum FrameAction {
|
|
186
|
-
Enter = 'enter',
|
|
187
|
-
Exit = 'exit',
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export enum ActiveObject {
|
|
191
|
-
Frame = 'frame',
|
|
192
|
-
Wire = 'wire',
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
export type SequenceItem =
|
|
197
|
-
[SequenceAction.To | SequenceAction.At, ClassComponent, number, LayoutDirection?, string?]
|
|
198
|
-
| [SequenceAction.Wire, wireId: number, WireSegment[]]
|
|
199
|
-
| [SequenceAction.WireJump, wireId: number, pinId: number]
|
|
200
|
-
| [SequenceAction.Frame, Frame, "enter" | "exit"]
|
|
201
|
-
;
|