circuitscript 0.1.4 → 0.1.7
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 +149 -80
- package/dist/cjs/SemanticTokenVisitor.js +19 -13
- package/dist/cjs/antlr/CircuitScriptParser.js +711 -671
- package/dist/cjs/builtinMethods.js +48 -22
- package/dist/cjs/draw_symbols.js +4 -1
- package/dist/cjs/environment.js +118 -0
- package/dist/cjs/execute.js +98 -46
- package/dist/cjs/geometry.js +1 -0
- package/dist/cjs/globals.js +14 -7
- package/dist/cjs/helpers.js +142 -150
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/layout.js +39 -14
- package/dist/cjs/main.js +34 -21
- package/dist/cjs/objects/ClassComponent.js +4 -1
- package/dist/cjs/objects/ExecutionScope.js +40 -2
- package/dist/cjs/objects/ParamDefinition.js +15 -15
- package/dist/cjs/parser.js +27 -21
- package/dist/cjs/regenerate-tests.js +9 -6
- package/dist/cjs/render.js +3 -1
- package/dist/cjs/sizing.js +10 -60
- package/dist/cjs/utils.js +148 -17
- package/dist/cjs/validate/SymbolTable.js +96 -0
- package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +14 -0
- package/dist/cjs/validate/SymbolValidatorVisitor.js +170 -0
- package/dist/cjs/validate.js +52 -44
- package/dist/cjs/visitor.js +149 -31
- package/dist/esm/{BaseVisitor.mjs → BaseVisitor.js} +124 -56
- package/dist/esm/{SemanticTokenVisitor.mjs → SemanticTokenVisitor.js} +17 -11
- package/dist/esm/antlr/{CircuitScriptParser.mjs → CircuitScriptParser.js} +711 -671
- package/dist/esm/{builtinMethods.mjs → builtinMethods.js} +40 -14
- package/dist/esm/{draw_symbols.mjs → draw_symbols.js} +11 -8
- package/dist/esm/environment.js +110 -0
- package/dist/esm/{execute.mjs → execute.js} +111 -58
- package/dist/esm/{export.mjs → export.js} +2 -2
- package/dist/esm/{geometry.mjs → geometry.js} +6 -5
- package/dist/esm/{globals.mjs → globals.js} +9 -2
- package/dist/esm/helpers.js +377 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/{layout.mjs → layout.js} +44 -22
- package/dist/esm/{lexer.mjs → lexer.js} +2 -2
- package/dist/esm/{main.mjs → main.js} +36 -23
- package/dist/esm/objects/{ClassComponent.mjs → ClassComponent.js} +9 -5
- package/dist/esm/objects/{ExecutionScope.mjs → ExecutionScope.js} +40 -2
- package/dist/esm/objects/{Frame.mjs → Frame.js} +1 -1
- package/dist/esm/objects/{ParamDefinition.mjs → ParamDefinition.js} +1 -1
- package/dist/esm/objects/{PinDefinition.mjs → PinDefinition.js} +1 -1
- package/dist/esm/parser.js +71 -0
- package/dist/esm/{regenerate-tests.mjs → regenerate-tests.js} +10 -7
- package/dist/esm/{render.mjs → render.js} +11 -9
- package/dist/esm/{sizing.mjs → sizing.js} +11 -36
- package/dist/esm/utils.js +286 -0
- package/dist/esm/validate/SymbolTable.js +90 -0
- package/dist/esm/validate/SymbolValidatorResolveVisitor.js +10 -0
- package/dist/esm/validate/SymbolValidatorVisitor.js +163 -0
- package/dist/esm/validate.js +86 -0
- package/dist/esm/{visitor.mjs → visitor.js} +160 -42
- package/dist/fonts/Arial.ttf +0 -0
- package/dist/fonts/Inter-Bold.ttf +0 -0
- package/dist/fonts/Inter-Regular.ttf +0 -0
- package/dist/fonts/OpenSans-Regular.ttf +0 -0
- package/dist/fonts/Roboto-Regular.ttf +0 -0
- package/dist/libs/lib.cst +423 -0
- package/dist/types/BaseVisitor.d.ts +36 -22
- package/dist/types/SemanticTokenVisitor.d.ts +6 -5
- package/dist/types/antlr/CircuitScriptParser.d.ts +4 -2
- package/dist/types/builtinMethods.d.ts +3 -2
- package/dist/types/draw_symbols.d.ts +2 -6
- package/dist/types/environment.d.ts +31 -0
- package/dist/types/execute.d.ts +2 -3
- package/dist/types/globals.d.ts +7 -2
- package/dist/types/helpers.d.ts +12 -14
- package/dist/types/index.d.ts +5 -0
- package/dist/types/objects/ClassComponent.d.ts +2 -3
- package/dist/types/objects/ExecutionScope.d.ts +20 -6
- package/dist/types/objects/types.d.ts +6 -1
- package/dist/types/parser.d.ts +7 -11
- package/dist/types/sizing.d.ts +0 -3
- package/dist/types/utils.d.ts +33 -4
- package/dist/types/validate/SymbolTable.d.ts +40 -0
- package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +7 -0
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +32 -0
- package/dist/types/validate.d.ts +1 -1
- package/libs/lib.cst +12 -22
- package/package.json +14 -13
- package/dist/cjs/SymbolValidatorVisitor.js +0 -233
- package/dist/esm/SymbolValidatorVisitor.mjs +0 -222
- package/dist/esm/helpers.mjs +0 -380
- package/dist/esm/index.mjs +0 -15
- package/dist/esm/parser.mjs +0 -64
- package/dist/esm/utils.mjs +0 -169
- package/dist/esm/validate.mjs +0 -74
- package/dist/types/SymbolValidatorVisitor.d.ts +0 -61
- package/dist/types/layout.d.ts +0 -148
- /package/dist/esm/antlr/{CircuitScriptLexer.mjs → CircuitScriptLexer.js} +0 -0
- /package/dist/esm/antlr/{CircuitScriptVisitor.mjs → CircuitScriptVisitor.js} +0 -0
- /package/dist/esm/{fonts.mjs → fonts.js} +0 -0
- /package/dist/esm/{logger.mjs → logger.js} +0 -0
- /package/dist/esm/objects/{Net.mjs → Net.js} +0 -0
- /package/dist/esm/objects/{PinTypes.mjs → PinTypes.js} +0 -0
- /package/dist/esm/objects/{Wire.mjs → Wire.js} +0 -0
- /package/dist/esm/objects/{types.mjs → types.js} +0 -0
- /package/dist/esm/{server.mjs → server.js} +0 -0
package/dist/esm/helpers.mjs
DELETED
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, createWriteStream } from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import PDFDocument from "pdfkit";
|
|
4
|
-
import { generateKiCADNetList, printTree } from "./export.mjs";
|
|
5
|
-
import { LayoutEngine } from "./layout.mjs";
|
|
6
|
-
import { SequenceAction } from "./objects/ExecutionScope.mjs";
|
|
7
|
-
import { parseFileWithVisitor } from "./parser.mjs";
|
|
8
|
-
import { generatePdfOutput, generateSvgOutput, renderSheetsToSVG } from "./render.mjs";
|
|
9
|
-
import { resolveToNumericValue, SimpleStopwatch } from "./utils.mjs";
|
|
10
|
-
import { ParserVisitor, VisitorExecutionException } from "./visitor.mjs";
|
|
11
|
-
import { createContext } from "this-file";
|
|
12
|
-
import { SymbolValidatorResolveVisitor, SymbolValidatorVisitor } from "./SymbolValidatorVisitor.mjs";
|
|
13
|
-
import { BaseErrorListener, CharStream, CommonTokenStream, DefaultErrorStrategy } from "antlr4ng";
|
|
14
|
-
import { MainLexer } from "./lexer.mjs";
|
|
15
|
-
import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
|
|
16
|
-
import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.mjs";
|
|
17
|
-
import { defaultPageMarginMM, defaultZoomScale, LengthUnit, MilsToMM, PxToMM } from "./globals.mjs";
|
|
18
|
-
import { FrameParamKeys } from "./objects/Frame.mjs";
|
|
19
|
-
import Big from "big.js";
|
|
20
|
-
import { Logger } from "./logger.mjs";
|
|
21
|
-
export var JSModuleType;
|
|
22
|
-
(function (JSModuleType) {
|
|
23
|
-
JSModuleType["CommonJs"] = "cjs";
|
|
24
|
-
JSModuleType["ESM"] = "mjs";
|
|
25
|
-
})(JSModuleType || (JSModuleType = {}));
|
|
26
|
-
export function prepareFile(textData) {
|
|
27
|
-
const chars = CharStream.fromString(textData);
|
|
28
|
-
const lexer = new MainLexer(chars);
|
|
29
|
-
const lexerTimer = new SimpleStopwatch();
|
|
30
|
-
const tokens = new CommonTokenStream(lexer);
|
|
31
|
-
tokens.fill();
|
|
32
|
-
const lexerTimeTaken = lexerTimer.lap();
|
|
33
|
-
const parser = new CircuitScriptParser(tokens);
|
|
34
|
-
return {
|
|
35
|
-
parser,
|
|
36
|
-
lexer,
|
|
37
|
-
lexerTimeTaken,
|
|
38
|
-
tokens
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
export function getScriptText(filePath) {
|
|
42
|
-
try {
|
|
43
|
-
return readFileSync(filePath, { encoding: 'utf-8' });
|
|
44
|
-
}
|
|
45
|
-
catch (err) {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export function getSemanticTokens(scriptData, options) {
|
|
50
|
-
const { parser, lexer, tokens } = prepareFile(scriptData);
|
|
51
|
-
const tree = parser.script();
|
|
52
|
-
const { currentDirectory = null, defaultLibsPath, } = options;
|
|
53
|
-
const visitor = new SemanticTokensVisitor(true, null, currentDirectory, defaultLibsPath, lexer, scriptData);
|
|
54
|
-
parser.removeErrorListeners();
|
|
55
|
-
visitor.onImportFile = (visitor, textData) => {
|
|
56
|
-
let hasError = false;
|
|
57
|
-
let hasParseError = false;
|
|
58
|
-
if (textData !== null) {
|
|
59
|
-
const { parser } = prepareFile(textData);
|
|
60
|
-
const tree = parser.script();
|
|
61
|
-
try {
|
|
62
|
-
visitor.visit(tree);
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
console.log('Error while parsing: ', err);
|
|
66
|
-
hasParseError = true;
|
|
67
|
-
hasError = true;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
console.log('File does not exist');
|
|
72
|
-
hasError = true;
|
|
73
|
-
}
|
|
74
|
-
return {
|
|
75
|
-
hasError, hasParseError
|
|
76
|
-
};
|
|
77
|
-
};
|
|
78
|
-
visitor.visit(tree);
|
|
79
|
-
const semanticTokens = visitor.getTokens();
|
|
80
|
-
const parsedTokens = prepareTokens(tokens.getTokens(), lexer, scriptData);
|
|
81
|
-
const finalParsedTokens = [];
|
|
82
|
-
parsedTokens.forEach(token => {
|
|
83
|
-
const location = `${token.line}_${token.column}`;
|
|
84
|
-
if (semanticTokens.has(location)) {
|
|
85
|
-
finalParsedTokens.push(semanticTokens.get(location));
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
finalParsedTokens.push(token);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
return {
|
|
92
|
-
visitor,
|
|
93
|
-
parsedTokens: finalParsedTokens
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
class TokenErrorListener extends BaseErrorListener {
|
|
97
|
-
syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
|
|
98
|
-
console.log(msg);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
export class ParseErrorStrategy extends DefaultErrorStrategy {
|
|
102
|
-
reportUnwantedToken(recognizer) {
|
|
103
|
-
if (this.inErrorRecoveryMode(recognizer)) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
this.beginErrorCondition(recognizer);
|
|
107
|
-
const t = recognizer.getCurrentToken();
|
|
108
|
-
const tokenName = this.getTokenErrorDisplay(t);
|
|
109
|
-
const msg = "extraneous input " + tokenName;
|
|
110
|
-
recognizer.notifyErrorListeners(msg, t, null);
|
|
111
|
-
this.endErrorCondition(recognizer);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
export function validateScript(scriptData, options) {
|
|
115
|
-
const { parser } = prepareFile(scriptData);
|
|
116
|
-
parser.removeErrorListeners();
|
|
117
|
-
parser.errorHandler = new ParseErrorStrategy();
|
|
118
|
-
parser.addErrorListener(new TokenErrorListener());
|
|
119
|
-
const tree = parser.script();
|
|
120
|
-
const { currentDirectory = null, defaultLibsPath, } = options;
|
|
121
|
-
const visitor = new SymbolValidatorVisitor(true, null, currentDirectory, defaultLibsPath);
|
|
122
|
-
visitor.onImportFile = (visitor, textData) => {
|
|
123
|
-
let hasError = false;
|
|
124
|
-
let hasParseError = false;
|
|
125
|
-
if (textData !== null) {
|
|
126
|
-
const { parser } = prepareFile(textData);
|
|
127
|
-
const tree = parser.script();
|
|
128
|
-
try {
|
|
129
|
-
visitor.visit(tree);
|
|
130
|
-
}
|
|
131
|
-
catch (err) {
|
|
132
|
-
console.log('got an error while parsing tree: ', err);
|
|
133
|
-
hasParseError = true;
|
|
134
|
-
hasError = true;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
console.log('file does not exist!');
|
|
139
|
-
hasError = true;
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
hasError, hasParseError
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
visitor.visit(tree);
|
|
146
|
-
const symbolTable = visitor.getSymbols();
|
|
147
|
-
symbolTable.clearUndefined();
|
|
148
|
-
const visitorResolver = new SymbolValidatorResolveVisitor(true, null, currentDirectory, defaultLibsPath);
|
|
149
|
-
visitorResolver.setSymbols(visitor.getSymbols());
|
|
150
|
-
visitorResolver.onImportFile = visitor.onImportFile;
|
|
151
|
-
visitorResolver.visit(tree);
|
|
152
|
-
return visitorResolver;
|
|
153
|
-
}
|
|
154
|
-
export function renderScript(scriptData, outputPath, options) {
|
|
155
|
-
const { currentDirectory = null, defaultLibsPath, dumpNets = false, dumpData = false, showStats = false } = options;
|
|
156
|
-
const onErrorHandler = (line, column, message, error) => {
|
|
157
|
-
if (error instanceof VisitorExecutionException) {
|
|
158
|
-
console.log('Error', line, column, message, error.errorMessage);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
const visitor = new ParserVisitor(true, onErrorHandler, currentDirectory, defaultLibsPath);
|
|
162
|
-
visitor.onImportFile = (visitor, fileData) => {
|
|
163
|
-
const { hasError, hasParseError } = parseFileWithVisitor(visitor, fileData);
|
|
164
|
-
return { hasError, hasParseError };
|
|
165
|
-
};
|
|
166
|
-
visitor.log('reading file');
|
|
167
|
-
visitor.log('done reading file');
|
|
168
|
-
const { tree, parser, hasParseError, hasError, parserTimeTaken, lexerTimeTaken } = parseFileWithVisitor(visitor, scriptData);
|
|
169
|
-
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
170
|
-
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
171
|
-
if (dumpNets) {
|
|
172
|
-
const nets = visitor.dumpNets();
|
|
173
|
-
console.log(nets);
|
|
174
|
-
}
|
|
175
|
-
dumpData && writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
|
|
176
|
-
dumpData && writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
|
|
177
|
-
if (hasError || hasParseError) {
|
|
178
|
-
console.log('Error while parsing');
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
const { frameComponent } = visitor.applySheetFrameComponent();
|
|
182
|
-
try {
|
|
183
|
-
visitor.annotateComponents();
|
|
184
|
-
}
|
|
185
|
-
catch (err) {
|
|
186
|
-
console.log('Error during annotation: ', err);
|
|
187
|
-
}
|
|
188
|
-
const { sequence, nets } = visitor.getGraph();
|
|
189
|
-
const tmpSequence = sequence.map(item => {
|
|
190
|
-
const tmp = [...item];
|
|
191
|
-
const action = tmp[0];
|
|
192
|
-
if (action === SequenceAction.Wire) {
|
|
193
|
-
tmp[2] = tmp[2].map(item2 => {
|
|
194
|
-
const lengthValue = item2.value;
|
|
195
|
-
const useValue = [item2.direction];
|
|
196
|
-
if (lengthValue !== null) {
|
|
197
|
-
useValue.push(lengthValue.value);
|
|
198
|
-
useValue.push(lengthValue.type);
|
|
199
|
-
}
|
|
200
|
-
return useValue.join(",");
|
|
201
|
-
}).join(" ");
|
|
202
|
-
}
|
|
203
|
-
else if (action === SequenceAction.Frame) {
|
|
204
|
-
tmp[1] = item[1].frameId;
|
|
205
|
-
}
|
|
206
|
-
else if (action !== SequenceAction.WireJump) {
|
|
207
|
-
tmp[1] = item[1].instanceName;
|
|
208
|
-
}
|
|
209
|
-
return tmp.join(" | ");
|
|
210
|
-
});
|
|
211
|
-
dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
|
|
212
|
-
let svgOutput = "";
|
|
213
|
-
try {
|
|
214
|
-
let fileExtension = null;
|
|
215
|
-
let outputDefaultZoom = defaultZoomScale;
|
|
216
|
-
if (outputPath) {
|
|
217
|
-
fileExtension = path.extname(outputPath).substring(1);
|
|
218
|
-
if (fileExtension === "pdf") {
|
|
219
|
-
outputDefaultZoom = 1;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (fileExtension === 'net') {
|
|
223
|
-
const { tree: kicadNetList, missingFootprints } = generateKiCADNetList(visitor.getNetList());
|
|
224
|
-
missingFootprints.forEach(entry => {
|
|
225
|
-
console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
|
|
226
|
-
});
|
|
227
|
-
writeFileSync(outputPath, printTree(kicadNetList));
|
|
228
|
-
console.log('Generated file', outputPath);
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
|
-
const layoutEngine = new LayoutEngine();
|
|
232
|
-
const layoutTimer = new SimpleStopwatch();
|
|
233
|
-
const sheetFrames = layoutEngine.runLayout(sequence, nets);
|
|
234
|
-
layoutEngine.printWarnings();
|
|
235
|
-
showStats && console.log('Layout took:', layoutTimer.lap());
|
|
236
|
-
dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
|
|
237
|
-
const generateSvgTimer = new SimpleStopwatch();
|
|
238
|
-
const renderLogger = new Logger();
|
|
239
|
-
const svgCanvas = renderSheetsToSVG(sheetFrames, renderLogger);
|
|
240
|
-
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
241
|
-
dumpData && writeFileSync('dump/raw-render.txt', renderLogger.dump());
|
|
242
|
-
svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
|
|
243
|
-
if (outputPath) {
|
|
244
|
-
if (fileExtension === 'svg') {
|
|
245
|
-
writeFileSync(outputPath, svgOutput);
|
|
246
|
-
}
|
|
247
|
-
else if (fileExtension === 'pdf') {
|
|
248
|
-
let sheetSize = "A4";
|
|
249
|
-
let sheetSizeDefined = false;
|
|
250
|
-
if (frameComponent) {
|
|
251
|
-
sheetSize = frameComponent.getParam(FrameParamKeys.PaperSize);
|
|
252
|
-
sheetSizeDefined = true;
|
|
253
|
-
}
|
|
254
|
-
const doc = new PDFDocument({
|
|
255
|
-
layout: 'landscape',
|
|
256
|
-
size: sheetSize
|
|
257
|
-
});
|
|
258
|
-
const outputStream = createWriteStream(outputPath);
|
|
259
|
-
generatePdfOutput(doc, svgCanvas, sheetSize, sheetSizeDefined, outputDefaultZoom);
|
|
260
|
-
doc.pipe(outputStream);
|
|
261
|
-
doc.end();
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
throw "Invalid output format";
|
|
265
|
-
}
|
|
266
|
-
console.log('Generated file', outputPath);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
catch (err) {
|
|
270
|
-
console.log('Error during render: ', err);
|
|
271
|
-
}
|
|
272
|
-
return svgOutput;
|
|
273
|
-
}
|
|
274
|
-
export function detectJSModuleType() {
|
|
275
|
-
if (typeof __filename === 'undefined' &&
|
|
276
|
-
typeof __dirname === 'undefined') {
|
|
277
|
-
return JSModuleType.ESM;
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
return JSModuleType.CommonJs;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
const context = createContext();
|
|
284
|
-
export function getCurrentPath() {
|
|
285
|
-
const filename = context.filename;
|
|
286
|
-
return { filePath: filename };
|
|
287
|
-
}
|
|
288
|
-
function getToolsPath() {
|
|
289
|
-
const { filePath } = getCurrentPath();
|
|
290
|
-
return path.normalize(path.dirname(filePath) + '/../../');
|
|
291
|
-
}
|
|
292
|
-
export function getFontsPath() {
|
|
293
|
-
const toolsPath = getToolsPath();
|
|
294
|
-
return path.normalize(toolsPath + "fonts");
|
|
295
|
-
}
|
|
296
|
-
export function getDefaultLibsPath() {
|
|
297
|
-
const toolsPath = getToolsPath();
|
|
298
|
-
return path.normalize(toolsPath + "libs");
|
|
299
|
-
}
|
|
300
|
-
export function getPackageVersion() {
|
|
301
|
-
const packageJson = JSON.parse(readFileSync(getToolsPath() + 'package.json').toString());
|
|
302
|
-
const { version } = packageJson;
|
|
303
|
-
return version;
|
|
304
|
-
}
|
|
305
|
-
export class UnitDimension {
|
|
306
|
-
type;
|
|
307
|
-
value;
|
|
308
|
-
constructor(value, type = LengthUnit.mils) {
|
|
309
|
-
this.value = value;
|
|
310
|
-
this.type = type;
|
|
311
|
-
}
|
|
312
|
-
getMM() {
|
|
313
|
-
switch (this.type) {
|
|
314
|
-
case LengthUnit.mm:
|
|
315
|
-
return this.value;
|
|
316
|
-
case LengthUnit.mils:
|
|
317
|
-
return this.value * MilsToMM;
|
|
318
|
-
case LengthUnit.px:
|
|
319
|
-
return this.value * PxToMM;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
static mm(value) {
|
|
323
|
-
return new UnitDimension(value, LengthUnit.mm);
|
|
324
|
-
}
|
|
325
|
-
static mils(value) {
|
|
326
|
-
return new UnitDimension(value, LengthUnit.mils);
|
|
327
|
-
}
|
|
328
|
-
static px(value) {
|
|
329
|
-
return new UnitDimension(value, LengthUnit.px);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
export function milsToMM(value) {
|
|
333
|
-
if (typeof value === 'number') {
|
|
334
|
-
value = resolveToNumericValue(new Big(value));
|
|
335
|
-
}
|
|
336
|
-
return resolveToNumericValue(value.toBigNumber().mul(new Big(MilsToMM)).round(6));
|
|
337
|
-
}
|
|
338
|
-
export function pxToMM(value) {
|
|
339
|
-
return value * PxToMM;
|
|
340
|
-
}
|
|
341
|
-
const PaperSizes = {
|
|
342
|
-
'A0': [1189, 841],
|
|
343
|
-
'A1': [841, 594],
|
|
344
|
-
'A2': [594, 420],
|
|
345
|
-
'A3': [420, 297],
|
|
346
|
-
'A4': [297, 210],
|
|
347
|
-
'A5': [210, 148],
|
|
348
|
-
'A6': [148, 105],
|
|
349
|
-
};
|
|
350
|
-
export const PaperGridReferences = {
|
|
351
|
-
'A0': [16, 24],
|
|
352
|
-
'A1': [12, 16],
|
|
353
|
-
'A2': [8, 12],
|
|
354
|
-
'A3': [6, 8],
|
|
355
|
-
'A4': [4, 6],
|
|
356
|
-
};
|
|
357
|
-
export function isSupportedPaperSize(type) {
|
|
358
|
-
if (PaperSizes[type]) {
|
|
359
|
-
return true;
|
|
360
|
-
}
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
export function getPaperSize(type, margin = defaultPageMarginMM) {
|
|
364
|
-
if (PaperSizes[type]) {
|
|
365
|
-
const [width, height] = PaperSizes[type];
|
|
366
|
-
const useWidth = width - margin * 2;
|
|
367
|
-
const useHeight = height - margin * 2;
|
|
368
|
-
return {
|
|
369
|
-
width: Math.floor(useWidth * (1 / MilsToMM)),
|
|
370
|
-
height: Math.floor(useHeight * (1 / MilsToMM)),
|
|
371
|
-
widthMM: useWidth,
|
|
372
|
-
heightMM: useHeight,
|
|
373
|
-
originalWidthMM: width,
|
|
374
|
-
originalHeightMM: height,
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
return getPaperSize('A4');
|
|
379
|
-
}
|
|
380
|
-
}
|
package/dist/esm/index.mjs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export * from './draw_symbols.mjs';
|
|
2
|
-
export * from './execute.mjs';
|
|
3
|
-
export * from './export.mjs';
|
|
4
|
-
export * from './geometry.mjs';
|
|
5
|
-
export * from './globals.mjs';
|
|
6
|
-
export * from './helpers.mjs';
|
|
7
|
-
export * from './layout.mjs';
|
|
8
|
-
export * from './lexer.mjs';
|
|
9
|
-
export * from './logger.mjs';
|
|
10
|
-
export * from './parser.mjs';
|
|
11
|
-
export * from './render.mjs';
|
|
12
|
-
export * from './utils.mjs';
|
|
13
|
-
export * from './visitor.mjs';
|
|
14
|
-
export * from './sizing.mjs';
|
|
15
|
-
export * from './objects/types.mjs';
|
package/dist/esm/parser.mjs
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { CircuitScriptParser } from './antlr/CircuitScriptParser.mjs';
|
|
2
|
-
import { MainLexer } from './lexer.mjs';
|
|
3
|
-
import { SimpleStopwatch } from './utils.mjs';
|
|
4
|
-
import { CharStream, CommonTokenStream, DefaultErrorStrategy } from 'antlr4ng';
|
|
5
|
-
export function parseFileWithVisitor(visitor, data) {
|
|
6
|
-
const chars = CharStream.fromString(data);
|
|
7
|
-
const lexer = new MainLexer(chars);
|
|
8
|
-
const lexerTimer = new SimpleStopwatch();
|
|
9
|
-
const tokens = new CommonTokenStream(lexer);
|
|
10
|
-
tokens.fill();
|
|
11
|
-
const lexerTimeTaken = lexerTimer.lap();
|
|
12
|
-
const parserTimer = new SimpleStopwatch();
|
|
13
|
-
const parser = new CircuitScriptParser(tokens);
|
|
14
|
-
const tree = parser.script();
|
|
15
|
-
let hasError = false;
|
|
16
|
-
try {
|
|
17
|
-
visitor.visit(tree);
|
|
18
|
-
}
|
|
19
|
-
catch (err) {
|
|
20
|
-
console.log(err);
|
|
21
|
-
hasError = true;
|
|
22
|
-
}
|
|
23
|
-
const parserTimeTaken = parserTimer.lap();
|
|
24
|
-
return {
|
|
25
|
-
tree, parser,
|
|
26
|
-
hasParseError: false,
|
|
27
|
-
hasError,
|
|
28
|
-
parserTimeTaken,
|
|
29
|
-
lexerTimeTaken,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export class TempErrorStrategy extends DefaultErrorStrategy {
|
|
33
|
-
recover(recognizer, e) {
|
|
34
|
-
throw new Error('Method not implemented.');
|
|
35
|
-
}
|
|
36
|
-
reportError(recognizer, e) {
|
|
37
|
-
throw new Error('Method not implemented.');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
export class CircuitscriptParserErrorListener {
|
|
41
|
-
syntaxErrorCounter = 0;
|
|
42
|
-
onErrorHandler = null;
|
|
43
|
-
constructor(onErrorHandler = null) {
|
|
44
|
-
this.onErrorHandler = onErrorHandler;
|
|
45
|
-
}
|
|
46
|
-
syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e) {
|
|
47
|
-
if (this.onErrorHandler) {
|
|
48
|
-
this.onErrorHandler(line, charPositionInLine, msg, e);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
console.log("Syntax error at line", line, ':', charPositionInLine, ' - ', msg);
|
|
52
|
-
}
|
|
53
|
-
this.syntaxErrorCounter++;
|
|
54
|
-
}
|
|
55
|
-
reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) {
|
|
56
|
-
}
|
|
57
|
-
reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) {
|
|
58
|
-
}
|
|
59
|
-
reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs) {
|
|
60
|
-
}
|
|
61
|
-
hasSyntaxErrors() {
|
|
62
|
-
return (this.syntaxErrorCounter > 0);
|
|
63
|
-
}
|
|
64
|
-
}
|
package/dist/esm/utils.mjs
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { Big } from 'big.js';
|
|
2
|
-
import { NumericValue } from "./objects/ParamDefinition";
|
|
3
|
-
export class SimpleStopwatch {
|
|
4
|
-
startTime;
|
|
5
|
-
constructor() {
|
|
6
|
-
this.startTime = new Date();
|
|
7
|
-
}
|
|
8
|
-
lap() {
|
|
9
|
-
return (new Date()).getTime() - this.startTime.getTime();
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
export function resizeBounds(bounds, value) {
|
|
13
|
-
return {
|
|
14
|
-
xmin: bounds.xmin - value,
|
|
15
|
-
xmax: bounds.xmax + value,
|
|
16
|
-
ymin: bounds.ymin - value,
|
|
17
|
-
ymax: bounds.ymax + value
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export function printBounds(bounds) {
|
|
21
|
-
if (bounds !== null) {
|
|
22
|
-
return `[${bounds.xmin}, ${bounds.ymin} to ${bounds.xmax}, ${bounds.ymax}]`;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
return 'null';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function hasRemainder(value, value2) {
|
|
29
|
-
const tmpValue = Math.abs(value) / value2;
|
|
30
|
-
const flooredValue = Math.floor(tmpValue);
|
|
31
|
-
const diff = tmpValue - flooredValue;
|
|
32
|
-
return diff;
|
|
33
|
-
}
|
|
34
|
-
export function resizeToNearestGrid(bounds, gridSize = 20) {
|
|
35
|
-
const addXMin = hasRemainder(bounds.xmin, gridSize) === 0 ? -1 : 0;
|
|
36
|
-
const addYMin = hasRemainder(bounds.ymin, gridSize) === 0 ? -1 : 0;
|
|
37
|
-
const addXMax = hasRemainder(bounds.xmax, gridSize) === 0 ? 1 : 0;
|
|
38
|
-
const addYMax = hasRemainder(bounds.ymax, gridSize) === 0 ? 1 : 0;
|
|
39
|
-
return {
|
|
40
|
-
xmin: Math.floor((bounds.xmin + addXMin) / gridSize) * gridSize,
|
|
41
|
-
ymin: Math.floor((bounds.ymin + addYMin) / gridSize) * gridSize,
|
|
42
|
-
xmax: Math.ceil((bounds.xmax + addXMax) / gridSize) * gridSize,
|
|
43
|
-
ymax: Math.ceil((bounds.ymax + addYMax) / gridSize) * gridSize,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
export function toNearestGrid(value, gridSize) {
|
|
47
|
-
return Math.floor(value / gridSize) * gridSize;
|
|
48
|
-
}
|
|
49
|
-
export function getBoundsSize(bounds) {
|
|
50
|
-
return {
|
|
51
|
-
width: bounds.xmax - bounds.xmin,
|
|
52
|
-
height: bounds.ymax - bounds.ymin,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
export function getPortType(component) {
|
|
56
|
-
const drawingCommands = component.displayProp;
|
|
57
|
-
let foundPinType = null;
|
|
58
|
-
const commands = drawingCommands.getCommands();
|
|
59
|
-
commands.some(item => {
|
|
60
|
-
if (item[0] === 'label' && item[2].has('portType')) {
|
|
61
|
-
foundPinType = item[2].get('portType');
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
return false;
|
|
65
|
-
});
|
|
66
|
-
return foundPinType;
|
|
67
|
-
}
|
|
68
|
-
export function roundValue(value) {
|
|
69
|
-
return resolveToNumericValue(new Big(value.toBigNumber().toFixed(7)));
|
|
70
|
-
}
|
|
71
|
-
export function throwWithContext(context, message) {
|
|
72
|
-
const startLine = context.start?.line;
|
|
73
|
-
const startColumn = context.start?.column;
|
|
74
|
-
const startString = startLine + ":" + startColumn;
|
|
75
|
-
const stopLine = context.stop?.line;
|
|
76
|
-
const stopColumn = context.stop?.column;
|
|
77
|
-
let stopString = "";
|
|
78
|
-
if (startLine === stopLine) {
|
|
79
|
-
stopString = stopColumn?.toString();
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
stopString = stopLine + ":" + stopString;
|
|
83
|
-
}
|
|
84
|
-
throw `Parse exception at [${startString} - ${stopString}] : ${message}`;
|
|
85
|
-
}
|
|
86
|
-
export function combineMaps(map1, map2) {
|
|
87
|
-
const newMap = new Map(map1);
|
|
88
|
-
map2.forEach((value, key) => {
|
|
89
|
-
newMap.set(key, value);
|
|
90
|
-
});
|
|
91
|
-
return newMap;
|
|
92
|
-
}
|
|
93
|
-
export function getNumberExponential(value) {
|
|
94
|
-
value = value.trim();
|
|
95
|
-
switch (value) {
|
|
96
|
-
case 'G':
|
|
97
|
-
return 9;
|
|
98
|
-
case 'M':
|
|
99
|
-
return 6;
|
|
100
|
-
case 'k':
|
|
101
|
-
case 'K':
|
|
102
|
-
return 3;
|
|
103
|
-
case 'm':
|
|
104
|
-
return -3;
|
|
105
|
-
case 'u':
|
|
106
|
-
return -6;
|
|
107
|
-
case 'n':
|
|
108
|
-
return -9;
|
|
109
|
-
case 'p':
|
|
110
|
-
return -12;
|
|
111
|
-
case 'f':
|
|
112
|
-
return -15;
|
|
113
|
-
default:
|
|
114
|
-
return 0;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
export function getNumberExponentialText(value) {
|
|
118
|
-
switch (value) {
|
|
119
|
-
case -15:
|
|
120
|
-
return 'f';
|
|
121
|
-
case -12:
|
|
122
|
-
return 'p';
|
|
123
|
-
case -9:
|
|
124
|
-
return 'n';
|
|
125
|
-
case -6:
|
|
126
|
-
return 'u';
|
|
127
|
-
case -3:
|
|
128
|
-
return 'm';
|
|
129
|
-
case 3:
|
|
130
|
-
return 'k';
|
|
131
|
-
case 6:
|
|
132
|
-
return 'M';
|
|
133
|
-
case 9:
|
|
134
|
-
return 'G';
|
|
135
|
-
case 0:
|
|
136
|
-
default:
|
|
137
|
-
return '';
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
export function resolveToNumericValue(value) {
|
|
141
|
-
if (value.toNumber() === 0) {
|
|
142
|
-
return new NumericValue(0);
|
|
143
|
-
}
|
|
144
|
-
const isNeg = value.lt(0);
|
|
145
|
-
const positiveValue = isNeg ? value.neg() : value;
|
|
146
|
-
const prefixPart = Math.floor(Math.log10(positiveValue.toNumber()) / 3);
|
|
147
|
-
let useValue = value;
|
|
148
|
-
if (prefixPart !== 0) {
|
|
149
|
-
const tmpValue1 = positiveValue.div(Math.pow(10, prefixPart * 3));
|
|
150
|
-
useValue = isNeg ? tmpValue1.neg() : tmpValue1;
|
|
151
|
-
}
|
|
152
|
-
return new NumericValue(useValue, prefixPart * 3);
|
|
153
|
-
}
|
|
154
|
-
export function isPointWithinArea(point, bounds) {
|
|
155
|
-
const [xPt, yPt] = point;
|
|
156
|
-
const [xmin, ymin, xmax, ymax] = bounds;
|
|
157
|
-
return (xPt > xmin && xPt < xmax && yPt > ymin && yPt < ymax);
|
|
158
|
-
}
|
|
159
|
-
export function areasOverlap(area1, area2) {
|
|
160
|
-
const [xmin, ymin, xmax, ymax] = area1;
|
|
161
|
-
const pt1 = [xmin, ymin];
|
|
162
|
-
const pt2 = [xmin, ymax];
|
|
163
|
-
const pt3 = [xmax, ymin];
|
|
164
|
-
const pt4 = [xmax, ymax];
|
|
165
|
-
return isPointWithinArea(pt1, area2)
|
|
166
|
-
|| isPointWithinArea(pt2, area2)
|
|
167
|
-
|| isPointWithinArea(pt3, area2)
|
|
168
|
-
|| isPointWithinArea(pt4, area2);
|
|
169
|
-
}
|
package/dist/esm/validate.mjs
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env node
|
|
2
|
-
import { program } from 'commander';
|
|
3
|
-
import figlet from 'figlet';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { readFileSync } from 'fs';
|
|
6
|
-
import { prepareSVGEnvironment } from './sizing.mjs';
|
|
7
|
-
import { getCurrentPath, getScriptText, getSemanticTokens, validateScript } from './helpers.mjs';
|
|
8
|
-
export async function validate() {
|
|
9
|
-
const { filePath } = getCurrentPath();
|
|
10
|
-
const toolSrcPath = filePath;
|
|
11
|
-
const toolDirectory = path.dirname(toolSrcPath) + '/../../';
|
|
12
|
-
const fontsPath = toolDirectory + '/fonts';
|
|
13
|
-
const defaultLibsPath = toolDirectory + '/libs';
|
|
14
|
-
const packageJson = JSON.parse(readFileSync(toolDirectory + 'package.json').toString());
|
|
15
|
-
;
|
|
16
|
-
const { version } = packageJson;
|
|
17
|
-
program
|
|
18
|
-
.description('generate graphical output from circuitscript files')
|
|
19
|
-
.version(version)
|
|
20
|
-
.option('-i, --input text <input text>', 'Input text directly')
|
|
21
|
-
.option('-f, --input-file <path>', 'Input file')
|
|
22
|
-
.option('-o, --output <path>', 'Output path')
|
|
23
|
-
.option('-c, --current-directory <path>', 'Set current directory')
|
|
24
|
-
.option('-k, --kicad-netlist <filename>', 'Create KiCad netlist')
|
|
25
|
-
.option('-w, --watch', 'Watch for file changes')
|
|
26
|
-
.option('-n, --dump-nets', 'Dump out net information')
|
|
27
|
-
.option('-d, --dump-data', 'Dump data during parsing')
|
|
28
|
-
.option('-s, --stats', 'Show stats during generation');
|
|
29
|
-
program.addHelpText('before', figlet.textSync('circuitscript', {
|
|
30
|
-
font: 'Small Slant'
|
|
31
|
-
}));
|
|
32
|
-
if (process.argv.length < 3) {
|
|
33
|
-
program.help();
|
|
34
|
-
}
|
|
35
|
-
program.parse();
|
|
36
|
-
const options = program.opts();
|
|
37
|
-
const watchFileChanges = options.watch;
|
|
38
|
-
const outputPath = options.output ?? null;
|
|
39
|
-
const dumpNets = options.dumpNets;
|
|
40
|
-
const dumpData = options.dumpData;
|
|
41
|
-
const kicadNetlist = options.kicadNetlist;
|
|
42
|
-
let currentDirectory = options.currentDirectory ?? null;
|
|
43
|
-
if (watchFileChanges) {
|
|
44
|
-
console.log('watching for file changes...');
|
|
45
|
-
}
|
|
46
|
-
await prepareSVGEnvironment(fontsPath);
|
|
47
|
-
let inputFilePath = null;
|
|
48
|
-
let scriptData;
|
|
49
|
-
if (options.input) {
|
|
50
|
-
scriptData = options.input;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
inputFilePath = options.inputFile;
|
|
54
|
-
const tmpScriptData = getScriptText(inputFilePath);
|
|
55
|
-
if (tmpScriptData === null) {
|
|
56
|
-
throw "File does not exists";
|
|
57
|
-
}
|
|
58
|
-
scriptData = tmpScriptData;
|
|
59
|
-
if (currentDirectory === null) {
|
|
60
|
-
currentDirectory = path.dirname(inputFilePath);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
const scriptOptions = {
|
|
64
|
-
currentDirectory,
|
|
65
|
-
defaultLibsPath,
|
|
66
|
-
dumpNets,
|
|
67
|
-
dumpData,
|
|
68
|
-
kicadNetlistPath: kicadNetlist,
|
|
69
|
-
showStats: options.stats,
|
|
70
|
-
};
|
|
71
|
-
const visitor = validateScript(scriptData, scriptOptions);
|
|
72
|
-
const semanticTokensVisitor = getSemanticTokens(scriptData, scriptOptions);
|
|
73
|
-
}
|
|
74
|
-
validate();
|