circuitscript 0.0.24 → 0.0.26
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/LICENSE +1 -1
- package/dist/cjs/BaseVisitor.js +485 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +256 -219
- package/dist/cjs/antlr/CircuitScriptParser.js +2891 -2151
- package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
- package/dist/cjs/draw_symbols.js +73 -22
- package/dist/cjs/execute.js +70 -78
- package/dist/cjs/export.js +91 -5
- package/dist/cjs/geometry.js +28 -8
- package/dist/cjs/globals.js +1 -2
- package/dist/cjs/helpers.js +180 -7
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/layout.js +8 -0
- package/dist/cjs/lexer.js +19 -22
- package/dist/cjs/main.js +27 -20
- package/dist/cjs/objects/ClassComponent.js +4 -0
- package/dist/cjs/objects/ExecutionScope.js +1 -0
- package/dist/cjs/objects/types.js +7 -1
- package/dist/cjs/parser.js +29 -258
- package/dist/cjs/render.js +1 -1
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +601 -823
- package/dist/esm/BaseVisitor.mjs +486 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +231 -218
- package/dist/esm/antlr/CircuitScriptParser.mjs +2852 -2144
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +13 -4
- package/dist/esm/draw_symbols.mjs +74 -23
- package/dist/esm/execute.mjs +70 -75
- package/dist/esm/export.mjs +89 -6
- package/dist/esm/geometry.mjs +28 -8
- package/dist/esm/globals.mjs +1 -2
- package/dist/esm/helpers.mjs +171 -9
- package/dist/esm/index.mjs +2 -0
- package/dist/esm/layout.mjs +8 -0
- package/dist/esm/lexer.mjs +10 -10
- package/dist/esm/main.mjs +28 -21
- package/dist/esm/objects/ClassComponent.mjs +4 -0
- package/dist/esm/objects/ExecutionScope.mjs +1 -0
- package/dist/esm/objects/types.mjs +6 -0
- package/dist/esm/parser.mjs +25 -230
- package/dist/esm/render.mjs +2 -2
- package/dist/esm/validate.mjs +74 -0
- package/dist/esm/visitor.mjs +415 -643
- package/dist/types/BaseVisitor.d.ts +66 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +37 -29
- package/dist/types/antlr/CircuitScriptParser.d.ts +606 -494
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +78 -60
- package/dist/types/draw_symbols.d.ts +12 -3
- package/dist/types/execute.d.ts +5 -10
- package/dist/types/export.d.ts +27 -1
- package/dist/types/geometry.d.ts +4 -0
- package/dist/types/globals.d.ts +2 -3
- package/dist/types/helpers.d.ts +32 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lexer.d.ts +2 -2
- package/dist/types/objects/ClassComponent.d.ts +1 -0
- package/dist/types/objects/ExecutionScope.d.ts +4 -1
- package/dist/types/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +15 -28
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +43 -95
- package/fonts/Inter-Bold.ttf +0 -0
- package/fonts/Inter-Regular.ttf +0 -0
- package/fonts/OpenSans-Regular.ttf +0 -0
- package/fonts/Roboto-Regular.ttf +0 -0
- package/libs/lib.cst +184 -0
- package/package.json +11 -6
package/dist/cjs/export.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateKiCADNetList = void 0;
|
|
3
|
+
exports.SExpObject = exports._id = exports.IdObject = exports.printTree = exports.generateKiCADNetList = void 0;
|
|
4
4
|
const globals_js_1 = require("./globals.js");
|
|
5
5
|
const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
|
|
6
6
|
function generateKiCADNetList(netlist) {
|
|
7
7
|
const componentsList = [];
|
|
8
8
|
const nets = {};
|
|
9
|
+
const missingFootprints = [];
|
|
9
10
|
netlist.forEach(entry => {
|
|
10
11
|
const { instance, pins } = entry;
|
|
11
12
|
if (instance.assignedRefDes !== null) {
|
|
@@ -25,7 +26,10 @@ function generateKiCADNetList(netlist) {
|
|
|
25
26
|
instance.parameters.get('footprint')]);
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
28
|
-
|
|
29
|
+
missingFootprints.push({
|
|
30
|
+
refdes: instance.assignedRefDes,
|
|
31
|
+
instanceName: instance.instanceName
|
|
32
|
+
});
|
|
29
33
|
}
|
|
30
34
|
componentsList.push(instanceDetails);
|
|
31
35
|
for (const key in pins) {
|
|
@@ -66,18 +70,22 @@ function generateKiCADNetList(netlist) {
|
|
|
66
70
|
]);
|
|
67
71
|
counter++;
|
|
68
72
|
}
|
|
73
|
+
const dateString = new Date().toISOString().slice(0, 10);
|
|
69
74
|
const tree = [
|
|
70
75
|
Id("export"),
|
|
71
76
|
[Id("version"), "E"],
|
|
72
77
|
[Id("design"),
|
|
73
|
-
[Id("source"), "/
|
|
74
|
-
[Id("date"),
|
|
78
|
+
[Id("source"), "/unknown-file"],
|
|
79
|
+
[Id("date"), dateString],
|
|
75
80
|
[Id("tool"), "circuitscript-to-kicad"]
|
|
76
81
|
],
|
|
77
82
|
[Id('components'), ...componentsList],
|
|
78
83
|
[Id('nets'), ...netItems]
|
|
79
84
|
];
|
|
80
|
-
return
|
|
85
|
+
return {
|
|
86
|
+
tree,
|
|
87
|
+
missingFootprints
|
|
88
|
+
};
|
|
81
89
|
}
|
|
82
90
|
exports.generateKiCADNetList = generateKiCADNetList;
|
|
83
91
|
function printTree(tree, level = 0) {
|
|
@@ -99,6 +107,7 @@ function printTree(tree, level = 0) {
|
|
|
99
107
|
}
|
|
100
108
|
return "(" + output.join(" ") + ")";
|
|
101
109
|
}
|
|
110
|
+
exports.printTree = printTree;
|
|
102
111
|
function Id(name) {
|
|
103
112
|
return new IdObject(name);
|
|
104
113
|
}
|
|
@@ -107,3 +116,80 @@ class IdObject {
|
|
|
107
116
|
this.keyName = keyName;
|
|
108
117
|
}
|
|
109
118
|
}
|
|
119
|
+
exports.IdObject = IdObject;
|
|
120
|
+
function _id(key) {
|
|
121
|
+
return new IdObject(key);
|
|
122
|
+
}
|
|
123
|
+
exports._id = _id;
|
|
124
|
+
class SExpObject {
|
|
125
|
+
constructor(object) {
|
|
126
|
+
this.object = object;
|
|
127
|
+
}
|
|
128
|
+
getKey(object = null) {
|
|
129
|
+
object = object ?? this.object;
|
|
130
|
+
return object[0];
|
|
131
|
+
}
|
|
132
|
+
getValue(object = null) {
|
|
133
|
+
object = object ?? this.object;
|
|
134
|
+
return object.slice(1);
|
|
135
|
+
}
|
|
136
|
+
getJSON(object = null) {
|
|
137
|
+
object = object ?? this.object;
|
|
138
|
+
if (!Array.isArray(object)) {
|
|
139
|
+
return object;
|
|
140
|
+
}
|
|
141
|
+
const properties = {};
|
|
142
|
+
const keyName = object[0].keyName;
|
|
143
|
+
if (object.length === 2) {
|
|
144
|
+
properties[keyName] = this.getJSON(object[1]);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const innerProps = {};
|
|
148
|
+
this.getValue(object).forEach(item => {
|
|
149
|
+
const tmpValue = this.getJSON(item);
|
|
150
|
+
if (typeof tmpValue === "object") {
|
|
151
|
+
for (const key in tmpValue) {
|
|
152
|
+
if (innerProps[key]) {
|
|
153
|
+
if (!Array.isArray(innerProps[key])) {
|
|
154
|
+
innerProps[key] = [innerProps[key]];
|
|
155
|
+
}
|
|
156
|
+
innerProps[key].push(tmpValue[key]);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
innerProps[key] = tmpValue[key];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
innerProps[item[0].keyName] = tmpValue;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
properties[keyName] = innerProps;
|
|
168
|
+
}
|
|
169
|
+
return properties;
|
|
170
|
+
}
|
|
171
|
+
getWithId(id, object = null) {
|
|
172
|
+
object = object ?? this.object;
|
|
173
|
+
let result = null;
|
|
174
|
+
const key = object[0];
|
|
175
|
+
if (key.keyName === id) {
|
|
176
|
+
return object;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.getValue(object).some(item => {
|
|
180
|
+
if (Array.isArray(item)) {
|
|
181
|
+
result = this.getWithId(id, item);
|
|
182
|
+
if (result !== null) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
print() {
|
|
192
|
+
console.log(printTree(this.object));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.SExpObject = SExpObject;
|
package/dist/cjs/geometry.js
CHANGED
|
@@ -53,8 +53,12 @@ class Label extends core_1.default.Polygon {
|
|
|
53
53
|
return new Label(id, useText, [x, y], polygon, style, box);
|
|
54
54
|
}
|
|
55
55
|
rotate(angle, origin) {
|
|
56
|
-
const
|
|
57
|
-
return new Label(this.id, this.text, this.anchorPoint,
|
|
56
|
+
const feature = super.rotate(angle, origin);
|
|
57
|
+
return new Label(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds);
|
|
58
|
+
}
|
|
59
|
+
transform(matrix) {
|
|
60
|
+
const feature = super.transform(matrix);
|
|
61
|
+
return new Label(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds);
|
|
58
62
|
}
|
|
59
63
|
getLabelPosition() {
|
|
60
64
|
return this.anchorPoint;
|
|
@@ -104,6 +108,10 @@ class Geometry {
|
|
|
104
108
|
const angleRads = angleDegrees * Math.PI / 180;
|
|
105
109
|
return feature.rotate(angleRads, Geometry.point(center[0], center[1]));
|
|
106
110
|
}
|
|
111
|
+
static flip(feature, flipX, flipY) {
|
|
112
|
+
const flipMatrix = (new core_1.default.Matrix()).scale(flipX === 0 ? 1 : -1, flipY == 0 ? 1 : -1);
|
|
113
|
+
return feature.transform(flipMatrix);
|
|
114
|
+
}
|
|
107
115
|
static groupRotate(features, angle, center) {
|
|
108
116
|
const angleRads = angle * Math.PI / 180;
|
|
109
117
|
const rotateAboutPoint = Geometry.point(center[0], center[1]);
|
|
@@ -111,6 +119,12 @@ class Geometry {
|
|
|
111
119
|
return feature.rotate(angleRads, rotateAboutPoint);
|
|
112
120
|
});
|
|
113
121
|
}
|
|
122
|
+
static groupFlip(features, flipX, flipY) {
|
|
123
|
+
const flipMatrix = (new core_1.default.Matrix()).scale(flipX === 0 ? 1 : -1, flipY == 0 ? 1 : -1);
|
|
124
|
+
return features.map(feature => {
|
|
125
|
+
return feature.transform(flipMatrix);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
114
128
|
static groupBounds(features) {
|
|
115
129
|
let minX = Number.POSITIVE_INFINITY;
|
|
116
130
|
let minY = Number.POSITIVE_INFINITY;
|
|
@@ -171,9 +185,7 @@ class Geometry {
|
|
|
171
185
|
}
|
|
172
186
|
const startPoint = getArcPointRadians(x, y, radius, item.startAngle);
|
|
173
187
|
const endPoint = getArcPointRadians(x, y, radius, useEndAngle);
|
|
174
|
-
paths.push('M
|
|
175
|
-
+ 'A ' + radius + ' ' + radius + ' 0 1 1 '
|
|
176
|
-
+ endPoint[0] + ' ' + endPoint[1] + extraEnd);
|
|
188
|
+
paths.push('M', startPoint[0], startPoint[1], 'A', radius, radius, 0, 1, 1, endPoint[0], endPoint[1], extraEnd);
|
|
177
189
|
}
|
|
178
190
|
else {
|
|
179
191
|
const coords = Geometry.getCoords(item);
|
|
@@ -183,19 +195,27 @@ class Geometry {
|
|
|
183
195
|
for (let i = 0; i < coords.length; i++) {
|
|
184
196
|
const [x, y] = coords[i];
|
|
185
197
|
const command = (i === 0) ? 'M' : 'L';
|
|
186
|
-
path.push(`${command}
|
|
198
|
+
path.push(`${command}`, x, y);
|
|
187
199
|
}
|
|
188
200
|
if (isClosedPolygon) {
|
|
189
201
|
path.push('Z');
|
|
190
202
|
}
|
|
191
|
-
paths.push(path
|
|
203
|
+
paths.push(...path);
|
|
192
204
|
}
|
|
193
205
|
});
|
|
194
206
|
return {
|
|
195
|
-
path:
|
|
207
|
+
path: this.roundPathValues(paths),
|
|
196
208
|
isClosedPolygon,
|
|
197
209
|
};
|
|
198
210
|
}
|
|
211
|
+
static roundPathValues(pathItems) {
|
|
212
|
+
return pathItems.map(item => {
|
|
213
|
+
if (typeof item === 'number') {
|
|
214
|
+
return (+item.toFixed(7)).toString();
|
|
215
|
+
}
|
|
216
|
+
return item;
|
|
217
|
+
}).join(" ");
|
|
218
|
+
}
|
|
199
219
|
static angle(dx, dy) {
|
|
200
220
|
const line = new core_1.default.Segment(new core_1.default.Point(0, 0), new core_1.default.Point(dx, dy));
|
|
201
221
|
return line.slope * 180 / Math.PI;
|
package/dist/cjs/globals.js
CHANGED
|
@@ -13,8 +13,6 @@ var GlobalNames;
|
|
|
13
13
|
exports.NoNetText = 'NO_NET';
|
|
14
14
|
var ParamKeys;
|
|
15
15
|
(function (ParamKeys) {
|
|
16
|
-
ParamKeys["__is_net"] = "__is_net";
|
|
17
|
-
ParamKeys["__is_label"] = "__is_label";
|
|
18
16
|
ParamKeys["priority"] = "priority";
|
|
19
17
|
ParamKeys["net_name"] = "net_name";
|
|
20
18
|
})(ParamKeys || (exports.ParamKeys = ParamKeys = {}));
|
|
@@ -50,6 +48,7 @@ var ReferenceTypes;
|
|
|
50
48
|
ReferenceTypes["value"] = "value";
|
|
51
49
|
ReferenceTypes["variable"] = "variable";
|
|
52
50
|
ReferenceTypes["instance"] = "instance";
|
|
51
|
+
ReferenceTypes["pinType"] = "pinType";
|
|
53
52
|
})(ReferenceTypes || (exports.ReferenceTypes = ReferenceTypes = {}));
|
|
54
53
|
var BlockTypes;
|
|
55
54
|
(function (BlockTypes) {
|
package/dist/cjs/helpers.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCurrentPath = exports.detectJSModuleType = exports.renderScript = exports.JSModuleType = void 0;
|
|
6
|
+
exports.getPackageVersion = exports.getDefaultLibsPath = exports.getFontsPath = exports.getCurrentPath = exports.detectJSModuleType = exports.renderScript = exports.validateScript = exports.ParseErrorStrategy = exports.getSemanticTokens = exports.getScriptText = exports.prepareFile = exports.JSModuleType = void 0;
|
|
4
7
|
const fs_1 = require("fs");
|
|
5
8
|
const export_js_1 = require("./export.js");
|
|
6
9
|
const layout_js_1 = require("./layout.js");
|
|
@@ -10,17 +13,164 @@ const render_js_1 = require("./render.js");
|
|
|
10
13
|
const utils_js_1 = require("./utils.js");
|
|
11
14
|
const visitor_js_1 = require("./visitor.js");
|
|
12
15
|
const this_file_1 = require("this-file");
|
|
16
|
+
const SymbolValidatorVisitor_js_1 = require("./SymbolValidatorVisitor.js");
|
|
17
|
+
const antlr4ng_1 = require("antlr4ng");
|
|
18
|
+
const lexer_js_1 = require("./lexer.js");
|
|
19
|
+
const CircuitScriptParser_js_1 = require("./antlr/CircuitScriptParser.js");
|
|
20
|
+
const SemanticTokenVisitor_js_1 = require("./SemanticTokenVisitor.js");
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
13
22
|
var JSModuleType;
|
|
14
23
|
(function (JSModuleType) {
|
|
15
24
|
JSModuleType["CommonJs"] = "cjs";
|
|
16
25
|
JSModuleType["ESM"] = "mjs";
|
|
17
26
|
})(JSModuleType || (exports.JSModuleType = JSModuleType = {}));
|
|
27
|
+
function prepareFile(textData) {
|
|
28
|
+
const chars = antlr4ng_1.CharStream.fromString(textData);
|
|
29
|
+
const lexer = new lexer_js_1.MainLexer(chars);
|
|
30
|
+
const lexerTimer = new utils_js_1.SimpleStopwatch();
|
|
31
|
+
const tokens = new antlr4ng_1.CommonTokenStream(lexer);
|
|
32
|
+
tokens.fill();
|
|
33
|
+
const lexerTimeTaken = lexerTimer.lap();
|
|
34
|
+
const parser = new CircuitScriptParser_js_1.CircuitScriptParser(tokens);
|
|
35
|
+
return {
|
|
36
|
+
parser,
|
|
37
|
+
lexer,
|
|
38
|
+
lexerTimeTaken,
|
|
39
|
+
tokens
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.prepareFile = prepareFile;
|
|
43
|
+
function getScriptText(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
return (0, fs_1.readFileSync)(filePath, { encoding: 'utf-8' });
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.getScriptText = getScriptText;
|
|
52
|
+
function getSemanticTokens(scriptData, options) {
|
|
53
|
+
const { parser, lexer, tokens } = prepareFile(scriptData);
|
|
54
|
+
const tree = parser.script();
|
|
55
|
+
const { currentDirectory = null, defaultLibsPath, } = options;
|
|
56
|
+
const visitor = new SemanticTokenVisitor_js_1.SemanticTokensVisitor(true, null, currentDirectory, defaultLibsPath, lexer, scriptData);
|
|
57
|
+
parser.removeErrorListeners();
|
|
58
|
+
visitor.onImportFile = (visitor, textData) => {
|
|
59
|
+
let hasError = false;
|
|
60
|
+
let hasParseError = false;
|
|
61
|
+
if (textData !== null) {
|
|
62
|
+
const { parser } = prepareFile(textData);
|
|
63
|
+
const tree = parser.script();
|
|
64
|
+
try {
|
|
65
|
+
visitor.visit(tree);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.log('Error while parsing: ', err);
|
|
69
|
+
hasParseError = true;
|
|
70
|
+
hasError = true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log('File does not exist');
|
|
75
|
+
hasError = true;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
hasError, hasParseError
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
visitor.visit(tree);
|
|
82
|
+
const semanticTokens = visitor.getTokens();
|
|
83
|
+
const parsedTokens = (0, SemanticTokenVisitor_js_1.prepareTokens)(tokens.getTokens(), lexer, scriptData);
|
|
84
|
+
const finalParsedTokens = [];
|
|
85
|
+
parsedTokens.forEach(token => {
|
|
86
|
+
const location = `${token.line}_${token.column}`;
|
|
87
|
+
if (semanticTokens.has(location)) {
|
|
88
|
+
finalParsedTokens.push(semanticTokens.get(location));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
finalParsedTokens.push(token);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
visitor,
|
|
96
|
+
parsedTokens: finalParsedTokens
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
exports.getSemanticTokens = getSemanticTokens;
|
|
100
|
+
class TokenErrorListener extends antlr4ng_1.BaseErrorListener {
|
|
101
|
+
syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
|
|
102
|
+
console.log(msg);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
class ParseErrorStrategy extends antlr4ng_1.DefaultErrorStrategy {
|
|
106
|
+
reportUnwantedToken(recognizer) {
|
|
107
|
+
if (this.inErrorRecoveryMode(recognizer)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.beginErrorCondition(recognizer);
|
|
111
|
+
const t = recognizer.getCurrentToken();
|
|
112
|
+
const tokenName = this.getTokenErrorDisplay(t);
|
|
113
|
+
const msg = "extraneous input " + tokenName;
|
|
114
|
+
recognizer.notifyErrorListeners(msg, t, null);
|
|
115
|
+
this.endErrorCondition(recognizer);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.ParseErrorStrategy = ParseErrorStrategy;
|
|
119
|
+
function validateScript(scriptData, options) {
|
|
120
|
+
const { parser } = prepareFile(scriptData);
|
|
121
|
+
parser.removeErrorListeners();
|
|
122
|
+
parser.errorHandler = new ParseErrorStrategy();
|
|
123
|
+
parser.addErrorListener(new TokenErrorListener());
|
|
124
|
+
const tree = parser.script();
|
|
125
|
+
const { currentDirectory = null, defaultLibsPath, } = options;
|
|
126
|
+
const visitor = new SymbolValidatorVisitor_js_1.SymbolValidatorVisitor(true, null, currentDirectory, defaultLibsPath);
|
|
127
|
+
visitor.onImportFile = (visitor, textData) => {
|
|
128
|
+
let hasError = false;
|
|
129
|
+
let hasParseError = false;
|
|
130
|
+
if (textData !== null) {
|
|
131
|
+
const { parser } = prepareFile(textData);
|
|
132
|
+
const tree = parser.script();
|
|
133
|
+
try {
|
|
134
|
+
visitor.visit(tree);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
console.log('got an error while parsing tree: ', err);
|
|
138
|
+
hasParseError = true;
|
|
139
|
+
hasError = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.log('file does not exist!');
|
|
144
|
+
hasError = true;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
hasError, hasParseError
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
visitor.visit(tree);
|
|
151
|
+
const symbolTable = visitor.getSymbols();
|
|
152
|
+
symbolTable.clearUndefined();
|
|
153
|
+
const visitorResolver = new SymbolValidatorVisitor_js_1.SymbolValidatorResolveVisitor(true, null, currentDirectory, defaultLibsPath);
|
|
154
|
+
visitorResolver.setSymbols(visitor.getSymbols());
|
|
155
|
+
visitorResolver.onImportFile = visitor.onImportFile;
|
|
156
|
+
visitorResolver.visit(tree);
|
|
157
|
+
return visitorResolver;
|
|
158
|
+
}
|
|
159
|
+
exports.validateScript = validateScript;
|
|
18
160
|
function renderScript(scriptData, outputPath, options) {
|
|
19
161
|
const { currentDirectory = null, defaultLibsPath, dumpNets = false, dumpData = false, kicadNetlistPath = null, showStats = false } = options;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
162
|
+
const onErrorHandler = (line, column, message, error) => {
|
|
163
|
+
if (error instanceof visitor_js_1.VisitorExecutionException) {
|
|
164
|
+
console.log('Error', line, column, message, error.errorMessage);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const visitor = new visitor_js_1.ParserVisitor(true, onErrorHandler, currentDirectory, defaultLibsPath);
|
|
168
|
+
visitor.onImportFile = (visitor, fileData) => {
|
|
169
|
+
const { hasError, hasParseError } = (0, parser_js_1.parseFileWithVisitor)(visitor, fileData);
|
|
170
|
+
return { hasError, hasParseError };
|
|
171
|
+
};
|
|
172
|
+
visitor.log('reading file');
|
|
173
|
+
visitor.log('done reading file');
|
|
24
174
|
const { tree, parser, hasParseError, hasError, parserTimeTaken, lexerTimeTaken } = (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
|
|
25
175
|
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
26
176
|
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
@@ -38,8 +188,11 @@ function renderScript(scriptData, outputPath, options) {
|
|
|
38
188
|
console.log('Error during annotation: ', err);
|
|
39
189
|
}
|
|
40
190
|
if (kicadNetlistPath) {
|
|
41
|
-
const kicadNetList = (0, export_js_1.generateKiCADNetList)(visitor.getNetList());
|
|
42
|
-
|
|
191
|
+
const { tree: kicadNetList, missingFootprints } = (0, export_js_1.generateKiCADNetList)(visitor.getNetList());
|
|
192
|
+
missingFootprints.forEach(entry => {
|
|
193
|
+
console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
|
|
194
|
+
});
|
|
195
|
+
(0, fs_1.writeFileSync)(kicadNetlistPath, (0, export_js_1.printTree)(kicadNetList));
|
|
43
196
|
console.log('Generated KiCad netlist file');
|
|
44
197
|
}
|
|
45
198
|
const { sequence, nets } = visitor.getGraph();
|
|
@@ -97,3 +250,23 @@ function getCurrentPath() {
|
|
|
97
250
|
return { filePath: filename };
|
|
98
251
|
}
|
|
99
252
|
exports.getCurrentPath = getCurrentPath;
|
|
253
|
+
function getToolsPath() {
|
|
254
|
+
const { filePath } = getCurrentPath();
|
|
255
|
+
return path_1.default.normalize(path_1.default.dirname(filePath) + '/../../');
|
|
256
|
+
}
|
|
257
|
+
function getFontsPath() {
|
|
258
|
+
const toolsPath = getToolsPath();
|
|
259
|
+
return path_1.default.normalize(toolsPath + "fonts");
|
|
260
|
+
}
|
|
261
|
+
exports.getFontsPath = getFontsPath;
|
|
262
|
+
function getDefaultLibsPath() {
|
|
263
|
+
const toolsPath = getToolsPath();
|
|
264
|
+
return path_1.default.normalize(toolsPath + "libs");
|
|
265
|
+
}
|
|
266
|
+
exports.getDefaultLibsPath = getDefaultLibsPath;
|
|
267
|
+
function getPackageVersion() {
|
|
268
|
+
const packageJson = JSON.parse((0, fs_1.readFileSync)(getToolsPath() + 'package.json').toString());
|
|
269
|
+
const { version } = packageJson;
|
|
270
|
+
return version;
|
|
271
|
+
}
|
|
272
|
+
exports.getPackageVersion = getPackageVersion;
|
package/dist/cjs/index.js
CHANGED
|
@@ -27,3 +27,5 @@ __exportStar(require("./parser.js"), exports);
|
|
|
27
27
|
__exportStar(require("./render.js"), exports);
|
|
28
28
|
__exportStar(require("./utils.js"), exports);
|
|
29
29
|
__exportStar(require("./visitor.js"), exports);
|
|
30
|
+
__exportStar(require("./sizing.js"), exports);
|
|
31
|
+
__exportStar(require("./objects/types.js"), exports);
|
package/dist/cjs/layout.js
CHANGED
|
@@ -395,6 +395,14 @@ class LayoutEngine {
|
|
|
395
395
|
didSetAngle = true;
|
|
396
396
|
tmpSymbol.angle = component.parameters.get('angle');
|
|
397
397
|
}
|
|
398
|
+
if (component.parameters.has('flipX')) {
|
|
399
|
+
tmpSymbol.flipX =
|
|
400
|
+
component.parameters.get('flipX');
|
|
401
|
+
}
|
|
402
|
+
if (component.parameters.has('flipY')) {
|
|
403
|
+
tmpSymbol.flipY =
|
|
404
|
+
component.parameters.get('flipY');
|
|
405
|
+
}
|
|
398
406
|
if (tmpSymbol instanceof draw_symbols_js_1.SymbolCustom && widthProp) {
|
|
399
407
|
tmpSymbol.bodyWidth = widthProp;
|
|
400
408
|
}
|
package/dist/cjs/lexer.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.MainLexer = void 0;
|
|
7
|
-
const
|
|
8
|
-
const CircuitScriptParser_js_1 =
|
|
9
|
-
const CircuitScriptLexer_js_1 =
|
|
10
|
-
class MainLexer extends CircuitScriptLexer_js_1.
|
|
4
|
+
const antlr4ng_1 = require("antlr4ng");
|
|
5
|
+
const CircuitScriptParser_js_1 = require("./antlr/CircuitScriptParser.js");
|
|
6
|
+
const CircuitScriptLexer_js_1 = require("./antlr/CircuitScriptLexer.js");
|
|
7
|
+
class MainLexer extends CircuitScriptLexer_js_1.CircuitScriptLexer {
|
|
11
8
|
constructor(input) {
|
|
12
9
|
super(input);
|
|
13
10
|
this.tokens = [];
|
|
@@ -25,38 +22,38 @@ class MainLexer extends CircuitScriptLexer_js_1.default {
|
|
|
25
22
|
this.tokens.push(token);
|
|
26
23
|
}
|
|
27
24
|
nextToken() {
|
|
28
|
-
if (this.
|
|
25
|
+
if (this.inputStream.LA(1) === CircuitScriptParser_js_1.CircuitScriptParser.EOF && this.indents.length) {
|
|
29
26
|
this.tokens = this.tokens.filter(function (val) {
|
|
30
|
-
return val.type !== CircuitScriptParser_js_1.
|
|
27
|
+
return val.type !== CircuitScriptParser_js_1.CircuitScriptParser.EOF;
|
|
31
28
|
});
|
|
32
|
-
this.emitToken(this.commonToken(CircuitScriptParser_js_1.
|
|
29
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, "\n"));
|
|
33
30
|
while (this.indents.length) {
|
|
34
31
|
this.emitToken(this.createDedent());
|
|
35
32
|
this.indents.pop();
|
|
36
33
|
}
|
|
37
|
-
this.emitToken(this.commonToken(CircuitScriptParser_js_1.
|
|
34
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.EOF, "<EOF>"));
|
|
38
35
|
}
|
|
39
36
|
const next = super.nextToken();
|
|
40
37
|
return this.tokens.length ? this.tokens.shift() : next;
|
|
41
38
|
}
|
|
42
39
|
createDedent() {
|
|
43
|
-
return this.commonToken(CircuitScriptParser_js_1.
|
|
40
|
+
return this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.DEDENT, "");
|
|
44
41
|
}
|
|
45
42
|
getCharIndex() {
|
|
46
|
-
return this.
|
|
43
|
+
return this.inputStream.index;
|
|
47
44
|
}
|
|
48
45
|
commonToken(type, text) {
|
|
49
46
|
const stop = this.getCharIndex() - 1;
|
|
50
47
|
const start = text.length ? stop - text.length + 1 : stop;
|
|
51
|
-
const token =
|
|
52
|
-
let tokenTypeString;
|
|
53
|
-
if (type === CircuitScriptParser_js_1.
|
|
48
|
+
const token = antlr4ng_1.CommonToken.fromSource([this, this.inputStream], type, 0, start, stop);
|
|
49
|
+
let tokenTypeString = null;
|
|
50
|
+
if (type === CircuitScriptParser_js_1.CircuitScriptParser.INDENT) {
|
|
54
51
|
tokenTypeString = "indent";
|
|
55
52
|
}
|
|
56
|
-
else if (type === CircuitScriptParser_js_1.
|
|
53
|
+
else if (type === CircuitScriptParser_js_1.CircuitScriptParser.DEDENT) {
|
|
57
54
|
tokenTypeString = "dedent";
|
|
58
55
|
}
|
|
59
|
-
if (tokenTypeString) {
|
|
56
|
+
if (tokenTypeString !== null) {
|
|
60
57
|
token.text = tokenTypeString;
|
|
61
58
|
}
|
|
62
59
|
return token;
|
|
@@ -85,14 +82,14 @@ class MainLexer extends CircuitScriptLexer_js_1.default {
|
|
|
85
82
|
onNewLine() {
|
|
86
83
|
const newLine = this.text.replace(/[^\r\n]+/g, '');
|
|
87
84
|
const spaces = this.text.replace(/[\r\n]+/g, '');
|
|
88
|
-
const next = this.
|
|
89
|
-
const nextnext = this.
|
|
85
|
+
const next = this.inputStream.LA(1);
|
|
86
|
+
const nextnext = this.inputStream.LA(2);
|
|
90
87
|
if (this.opened > 0 || (nextnext != -1 &&
|
|
91
88
|
(next === 13 || next === 10 || next === 35))) {
|
|
92
89
|
this.skip();
|
|
93
90
|
}
|
|
94
91
|
else {
|
|
95
|
-
this.emitToken(this.commonToken(CircuitScriptParser_js_1.
|
|
92
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.NEWLINE, newLine));
|
|
96
93
|
const indent = this.getIndentationCount(spaces);
|
|
97
94
|
const previous = this.indents.length ? this.indents[this.indents.length - 1] : 0;
|
|
98
95
|
if (indent === previous) {
|
|
@@ -100,7 +97,7 @@ class MainLexer extends CircuitScriptLexer_js_1.default {
|
|
|
100
97
|
}
|
|
101
98
|
else if (indent > previous) {
|
|
102
99
|
this.indents.push(indent);
|
|
103
|
-
this.emitToken(this.commonToken(CircuitScriptParser_js_1.
|
|
100
|
+
this.emitToken(this.commonToken(CircuitScriptParser_js_1.CircuitScriptParser.INDENT, spaces));
|
|
104
101
|
}
|
|
105
102
|
else {
|
|
106
103
|
while (this.indents.length && this.indents[this.indents.length - 1] > indent) {
|
package/dist/cjs/main.js
CHANGED
|
@@ -11,20 +11,15 @@ const fs_1 = require("fs");
|
|
|
11
11
|
const sizing_js_1 = require("./sizing.js");
|
|
12
12
|
const helpers_js_1 = require("./helpers.js");
|
|
13
13
|
async function main() {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const fontsPath = toolDirectory + '/fonts';
|
|
18
|
-
const defaultLibsPath = toolDirectory + '/libs';
|
|
19
|
-
const packageJson = JSON.parse((0, fs_1.readFileSync)(toolDirectory + 'package.json').toString());
|
|
20
|
-
;
|
|
21
|
-
const { version } = packageJson;
|
|
14
|
+
const fontsPath = (0, helpers_js_1.getFontsPath)();
|
|
15
|
+
const defaultLibsPath = (0, helpers_js_1.getDefaultLibsPath)();
|
|
16
|
+
const version = (0, helpers_js_1.getPackageVersion)();
|
|
22
17
|
commander_1.program
|
|
23
18
|
.description('generate graphical output from circuitscript files')
|
|
24
19
|
.version(version)
|
|
20
|
+
.argument('[input path]', 'Input path')
|
|
21
|
+
.argument('[output path]', 'Output path')
|
|
25
22
|
.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
23
|
.option('-c, --current-directory <path>', 'Set current directory')
|
|
29
24
|
.option('-k, --kicad-netlist <filename>', 'Create KiCad netlist')
|
|
30
25
|
.option('-w, --watch', 'Watch for file changes')
|
|
@@ -39,8 +34,8 @@ async function main() {
|
|
|
39
34
|
}
|
|
40
35
|
commander_1.program.parse();
|
|
41
36
|
const options = commander_1.program.opts();
|
|
37
|
+
const args = commander_1.program.args;
|
|
42
38
|
const watchFileChanges = options.watch;
|
|
43
|
-
const outputPath = options.output ?? null;
|
|
44
39
|
const dumpNets = options.dumpNets;
|
|
45
40
|
const dumpData = options.dumpData;
|
|
46
41
|
const kicadNetlist = options.kicadNetlist;
|
|
@@ -49,19 +44,27 @@ async function main() {
|
|
|
49
44
|
console.log('watching for file changes...');
|
|
50
45
|
}
|
|
51
46
|
await (0, sizing_js_1.prepareSVGEnvironment)(fontsPath);
|
|
52
|
-
let inputFilePath =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
47
|
+
let inputFilePath = "";
|
|
48
|
+
if (args.length > 2) {
|
|
49
|
+
console.log("Error: Extra arguments passed");
|
|
50
|
+
return;
|
|
56
51
|
}
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
let scriptData;
|
|
53
|
+
if (args.length > 0 && args[0]) {
|
|
54
|
+
inputFilePath = args[0];
|
|
59
55
|
scriptData = (0, fs_1.readFileSync)(inputFilePath, { encoding: 'utf-8' });
|
|
60
56
|
if (currentDirectory === null) {
|
|
61
57
|
currentDirectory = path_1.default.dirname(inputFilePath);
|
|
62
58
|
}
|
|
63
59
|
}
|
|
64
|
-
|
|
60
|
+
else if (options.input) {
|
|
61
|
+
scriptData = options.input;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log("Error: No input provided");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const scriptOptions = {
|
|
65
68
|
currentDirectory,
|
|
66
69
|
defaultLibsPath,
|
|
67
70
|
dumpNets,
|
|
@@ -69,7 +72,11 @@ async function main() {
|
|
|
69
72
|
kicadNetlistPath: kicadNetlist,
|
|
70
73
|
showStats: options.stats,
|
|
71
74
|
};
|
|
72
|
-
|
|
75
|
+
let outputPath = null;
|
|
76
|
+
if (args.length > 0 && args[1]) {
|
|
77
|
+
outputPath = args[1];
|
|
78
|
+
}
|
|
79
|
+
const output = (0, helpers_js_1.renderScript)(scriptData, outputPath, scriptOptions);
|
|
73
80
|
if (outputPath === null && output) {
|
|
74
81
|
console.log(output);
|
|
75
82
|
}
|
|
@@ -77,7 +84,7 @@ async function main() {
|
|
|
77
84
|
(0, fs_1.watch)(inputFilePath, event => {
|
|
78
85
|
if (event === 'change') {
|
|
79
86
|
const scriptData = (0, fs_1.readFileSync)(inputFilePath, { encoding: 'utf-8' });
|
|
80
|
-
(0, helpers_js_1.renderScript)(scriptData, outputPath,
|
|
87
|
+
(0, helpers_js_1.renderScript)(scriptData, outputPath, scriptOptions);
|
|
81
88
|
console.log('done');
|
|
82
89
|
}
|
|
83
90
|
});
|