circuitscript 0.1.23 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/BaseVisitor.js +35 -23
- package/dist/cjs/BomGeneration.js +167 -0
- package/dist/cjs/ComponentMatchConditions.js +116 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +247 -244
- package/dist/cjs/antlr/CircuitScriptParser.js +1476 -825
- package/dist/cjs/builtinMethods.js +6 -1
- package/dist/cjs/execute.js +27 -16
- package/dist/cjs/graph.js +10 -9
- package/dist/cjs/helpers.js +23 -4
- package/dist/cjs/layout.js +14 -13
- package/dist/cjs/main.js +17 -1
- package/dist/cjs/objects/ExecutionScope.js +3 -0
- package/dist/cjs/objects/PinDefinition.js +11 -1
- package/dist/cjs/objects/types.js +6 -4
- package/dist/cjs/rules-check/no-connect-on-connected-pin.js +81 -0
- package/dist/cjs/rules-check/rules.js +74 -0
- package/dist/cjs/rules-check/unconnected-pins.js +52 -0
- package/dist/cjs/visitor.js +121 -5
- package/dist/esm/BaseVisitor.js +35 -23
- package/dist/esm/BomGeneration.js +137 -0
- package/dist/esm/ComponentMatchConditions.js +109 -0
- package/dist/esm/antlr/CircuitScriptLexer.js +247 -244
- package/dist/esm/antlr/CircuitScriptParser.js +1471 -824
- package/dist/esm/antlr/CircuitScriptVisitor.js +7 -0
- package/dist/esm/builtinMethods.js +6 -1
- package/dist/esm/execute.js +27 -16
- package/dist/esm/graph.js +11 -10
- package/dist/esm/helpers.js +23 -4
- package/dist/esm/layout.js +15 -13
- package/dist/esm/main.js +17 -1
- package/dist/esm/objects/ExecutionScope.js +3 -0
- package/dist/esm/objects/PinDefinition.js +11 -1
- package/dist/esm/objects/types.js +7 -5
- package/dist/esm/rules-check/no-connect-on-connected-pin.js +77 -0
- package/dist/esm/rules-check/rules.js +70 -0
- package/dist/esm/rules-check/unconnected-pins.js +48 -0
- package/dist/esm/visitor.js +121 -5
- package/dist/libs/std.cst +7 -3
- package/dist/types/BomGeneration.d.ts +13 -0
- package/dist/types/ComponentMatchConditions.d.ts +19 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +60 -59
- package/dist/types/antlr/CircuitScriptParser.d.ts +146 -62
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +14 -0
- package/dist/types/execute.d.ts +2 -1
- package/dist/types/graph.d.ts +6 -1
- package/dist/types/helpers.d.ts +3 -0
- package/dist/types/layout.d.ts +3 -2
- package/dist/types/objects/ExecutionScope.d.ts +8 -2
- package/dist/types/objects/ParamDefinition.d.ts +1 -1
- package/dist/types/objects/PinDefinition.d.ts +1 -0
- package/dist/types/objects/types.d.ts +4 -2
- package/dist/types/rules-check/no-connect-on-connected-pin.d.ts +3 -0
- package/dist/types/rules-check/rules.d.ts +15 -0
- package/dist/types/rules-check/unconnected-pins.d.ts +2 -0
- package/dist/types/visitor.d.ts +10 -1
- package/libs/std.cst +7 -3
- package/package.json +2 -1
package/dist/cjs/visitor.js
CHANGED
|
@@ -14,10 +14,12 @@ const utils_js_2 = require("./utils.js");
|
|
|
14
14
|
const helpers_js_1 = require("./helpers.js");
|
|
15
15
|
const Frame_js_1 = require("./objects/Frame.js");
|
|
16
16
|
const ComponentAnnotater_js_1 = require("./ComponentAnnotater.js");
|
|
17
|
+
const ComponentMatchConditions_js_1 = require("./ComponentMatchConditions.js");
|
|
17
18
|
class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
18
19
|
constructor() {
|
|
19
20
|
super(...arguments);
|
|
20
21
|
this.componentCreationIndex = 0;
|
|
22
|
+
this.creationCtx = new Map();
|
|
21
23
|
this.visitKeyword_assignment_expr = (ctx) => {
|
|
22
24
|
const id = ctx.ID().getText();
|
|
23
25
|
const value = this.visitResult(ctx.data_expr());
|
|
@@ -542,7 +544,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
542
544
|
scope.triggerPropertyHandler(this, value, ctxValue);
|
|
543
545
|
this.getScope().exitContext();
|
|
544
546
|
this.getScope().exitContext();
|
|
545
|
-
if (value instanceof types_js_1.UndeclaredReference && (value.reference.
|
|
547
|
+
if (value instanceof types_js_1.UndeclaredReference && (value.reference.rootValue === undefined
|
|
546
548
|
&& value.reference.value === undefined)) {
|
|
547
549
|
throw value.throwMessage();
|
|
548
550
|
}
|
|
@@ -611,11 +613,11 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
611
613
|
componentCtx = ctxAssignmentExpr;
|
|
612
614
|
}
|
|
613
615
|
if (dataResult instanceof types_js_1.AnyReference) {
|
|
614
|
-
const { trailers = [],
|
|
615
|
-
if (
|
|
616
|
+
const { trailers = [], rootValue = null } = dataResult;
|
|
617
|
+
if (rootValue instanceof ClassComponent_js_1.ClassComponent
|
|
616
618
|
&& trailers.length > 0
|
|
617
619
|
&& trailers[0] === globals_js_1.ModuleContainsKeyword) {
|
|
618
|
-
dataResult =
|
|
620
|
+
dataResult = rootValue;
|
|
619
621
|
this.placeModuleContains(dataResult);
|
|
620
622
|
}
|
|
621
623
|
}
|
|
@@ -1011,7 +1013,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1011
1013
|
const segments = wireAtomExpr.map(wireSegment => {
|
|
1012
1014
|
return this.visitResult(wireSegment);
|
|
1013
1015
|
});
|
|
1014
|
-
this.getExecutor().addWire(segments);
|
|
1016
|
+
const newWire = this.getExecutor().addWire(segments);
|
|
1017
|
+
this.creationCtx.set(newWire, ctx);
|
|
1015
1018
|
};
|
|
1016
1019
|
this.visitPoint_expr = (ctx) => {
|
|
1017
1020
|
const ID = ctx.ID();
|
|
@@ -1199,6 +1202,119 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1199
1202
|
}
|
|
1200
1203
|
}
|
|
1201
1204
|
};
|
|
1205
|
+
this.visitPart_set_expr = (ctx) => {
|
|
1206
|
+
const paramKeys = ctx.data_expr().map(ctx => {
|
|
1207
|
+
return this.visitResult(ctx);
|
|
1208
|
+
});
|
|
1209
|
+
const partConditionTree = this.visitResult(ctx.part_match_block());
|
|
1210
|
+
const flattenedTree = (0, ComponentMatchConditions_js_1.flattenConditionNodes)(partConditionTree);
|
|
1211
|
+
const partConditions = (0, ComponentMatchConditions_js_1.extractPartConditions)(flattenedTree);
|
|
1212
|
+
const instances = this.getScope().getInstances();
|
|
1213
|
+
(0, ComponentMatchConditions_js_1.applyPartConditions)(instances, paramKeys, partConditions);
|
|
1214
|
+
};
|
|
1215
|
+
this.visitPart_match_block = (ctx) => {
|
|
1216
|
+
const results = ctx.part_sub_expr().map(ctxExpr => {
|
|
1217
|
+
return this.visitResult(ctxExpr);
|
|
1218
|
+
});
|
|
1219
|
+
this.setResult(ctx, results);
|
|
1220
|
+
};
|
|
1221
|
+
this.visitPart_sub_expr = (ctx) => {
|
|
1222
|
+
const ctxForm1 = ctx.part_condition_expr();
|
|
1223
|
+
const ctxForm2 = ctx.part_condition_key_only_expr();
|
|
1224
|
+
const ctxForm3 = ctx.part_value_expr();
|
|
1225
|
+
let result;
|
|
1226
|
+
if (ctxForm1) {
|
|
1227
|
+
result = this.visitResult(ctxForm1);
|
|
1228
|
+
}
|
|
1229
|
+
else if (ctxForm2) {
|
|
1230
|
+
result = this.visitResult(ctxForm2);
|
|
1231
|
+
}
|
|
1232
|
+
else if (ctxForm3) {
|
|
1233
|
+
result = this.visitResult(ctxForm3);
|
|
1234
|
+
}
|
|
1235
|
+
this.setResult(ctx, result);
|
|
1236
|
+
};
|
|
1237
|
+
this.visitPart_set_key = (ctx) => {
|
|
1238
|
+
const ctxID = ctx.ID();
|
|
1239
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
1240
|
+
const ctxNumericValue = ctx.NUMERIC_VALUE();
|
|
1241
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
1242
|
+
let useType = '';
|
|
1243
|
+
let useValue;
|
|
1244
|
+
if (ctxID) {
|
|
1245
|
+
useType = 'ID';
|
|
1246
|
+
useValue = ctxID.getText();
|
|
1247
|
+
}
|
|
1248
|
+
else if (ctxIntegerValue) {
|
|
1249
|
+
useType = 'number',
|
|
1250
|
+
useValue = Number(ctxIntegerValue.getText());
|
|
1251
|
+
}
|
|
1252
|
+
else if (ctxNumericValue) {
|
|
1253
|
+
useType = 'NUMERIC_VALUE';
|
|
1254
|
+
useValue = (0, ParamDefinition_js_1.numeric)(ctxNumericValue.getText());
|
|
1255
|
+
}
|
|
1256
|
+
else if (ctxStringValue) {
|
|
1257
|
+
useType = 'STRING_VALUE';
|
|
1258
|
+
useValue = this.prepareStringValue(ctxStringValue.getText());
|
|
1259
|
+
}
|
|
1260
|
+
this.setResult(ctx, {
|
|
1261
|
+
type: useType,
|
|
1262
|
+
value: useValue
|
|
1263
|
+
});
|
|
1264
|
+
};
|
|
1265
|
+
this.visitPart_value_expr = (ctx) => {
|
|
1266
|
+
const key = this.visitResult(ctx.part_set_key());
|
|
1267
|
+
const values = ctx.data_expr().map(ctxData => {
|
|
1268
|
+
return this.visitResult(ctxData);
|
|
1269
|
+
});
|
|
1270
|
+
this.setResult(ctx, { key, endValue: values });
|
|
1271
|
+
};
|
|
1272
|
+
this.visitPart_condition_expr = (ctx) => {
|
|
1273
|
+
const allKeys = ctx._key_id.map(ctx => {
|
|
1274
|
+
return this.visitResult(ctx);
|
|
1275
|
+
});
|
|
1276
|
+
const allValues = ctx._values.map(ctx => {
|
|
1277
|
+
return this.visitResult(ctx);
|
|
1278
|
+
});
|
|
1279
|
+
let deepestChildren = [];
|
|
1280
|
+
const ctxPartMatchBlock = ctx.part_match_block();
|
|
1281
|
+
if (ctxPartMatchBlock) {
|
|
1282
|
+
deepestChildren = this.visitResult(ctxPartMatchBlock);
|
|
1283
|
+
}
|
|
1284
|
+
let lastValue = undefined;
|
|
1285
|
+
if (ctx._last_data.length > 0) {
|
|
1286
|
+
lastValue = ctx._last_data.map(ctxData => {
|
|
1287
|
+
return this.visitResult(ctxData);
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
if (ctx._id_only) {
|
|
1291
|
+
allKeys.push(this.visitResult(ctx._id_only));
|
|
1292
|
+
allValues.push(undefined);
|
|
1293
|
+
}
|
|
1294
|
+
const reversedKeys = [...allKeys].reverse();
|
|
1295
|
+
const reversedValues = [...allValues].reverse();
|
|
1296
|
+
let tmpKeyValues;
|
|
1297
|
+
reversedKeys.forEach((key, index) => {
|
|
1298
|
+
const node = {
|
|
1299
|
+
key,
|
|
1300
|
+
values: (reversedValues[index] !== undefined) ? [reversedValues[index]] : undefined,
|
|
1301
|
+
children: (index === 0) ? deepestChildren : [tmpKeyValues],
|
|
1302
|
+
};
|
|
1303
|
+
if (index === 0 && lastValue !== undefined) {
|
|
1304
|
+
node.endValue = lastValue;
|
|
1305
|
+
}
|
|
1306
|
+
tmpKeyValues = node;
|
|
1307
|
+
});
|
|
1308
|
+
this.setResult(ctx, tmpKeyValues);
|
|
1309
|
+
};
|
|
1310
|
+
this.visitPart_condition_key_only_expr = (ctx) => {
|
|
1311
|
+
const key = this.visitResult(ctx.part_set_key());
|
|
1312
|
+
const children = this.visitResult(ctx.part_match_block());
|
|
1313
|
+
this.setResult(ctx, {
|
|
1314
|
+
key,
|
|
1315
|
+
children,
|
|
1316
|
+
});
|
|
1317
|
+
};
|
|
1202
1318
|
this.pinTypes = [
|
|
1203
1319
|
PinTypes_js_1.PinTypes.Any,
|
|
1204
1320
|
PinTypes_js_1.PinTypes.IO,
|
package/dist/esm/BaseVisitor.js
CHANGED
|
@@ -48,7 +48,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
48
48
|
scope.sequence.push([
|
|
49
49
|
SequenceAction.At, scope.componentRoot, scope.currentPin
|
|
50
50
|
]);
|
|
51
|
-
scope.setVariable(GlobalDocumentName, {
|
|
51
|
+
scope.setVariable(GlobalDocumentName, {
|
|
52
|
+
'bom': {},
|
|
53
|
+
});
|
|
52
54
|
this.setupBuiltInFunctions(this.startingContext);
|
|
53
55
|
this.executionStack = [this.startingContext];
|
|
54
56
|
this.startingContext.resolveNet =
|
|
@@ -168,34 +170,39 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
168
170
|
sequenceParts.push(...[itemType, leftSideReference.name, rhsValue]);
|
|
169
171
|
}
|
|
170
172
|
else {
|
|
171
|
-
if (leftSideReference.
|
|
172
|
-
this.setInstanceParam(leftSideReference.
|
|
173
|
-
this.log2(`assigned component param ${leftSideReference.
|
|
174
|
-
sequenceParts.push(...['instance', [leftSideReference.
|
|
175
|
-
if (leftSideReference.
|
|
176
|
-
const net = this.getScope().getNet(leftSideReference.
|
|
173
|
+
if (leftSideReference.rootValue instanceof ClassComponent) {
|
|
174
|
+
this.setInstanceParam(leftSideReference.rootValue, trailers, rhsValue);
|
|
175
|
+
this.log2(`assigned component param ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
|
|
176
|
+
sequenceParts.push(...['instance', [leftSideReference.rootValue, trailers], rhsValue]);
|
|
177
|
+
if (leftSideReference.rootValue.typeProp === ComponentTypes.net) {
|
|
178
|
+
const net = this.getScope().getNet(leftSideReference.rootValue, new PinId(1));
|
|
177
179
|
if (net) {
|
|
178
180
|
const trailerValue = trailers.join(".");
|
|
179
181
|
net.params.set(trailerValue, rhsValue);
|
|
180
182
|
}
|
|
181
183
|
}
|
|
182
184
|
}
|
|
183
|
-
else if (leftSideReference.
|
|
185
|
+
else if (leftSideReference.rootValue instanceof Object) {
|
|
184
186
|
if (Array.isArray(trailers[0]) && trailers[0][0] === TrailerArrayIndex) {
|
|
185
|
-
if (Array.isArray(leftSideReference.
|
|
187
|
+
if (Array.isArray(leftSideReference.rootValue)) {
|
|
186
188
|
const arrayIndexValue = trailers[0][1];
|
|
187
|
-
leftSideReference.
|
|
188
|
-
this.log2(`assigned array index ${leftSideReference.
|
|
189
|
+
leftSideReference.rootValue[arrayIndexValue] = rhsValue;
|
|
190
|
+
this.log2(`assigned array index ${leftSideReference.rootValue} index: ${arrayIndexValue} value: ${rhsValue}`);
|
|
189
191
|
}
|
|
190
192
|
else {
|
|
191
193
|
this.throwWithContext(lhsCtx, "Invalid array");
|
|
192
194
|
}
|
|
193
195
|
}
|
|
194
196
|
else {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
+
let expandedValue = leftSideReference.rootValue;
|
|
198
|
+
trailers.slice(0, -1).forEach(trailer => {
|
|
199
|
+
expandedValue = expandedValue[trailer];
|
|
200
|
+
});
|
|
201
|
+
const lastTrailer = trailers.slice(-1)[0];
|
|
202
|
+
expandedValue[lastTrailer] = rhsValue;
|
|
203
|
+
this.log2(`assigned object ${leftSideReference.rootValue} trailers: ${trailers} value: ${rhsValue}`);
|
|
197
204
|
}
|
|
198
|
-
sequenceParts.push(...['variable', [leftSideReference.
|
|
205
|
+
sequenceParts.push(...['variable', [leftSideReference.rootValue, trailers], rhsValue]);
|
|
199
206
|
}
|
|
200
207
|
}
|
|
201
208
|
if (sequenceParts.length > 0) {
|
|
@@ -268,7 +275,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
268
275
|
const reference = this.visitResult(ctx);
|
|
269
276
|
const { trailers = [] } = reference;
|
|
270
277
|
const undefinedParentWithTrailers = trailers.length > 0
|
|
271
|
-
&& reference.
|
|
278
|
+
&& reference.rootValue === undefined;
|
|
272
279
|
if (undefinedParentWithTrailers) {
|
|
273
280
|
this.throwWithContext(ctx, 'Undefined reference: ' + reference.name + '.' + trailers.join('.'));
|
|
274
281
|
}
|
|
@@ -282,7 +289,12 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
282
289
|
let nextReference;
|
|
283
290
|
if (ctxID) {
|
|
284
291
|
reference.trailers.push(ctxID.getText());
|
|
285
|
-
|
|
292
|
+
const useRootValue = reference.rootValue ?? reference.value;
|
|
293
|
+
const useTrailerIndex = reference.trailerIndex ?? 0;
|
|
294
|
+
nextReference = this.getExecutor().resolveTrailers(reference.type, useRootValue, reference.trailers);
|
|
295
|
+
nextReference.name =
|
|
296
|
+
[reference.name,
|
|
297
|
+
...reference.trailers.slice(useTrailerIndex)].join('.');
|
|
286
298
|
}
|
|
287
299
|
else if (ctxDataExpr) {
|
|
288
300
|
const arrayIndex = this.visitResult(ctxDataExpr);
|
|
@@ -296,7 +308,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
296
308
|
type: refType,
|
|
297
309
|
value: foundValue,
|
|
298
310
|
trailers: [[TrailerArrayIndex, arrayIndexValue]],
|
|
299
|
-
|
|
311
|
+
rootValue: useValue
|
|
300
312
|
});
|
|
301
313
|
}
|
|
302
314
|
}
|
|
@@ -315,15 +327,15 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
315
327
|
});
|
|
316
328
|
}
|
|
317
329
|
else {
|
|
330
|
+
this.log('resolve variable ctx: ' + ctx.getText(), 'atomId', atomId);
|
|
318
331
|
currentReference = executor.resolveVariable(this.executionStack, atomId);
|
|
332
|
+
this.log('reference:', currentReference.name, 'found:', currentReference.found);
|
|
319
333
|
}
|
|
320
334
|
if (currentReference !== undefined && currentReference.found) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
currentReference = this.visitResult(trailerCtx);
|
|
326
|
-
}
|
|
335
|
+
ctx.trailer_expr2().forEach(ctxTrailer => {
|
|
336
|
+
this.setResult(ctxTrailer, currentReference);
|
|
337
|
+
currentReference = this.visitResult(ctxTrailer);
|
|
338
|
+
});
|
|
327
339
|
}
|
|
328
340
|
this.setResult(ctx, currentReference);
|
|
329
341
|
this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as csv from '@fast-csv/format';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { NumericValue } from "./objects/ParamDefinition.js";
|
|
4
|
+
const TypeSortOrder = {
|
|
5
|
+
"res": 1,
|
|
6
|
+
"cap": 2,
|
|
7
|
+
"ind": 3,
|
|
8
|
+
"diode": 9,
|
|
9
|
+
"ic": 10,
|
|
10
|
+
"conn": 20,
|
|
11
|
+
};
|
|
12
|
+
export function generateBom(bomConfig, instances) {
|
|
13
|
+
const bomComponents = extractComponentValuesForBom(bomConfig, instances);
|
|
14
|
+
const tmpGroupedComponents = groupComponents(bomConfig, bomComponents);
|
|
15
|
+
const groupedBom = [];
|
|
16
|
+
tmpGroupedComponents.forEach(value => {
|
|
17
|
+
groupedBom.push({
|
|
18
|
+
...value.items[0],
|
|
19
|
+
refdes: value.allRefdes.join(', ')
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
const sortedGroupedBom = groupedBom.toSorted((a, b) => {
|
|
23
|
+
const typeSortA = TypeSortOrder[a['.type']] ?? 100;
|
|
24
|
+
const typeSortB = TypeSortOrder[b['.type']] ?? 100;
|
|
25
|
+
return typeSortA - typeSortB;
|
|
26
|
+
});
|
|
27
|
+
return sortedGroupedBom;
|
|
28
|
+
}
|
|
29
|
+
export function groupComponents(bomConfig, bomComponents) {
|
|
30
|
+
const { group_by } = bomConfig;
|
|
31
|
+
const grouped = new Map();
|
|
32
|
+
bomComponents.forEach(row => {
|
|
33
|
+
const groupKeyParts = {};
|
|
34
|
+
group_by.forEach(paramKey => {
|
|
35
|
+
groupKeyParts[paramKey] = row[paramKey];
|
|
36
|
+
});
|
|
37
|
+
const groupKey = JSON.stringify(groupKeyParts);
|
|
38
|
+
if (!grouped.has(groupKey)) {
|
|
39
|
+
grouped.set(groupKey, {
|
|
40
|
+
allRefdes: [],
|
|
41
|
+
items: [],
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const entry = grouped.get(groupKey);
|
|
45
|
+
entry.items.push(row);
|
|
46
|
+
entry.allRefdes.push(row.refdes);
|
|
47
|
+
grouped.set(groupKey, entry);
|
|
48
|
+
});
|
|
49
|
+
return grouped;
|
|
50
|
+
}
|
|
51
|
+
function extractComponentValuesForBom(bomConfig, instances) {
|
|
52
|
+
const { columns = [] } = bomConfig;
|
|
53
|
+
const resultRows = [];
|
|
54
|
+
instances.forEach(instance => {
|
|
55
|
+
if (instance.assignedRefDes !== null) {
|
|
56
|
+
const row = {
|
|
57
|
+
'.type': instance.typeProp,
|
|
58
|
+
};
|
|
59
|
+
columns.forEach(paramKey => {
|
|
60
|
+
let useValue = '';
|
|
61
|
+
if (paramKey === 'refdes') {
|
|
62
|
+
useValue = instance.assignedRefDes;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
if (instance.hasParam(paramKey)) {
|
|
66
|
+
useValue = instance.getParam(paramKey);
|
|
67
|
+
if (typeof useValue === 'string') {
|
|
68
|
+
useValue = resolveValuesInTemplate(instance, useValue);
|
|
69
|
+
}
|
|
70
|
+
else if (useValue instanceof NumericValue) {
|
|
71
|
+
useValue = useValue.toDisplayString();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
row[paramKey] = useValue;
|
|
76
|
+
});
|
|
77
|
+
resultRows.push(row);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
return resultRows;
|
|
81
|
+
}
|
|
82
|
+
function resolveValuesInTemplate(instance, templateString) {
|
|
83
|
+
return templateString.replace(/\{(\w+)\}/g, (match, paramName) => {
|
|
84
|
+
if (instance.hasParam(paramName)) {
|
|
85
|
+
const paramValue = instance.getParam(paramName);
|
|
86
|
+
if (paramValue instanceof NumericValue) {
|
|
87
|
+
return paramValue.toDisplayString();
|
|
88
|
+
}
|
|
89
|
+
return instance.getParam(paramName);
|
|
90
|
+
}
|
|
91
|
+
return match;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export function generateBomCSV(bomData) {
|
|
95
|
+
const useHeaders = [];
|
|
96
|
+
const rows = [];
|
|
97
|
+
if (bomData.length > 0) {
|
|
98
|
+
const [firstRow] = bomData;
|
|
99
|
+
for (const key in firstRow) {
|
|
100
|
+
if (key.startsWith('.')) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const useKey = key[0].toUpperCase() + key.substring(1);
|
|
104
|
+
useHeaders.push(useKey);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
rows.push(useHeaders);
|
|
108
|
+
const keys = [];
|
|
109
|
+
if (bomData.length > 0) {
|
|
110
|
+
for (const key in bomData[0]) {
|
|
111
|
+
if (key.startsWith('.')) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
keys.push(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
bomData.forEach(row => {
|
|
118
|
+
const result = keys.map(key => {
|
|
119
|
+
return row[key];
|
|
120
|
+
});
|
|
121
|
+
rows.push(result);
|
|
122
|
+
});
|
|
123
|
+
return rows;
|
|
124
|
+
}
|
|
125
|
+
export async function saveBomOutputCsv(bomCsvOutput, filePath) {
|
|
126
|
+
return new Promise(resolve => {
|
|
127
|
+
const outputStream = fs.createWriteStream(filePath);
|
|
128
|
+
const csvStream = csv.format();
|
|
129
|
+
csvStream.pipe(outputStream).on("finish", () => {
|
|
130
|
+
resolve();
|
|
131
|
+
});
|
|
132
|
+
bomCsvOutput.forEach(row => {
|
|
133
|
+
csvStream.write(row);
|
|
134
|
+
});
|
|
135
|
+
csvStream.end();
|
|
136
|
+
});
|
|
137
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { NumericValue } from "./objects/ParamDefinition.js";
|
|
2
|
+
import { TypeProps } from "./objects/types.js";
|
|
3
|
+
export function flattenConditionNodes(conditionNodes, level = 0) {
|
|
4
|
+
const conditionBranches = [];
|
|
5
|
+
conditionNodes.forEach(node => {
|
|
6
|
+
const { key, values, children = [], endValue = [] } = node;
|
|
7
|
+
const firstCondition = {
|
|
8
|
+
key, values, endValue
|
|
9
|
+
};
|
|
10
|
+
if (children.length > 0) {
|
|
11
|
+
const nestedBranches = flattenConditionNodes(children, level + 1);
|
|
12
|
+
nestedBranches.forEach(tmpCondition => {
|
|
13
|
+
if (values === undefined) {
|
|
14
|
+
const modifiedCondition = {
|
|
15
|
+
...firstCondition,
|
|
16
|
+
values: [tmpCondition[0].key.value],
|
|
17
|
+
endValue: tmpCondition[0].endValue
|
|
18
|
+
};
|
|
19
|
+
conditionBranches.push([
|
|
20
|
+
modifiedCondition,
|
|
21
|
+
...tmpCondition.slice(1)
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
conditionBranches.push([
|
|
26
|
+
firstCondition,
|
|
27
|
+
...tmpCondition
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
conditionBranches.push([firstCondition]);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return conditionBranches;
|
|
37
|
+
}
|
|
38
|
+
export function extractPartConditions(conditionBranches) {
|
|
39
|
+
const partConditions = conditionBranches.map(branch => {
|
|
40
|
+
const lastNode = branch[branch.length - 1];
|
|
41
|
+
const { endValue } = lastNode;
|
|
42
|
+
const conditions = [];
|
|
43
|
+
branch.forEach((node, index) => {
|
|
44
|
+
conditions.push({
|
|
45
|
+
key: node.key,
|
|
46
|
+
values: node.values
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
endValue,
|
|
51
|
+
conditions
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
return partConditions;
|
|
55
|
+
}
|
|
56
|
+
export function partMatchesConditions(instance, partConditions) {
|
|
57
|
+
for (let i = 0; i < partConditions.length; i++) {
|
|
58
|
+
const { endValue, conditions } = partConditions[i];
|
|
59
|
+
const didNotMatch = conditions.some(condition => {
|
|
60
|
+
const { key, values } = condition;
|
|
61
|
+
let useKey = '';
|
|
62
|
+
if (key.type === 'ID') {
|
|
63
|
+
useKey = key.value;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log('key type not supported', key);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (useKey === 'type') {
|
|
70
|
+
return (instance.typeProp !== values[0]);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
if (!instance.hasParam(useKey)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const paramValue = instance.getParam(useKey);
|
|
78
|
+
const compareValue = values[0];
|
|
79
|
+
if (typeof compareValue === "string") {
|
|
80
|
+
return (compareValue !== paramValue);
|
|
81
|
+
}
|
|
82
|
+
else if (compareValue instanceof NumericValue) {
|
|
83
|
+
return !compareValue.eq(paramValue);
|
|
84
|
+
}
|
|
85
|
+
else if (typeof compareValue === 'number') {
|
|
86
|
+
return compareValue !== paramValue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (didNotMatch === false) {
|
|
92
|
+
return endValue;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export function applyPartConditions(instances, paramKeys, partConditions) {
|
|
97
|
+
instances.forEach(item => {
|
|
98
|
+
if (item.typeProp !== TypeProps.Graphic) {
|
|
99
|
+
const matchedResult = partMatchesConditions(item, partConditions);
|
|
100
|
+
if (matchedResult !== undefined) {
|
|
101
|
+
paramKeys.forEach((paramKey, index) => {
|
|
102
|
+
if (matchedResult[index] !== undefined) {
|
|
103
|
+
item.setParam(paramKey, matchedResult[index]);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|