circuitscript 0.1.31 → 0.1.33
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 +37 -3
- package/dist/cjs/RefdesAnnotationVisitor.js +27 -10
- package/dist/cjs/antlr/CircuitScriptParser.js +990 -831
- package/dist/cjs/draw_symbols.js +38 -34
- package/dist/cjs/environment.js +24 -4
- package/dist/cjs/execute.js +107 -68
- package/dist/cjs/globals.js +4 -2
- package/dist/cjs/graph.js +14 -12
- package/dist/cjs/helpers.js +85 -16
- package/dist/cjs/layout.js +50 -25
- package/dist/cjs/main.js +16 -18
- package/dist/cjs/objects/ClassComponent.js +199 -30
- package/dist/cjs/objects/types.js +5 -1
- package/dist/cjs/regenerate-tests.js +3 -3
- package/dist/cjs/render.js +5 -3
- package/dist/cjs/rules-check/no-connect-on-connected-pin.js +9 -8
- package/dist/cjs/rules-check/rules.js +7 -2
- package/dist/cjs/rules-check/unconnected-pins.js +10 -8
- package/dist/cjs/utils.js +2 -1
- package/dist/cjs/validate/SymbolValidatorVisitor.js +0 -10
- package/dist/cjs/visitor.js +284 -191
- package/dist/esm/BaseVisitor.js +37 -3
- package/dist/esm/RefdesAnnotationVisitor.js +27 -10
- package/dist/esm/antlr/CircuitScriptParser.js +989 -830
- package/dist/esm/antlr/CircuitScriptVisitor.js +1 -0
- package/dist/esm/draw_symbols.js +38 -34
- package/dist/esm/environment.js +21 -1
- package/dist/esm/execute.js +108 -69
- package/dist/esm/globals.js +2 -0
- package/dist/esm/graph.js +14 -12
- package/dist/esm/helpers.js +86 -17
- package/dist/esm/layout.js +51 -26
- package/dist/esm/main.js +16 -18
- package/dist/esm/objects/ClassComponent.js +201 -30
- package/dist/esm/objects/types.js +7 -1
- package/dist/esm/regenerate-tests.js +3 -3
- package/dist/esm/render.js +5 -3
- package/dist/esm/rules-check/no-connect-on-connected-pin.js +9 -8
- package/dist/esm/rules-check/rules.js +7 -2
- package/dist/esm/rules-check/unconnected-pins.js +10 -8
- package/dist/esm/utils.js +2 -1
- package/dist/esm/validate/SymbolValidatorVisitor.js +0 -10
- package/dist/esm/visitor.js +185 -92
- package/dist/types/BaseVisitor.d.ts +15 -5
- package/dist/types/RefdesAnnotationVisitor.d.ts +2 -0
- package/dist/types/antlr/CircuitScriptParser.d.ts +32 -14
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +2 -0
- package/dist/types/environment.d.ts +7 -1
- package/dist/types/execute.d.ts +4 -1
- package/dist/types/globals.d.ts +2 -0
- package/dist/types/graph.d.ts +2 -2
- package/dist/types/helpers.d.ts +2 -1
- package/dist/types/layout.d.ts +5 -4
- package/dist/types/objects/ClassComponent.d.ts +34 -9
- package/dist/types/objects/types.d.ts +19 -3
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +0 -4
- package/dist/types/visitor.d.ts +7 -1
- package/package.json +1 -1
package/dist/cjs/visitor.js
CHANGED
|
@@ -167,137 +167,20 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
167
167
|
if (ctxNotPathBlock) {
|
|
168
168
|
this.visit(ctxNotPathBlock);
|
|
169
169
|
}
|
|
170
|
+
if (ctx.start && ctx.stop) {
|
|
171
|
+
const startToken = ctx.start;
|
|
172
|
+
const stopToken = ctx.stop;
|
|
173
|
+
const annotationKey = this.getRefdesFileAnnotation(this.getCurrentFile(), startToken.line, startToken.column, stopToken.line, stopToken.column);
|
|
174
|
+
if (this.refdesFileAnnotations.has(annotationKey)) {
|
|
175
|
+
let refdesValue = this.refdesFileAnnotations.get(annotationKey);
|
|
176
|
+
refdesValue = refdesValue.split(',')[0];
|
|
177
|
+
this.setCurrentComponentRefdes(refdesValue, true);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
170
180
|
};
|
|
171
181
|
this.visitCreate_component_expr = (ctx) => {
|
|
172
182
|
const scope = this.getScope();
|
|
173
|
-
|
|
174
|
-
const arrangedPinIds = [];
|
|
175
|
-
const checkPinExistsAndNotDuplicated = (pinId, ctx) => {
|
|
176
|
-
if (definedPinIds.indexOf(pinId) === -1) {
|
|
177
|
-
this.warnings.push({
|
|
178
|
-
message: `Invalid pin ${pinId}`, ctx
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
if (arrangedPinIds.indexOf(pinId) !== -1) {
|
|
182
|
-
this.warnings.push({
|
|
183
|
-
message: `Pin ${pinId} specified more than once`,
|
|
184
|
-
ctx,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
arrangedPinIds.push(pinId);
|
|
188
|
-
};
|
|
189
|
-
let didDefineArrangeProp = false;
|
|
190
|
-
let didDefineDisplayProp = false;
|
|
191
|
-
scope.setOnPropertyHandler((path, value, ctx) => {
|
|
192
|
-
if (path.length === 1) {
|
|
193
|
-
const [, keyName] = path[0];
|
|
194
|
-
switch (keyName) {
|
|
195
|
-
case 'type':
|
|
196
|
-
this.validateString(value, ctx);
|
|
197
|
-
break;
|
|
198
|
-
case 'angle':
|
|
199
|
-
case 'width':
|
|
200
|
-
case 'height':
|
|
201
|
-
this.validateNumeric(value, ctx);
|
|
202
|
-
break;
|
|
203
|
-
case 'display':
|
|
204
|
-
if (didDefineArrangeProp) {
|
|
205
|
-
throw new utils_js_2.RuntimeExecutionError("arrange property has already been defined", ctx);
|
|
206
|
-
}
|
|
207
|
-
didDefineDisplayProp = true;
|
|
208
|
-
break;
|
|
209
|
-
case 'arrange':
|
|
210
|
-
if (didDefineDisplayProp) {
|
|
211
|
-
throw new utils_js_2.RuntimeExecutionError("display property already defined", ctx);
|
|
212
|
-
}
|
|
213
|
-
didDefineArrangeProp = true;
|
|
214
|
-
break;
|
|
215
|
-
case 'pins':
|
|
216
|
-
if (!(value instanceof Map)) {
|
|
217
|
-
this.validateNumeric(value, ctx);
|
|
218
|
-
const numPins = value.toNumber();
|
|
219
|
-
for (let i = 0; i < numPins; i++) {
|
|
220
|
-
definedPinIds.push(i + 1);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
break;
|
|
224
|
-
case 'copy':
|
|
225
|
-
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
226
|
-
this.validateNumeric(value, ctx);
|
|
227
|
-
}
|
|
228
|
-
else if (typeof value === 'boolean') {
|
|
229
|
-
this.validateBoolean(value, ctx);
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
throw new utils_js_2.RuntimeExecutionError("Invalid value for 'copy' property", ctx);
|
|
233
|
-
}
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
const [, keyName] = path[0];
|
|
239
|
-
if (keyName === 'arrange') {
|
|
240
|
-
const [sideKeyCtx, sideKeyName] = path[1];
|
|
241
|
-
if (globals_js_1.ValidPinSides.indexOf(sideKeyName) === -1) {
|
|
242
|
-
throw new utils_js_2.RuntimeExecutionError(`Invalid side ${sideKeyName} in arrange`, sideKeyCtx);
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
if (path.length === 2 && value instanceof ParamDefinition_js_1.NumericValue) {
|
|
246
|
-
checkPinExistsAndNotDuplicated(value.toNumber(), ctx);
|
|
247
|
-
}
|
|
248
|
-
else if (path.length > 2 && path[2][0] === 'index') {
|
|
249
|
-
if (Array.isArray(value)) {
|
|
250
|
-
const goodBlank = value.length === 1 &&
|
|
251
|
-
value[0] instanceof ParamDefinition_js_1.NumericValue;
|
|
252
|
-
if (!goodBlank) {
|
|
253
|
-
throw new utils_js_2.RuntimeExecutionError(`Invalid blank specifier`, ctx);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
if (!(value instanceof ParamDefinition_js_1.NumericValue) && !(typeof value === 'string')) {
|
|
258
|
-
throw new utils_js_2.RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx);
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
let useValue;
|
|
262
|
-
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
263
|
-
useValue = value.toNumber();
|
|
264
|
-
}
|
|
265
|
-
else if (typeof value === 'string') {
|
|
266
|
-
useValue = value;
|
|
267
|
-
}
|
|
268
|
-
value && checkPinExistsAndNotDuplicated(useValue, ctx);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
else if (keyName === 'params') {
|
|
275
|
-
const [, subKeyName] = path[1];
|
|
276
|
-
switch (subKeyName) {
|
|
277
|
-
case 'mpn':
|
|
278
|
-
case 'refdes':
|
|
279
|
-
case 'footprint':
|
|
280
|
-
this.validateString(value, ctx);
|
|
281
|
-
break;
|
|
282
|
-
case 'place':
|
|
283
|
-
this.validateBoolean(value, ctx);
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
else if (keyName === 'pins') {
|
|
288
|
-
if (path.length === 2) {
|
|
289
|
-
const idName = path[1][1];
|
|
290
|
-
definedPinIds.push(idName);
|
|
291
|
-
if (value.length === 2) {
|
|
292
|
-
const [pinType,] = value;
|
|
293
|
-
if (pinType instanceof types_js_1.UndeclaredReference) {
|
|
294
|
-
throw new utils_js_2.RuntimeExecutionError(`Invalid pin type: ${pinType.reference.name}`, ctx);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
});
|
|
183
|
+
scope.setOnPropertyHandler(this.createComponentPropertyValidator());
|
|
301
184
|
scope.enterContext(ctx);
|
|
302
185
|
ctx.property_expr().forEach(item => {
|
|
303
186
|
this.visitResult(item);
|
|
@@ -317,49 +200,16 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
317
200
|
}
|
|
318
201
|
instanceName += `${globals_js_1.Delimiter1}${appendValue}`;
|
|
319
202
|
}
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
properties.get('display') : null;
|
|
324
|
-
const typeProp = properties.has('type') ?
|
|
325
|
-
properties.get('type') : null;
|
|
326
|
-
const copy = properties.has('copy') ?
|
|
327
|
-
properties.get('copy') : false;
|
|
328
|
-
const width = properties.has('width') ?
|
|
329
|
-
properties.get('width') : null;
|
|
330
|
-
const height = properties.has('height') ?
|
|
331
|
-
properties.get('height') : null;
|
|
332
|
-
const angle = properties.has(globals_js_1.ParamKeys.angle) ?
|
|
333
|
-
properties.get(globals_js_1.ParamKeys.angle) : null;
|
|
334
|
-
const followWireOrientation = properties.has('followWireOrientation') ?
|
|
335
|
-
properties.get('followWireOrientation') : true;
|
|
336
|
-
let pins = [];
|
|
337
|
-
if (displayProp !== null && arrangeProp === null
|
|
338
|
-
&& typeProp !== types_js_1.TypeProps.Graphic) {
|
|
339
|
-
const drawCommands = displayProp.getCommands();
|
|
340
|
-
drawCommands.forEach(command => {
|
|
341
|
-
const [commandValue,] = command;
|
|
342
|
-
if (commandValue === draw_symbols_js_1.PlaceHolderCommands.vpin
|
|
343
|
-
|| commandValue === draw_symbols_js_1.PlaceHolderCommands.hpin
|
|
344
|
-
|| commandValue === draw_symbols_js_1.PlaceHolderCommands.pin) {
|
|
345
|
-
const id = PinDefinition_js_1.PinId.from(command[1][0]);
|
|
346
|
-
const pinType = id.getType();
|
|
347
|
-
const pinName = id.toString();
|
|
348
|
-
pins.push(new PinDefinition_js_1.PinDefinition(id, pinType, pinName, PinTypes_js_1.PinTypes.Any));
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
354
|
-
}
|
|
203
|
+
const typeProp = properties.get('type') ?? null;
|
|
204
|
+
const copy = properties.get('copy') ?? false;
|
|
205
|
+
const unitDefinitions = this.extractComponentUnitProperties(properties, typeProp);
|
|
355
206
|
const props = {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
angle, followWireOrientation
|
|
207
|
+
type: typeProp,
|
|
208
|
+
copy,
|
|
209
|
+
units: unitDefinitions
|
|
360
210
|
};
|
|
361
211
|
try {
|
|
362
|
-
const createdComponent = this.getExecutor().createComponent(instanceName,
|
|
212
|
+
const createdComponent = this.getExecutor().createComponent(instanceName, [], params, props);
|
|
363
213
|
this.setResult(ctx, createdComponent);
|
|
364
214
|
createdComponent._creationIndex = this.componentCreationIndex++;
|
|
365
215
|
}
|
|
@@ -501,19 +351,18 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
501
351
|
return new PinDefinition_js_1.PinDefinition(index + 1, PinDefinition_js_1.PinIdType.Int, portName, PinTypes_js_1.PinTypes.Any);
|
|
502
352
|
});
|
|
503
353
|
const arrange = this.getArrangePropFromModulePorts(modulePorts, nameToPinId);
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
354
|
+
const unitProperties = this.extractComponentUnitProperties(properties, types_js_1.TypeProps.Module);
|
|
355
|
+
const firstUnitDef = unitProperties[0][1];
|
|
356
|
+
firstUnitDef.pins = tmpPorts;
|
|
357
|
+
firstUnitDef.arrange = arrange;
|
|
508
358
|
const blankParams = [];
|
|
509
359
|
const props = {
|
|
510
|
-
arrange, width, height,
|
|
511
360
|
copy: false,
|
|
512
|
-
|
|
361
|
+
units: unitProperties,
|
|
513
362
|
};
|
|
514
363
|
const moduleInstanceName = this.getExecutor().getUniqueInstanceName();
|
|
515
364
|
const moduleComponent = this.getExecutor().createComponent(moduleInstanceName, tmpPorts, blankParams, props, true);
|
|
516
|
-
moduleComponent.typeProp =
|
|
365
|
+
moduleComponent.typeProp = types_js_1.TypeProps.Module;
|
|
517
366
|
const ctxPropertyBlock = ctx.property_block_expr();
|
|
518
367
|
if (ctxPropertyBlock) {
|
|
519
368
|
const [firstBlock] = ctxPropertyBlock;
|
|
@@ -536,6 +385,10 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
536
385
|
this.visitProperty_expr = (ctx) => {
|
|
537
386
|
const ctxKey = ctx.property_key_expr();
|
|
538
387
|
const ctxValue = ctx.property_value_expr();
|
|
388
|
+
const extraValue = ctx._extra;
|
|
389
|
+
if (extraValue) {
|
|
390
|
+
console.log('extra', extraValue.text);
|
|
391
|
+
}
|
|
539
392
|
const scope = this.getScope();
|
|
540
393
|
this.getScope().enterContext(ctxKey);
|
|
541
394
|
this.getScope().enterContext(ctxValue);
|
|
@@ -630,6 +483,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
630
483
|
dataResult = this.getExecutor().copyComponent(dataResult);
|
|
631
484
|
}
|
|
632
485
|
if (dataResult && dataResult instanceof ClassComponent_js_1.ClassComponent) {
|
|
486
|
+
const defaultUnit = dataResult.getUnit();
|
|
633
487
|
const modifiers = ctx.component_modifier_expr();
|
|
634
488
|
modifiers.forEach(modifier => {
|
|
635
489
|
const modifierText = modifier.ID(0).getText();
|
|
@@ -646,23 +500,23 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
646
500
|
if (modifierText === globals_js_1.ParamKeys.flip) {
|
|
647
501
|
const flipValue = result;
|
|
648
502
|
if (flipValue.indexOf('x') !== -1) {
|
|
649
|
-
|
|
503
|
+
defaultUnit.setParam(globals_js_1.ParamKeys.flipX, (0, ParamDefinition_js_1.numeric)(1));
|
|
650
504
|
shouldIgnoreWireOrientation = true;
|
|
651
505
|
}
|
|
652
506
|
if (flipValue.indexOf('y') !== -1) {
|
|
653
|
-
|
|
507
|
+
defaultUnit.setParam(globals_js_1.ParamKeys.flipY, (0, ParamDefinition_js_1.numeric)(1));
|
|
654
508
|
shouldIgnoreWireOrientation = true;
|
|
655
509
|
}
|
|
656
510
|
}
|
|
657
511
|
else if (modifierText === globals_js_1.ParamKeys.angle) {
|
|
658
|
-
|
|
512
|
+
defaultUnit.setParam(globals_js_1.ParamKeys.angle, result);
|
|
659
513
|
shouldIgnoreWireOrientation = true;
|
|
660
514
|
}
|
|
661
515
|
else if (modifierText === 'anchor') {
|
|
662
516
|
dataResult.setParam('anchor', result);
|
|
663
517
|
}
|
|
664
518
|
if (shouldIgnoreWireOrientation) {
|
|
665
|
-
|
|
519
|
+
defaultUnit.useWireOrientationAngle = false;
|
|
666
520
|
}
|
|
667
521
|
});
|
|
668
522
|
}
|
|
@@ -1155,15 +1009,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1155
1009
|
};
|
|
1156
1010
|
this.visitAnnotation_comment_expr = (ctx) => {
|
|
1157
1011
|
const refdesID = ctx.ID().getText();
|
|
1158
|
-
|
|
1159
|
-
if (currentComponent !== null) {
|
|
1160
|
-
if (refdesID.indexOf('_') === -1) {
|
|
1161
|
-
currentComponent.setParam('refdes', refdesID);
|
|
1162
|
-
}
|
|
1163
|
-
else {
|
|
1164
|
-
currentComponent.placeHolderRefDes = refdesID;
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1012
|
+
this.setCurrentComponentRefdes(refdesID);
|
|
1167
1013
|
};
|
|
1168
1014
|
this.visitPart_set_expr = (ctx) => {
|
|
1169
1015
|
const paramKeys = ctx.data_expr().map(ctx => {
|
|
@@ -1293,6 +1139,192 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1293
1139
|
this.log('-----------------');
|
|
1294
1140
|
}
|
|
1295
1141
|
}
|
|
1142
|
+
extractComponentUnitDefinition(properties, typeProp = null, lastNumericPinId = 0) {
|
|
1143
|
+
const width = properties.get('width') ?? null;
|
|
1144
|
+
const height = properties.get('height') ?? null;
|
|
1145
|
+
const angle = properties.get(globals_js_1.ParamKeys.angle) ?? null;
|
|
1146
|
+
const followWireOrientation = properties.get('followWireOrientation') ?? true;
|
|
1147
|
+
const arrange = properties.get('arrange') ?? null;
|
|
1148
|
+
const display = properties.get('display') ?? null;
|
|
1149
|
+
const suffix = properties.get('suffix') ?? null;
|
|
1150
|
+
let pins = [];
|
|
1151
|
+
if (display !== null && arrange === null && typeProp !== types_js_1.TypeProps.Graphic) {
|
|
1152
|
+
const drawCommands = display.getCommands();
|
|
1153
|
+
drawCommands.forEach(command => {
|
|
1154
|
+
const [commandValue,] = command;
|
|
1155
|
+
if (commandValue === draw_symbols_js_1.PlaceHolderCommands.vpin
|
|
1156
|
+
|| commandValue === draw_symbols_js_1.PlaceHolderCommands.hpin
|
|
1157
|
+
|| commandValue === draw_symbols_js_1.PlaceHolderCommands.pin) {
|
|
1158
|
+
const id = PinDefinition_js_1.PinId.from(command[1][0]);
|
|
1159
|
+
const pinType = id.getType();
|
|
1160
|
+
const pinName = id.toString();
|
|
1161
|
+
pins.push(new PinDefinition_js_1.PinDefinition(id, pinType, pinName, PinTypes_js_1.PinTypes.Any));
|
|
1162
|
+
}
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
else {
|
|
1166
|
+
pins = this.extractPinDefintion(properties.get('pins'), lastNumericPinId);
|
|
1167
|
+
}
|
|
1168
|
+
return {
|
|
1169
|
+
width,
|
|
1170
|
+
height,
|
|
1171
|
+
angle,
|
|
1172
|
+
followWireOrientation,
|
|
1173
|
+
display, arrange,
|
|
1174
|
+
pins,
|
|
1175
|
+
suffix
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
extractComponentUnitProperties(properties, typeProp) {
|
|
1179
|
+
let lastNumericPinId = 0;
|
|
1180
|
+
const unitsProperties = [];
|
|
1181
|
+
for (const [key, value] of properties) {
|
|
1182
|
+
if (key.split(':')[0] === 'unit') {
|
|
1183
|
+
const unitDef = this.extractComponentUnitDefinition(value, typeProp, lastNumericPinId);
|
|
1184
|
+
unitDef.pins.forEach(pin => {
|
|
1185
|
+
if (pin.id.isNumeric()) {
|
|
1186
|
+
lastNumericPinId = Math.max(lastNumericPinId, pin.id.getValue());
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
unitsProperties.push([key, unitDef]);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
if (unitsProperties.length === 0) {
|
|
1193
|
+
unitsProperties.push(['unit',
|
|
1194
|
+
this.extractComponentUnitDefinition(properties, typeProp)]);
|
|
1195
|
+
}
|
|
1196
|
+
return unitsProperties;
|
|
1197
|
+
}
|
|
1198
|
+
createComponentPropertyValidator() {
|
|
1199
|
+
const definedPinIds = [];
|
|
1200
|
+
const arrangedPinIds = [];
|
|
1201
|
+
let didDefineArrangeProp = false;
|
|
1202
|
+
let didDefineDisplayProp = false;
|
|
1203
|
+
const checkPinExistsAndNotDuplicated = (pinId, ctx) => {
|
|
1204
|
+
if (definedPinIds.indexOf(pinId) === -1) {
|
|
1205
|
+
this.warnings.push({
|
|
1206
|
+
message: `Invalid pin ${pinId}`, ctx
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
if (arrangedPinIds.indexOf(pinId) !== -1) {
|
|
1210
|
+
this.warnings.push({
|
|
1211
|
+
message: `Pin ${pinId} specified more than once`,
|
|
1212
|
+
ctx,
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
arrangedPinIds.push(pinId);
|
|
1216
|
+
};
|
|
1217
|
+
return (path, value, ctx) => {
|
|
1218
|
+
if (path.length === 1) {
|
|
1219
|
+
const [, keyName] = path[0];
|
|
1220
|
+
switch (keyName) {
|
|
1221
|
+
case 'type':
|
|
1222
|
+
this.validateString(value, ctx);
|
|
1223
|
+
break;
|
|
1224
|
+
case 'angle':
|
|
1225
|
+
case 'width':
|
|
1226
|
+
case 'height':
|
|
1227
|
+
this.validateNumeric(value, ctx);
|
|
1228
|
+
break;
|
|
1229
|
+
case 'display':
|
|
1230
|
+
if (didDefineArrangeProp) {
|
|
1231
|
+
throw new utils_js_2.RuntimeExecutionError("arrange property has already been defined", ctx);
|
|
1232
|
+
}
|
|
1233
|
+
didDefineDisplayProp = true;
|
|
1234
|
+
break;
|
|
1235
|
+
case 'arrange':
|
|
1236
|
+
if (didDefineDisplayProp) {
|
|
1237
|
+
throw new utils_js_2.RuntimeExecutionError("display property already defined", ctx);
|
|
1238
|
+
}
|
|
1239
|
+
didDefineArrangeProp = true;
|
|
1240
|
+
break;
|
|
1241
|
+
case 'pins':
|
|
1242
|
+
if (!(value instanceof Map)) {
|
|
1243
|
+
this.validateNumeric(value, ctx);
|
|
1244
|
+
const numPins = value.toNumber();
|
|
1245
|
+
for (let i = 0; i < numPins; i++) {
|
|
1246
|
+
definedPinIds.push(i + 1);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
break;
|
|
1250
|
+
case 'copy':
|
|
1251
|
+
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
1252
|
+
this.validateNumeric(value, ctx);
|
|
1253
|
+
}
|
|
1254
|
+
else if (typeof value === 'boolean') {
|
|
1255
|
+
this.validateBoolean(value, ctx);
|
|
1256
|
+
}
|
|
1257
|
+
else {
|
|
1258
|
+
throw new utils_js_2.RuntimeExecutionError("Invalid value for 'copy' property", ctx);
|
|
1259
|
+
}
|
|
1260
|
+
break;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
else {
|
|
1264
|
+
const [, keyName] = path[0];
|
|
1265
|
+
if (keyName === 'arrange') {
|
|
1266
|
+
const [sideKeyCtx, sideKeyName] = path[1];
|
|
1267
|
+
if (globals_js_1.ValidPinSides.indexOf(sideKeyName) === -1) {
|
|
1268
|
+
throw new utils_js_2.RuntimeExecutionError(`Invalid side ${sideKeyName} in arrange`, sideKeyCtx);
|
|
1269
|
+
}
|
|
1270
|
+
else {
|
|
1271
|
+
if (path.length === 2 && value instanceof ParamDefinition_js_1.NumericValue) {
|
|
1272
|
+
checkPinExistsAndNotDuplicated(value.toNumber(), ctx);
|
|
1273
|
+
}
|
|
1274
|
+
else if (path.length > 2 && path[2][0] === 'index') {
|
|
1275
|
+
if (Array.isArray(value)) {
|
|
1276
|
+
const goodBlank = value.length === 1 &&
|
|
1277
|
+
value[0] instanceof ParamDefinition_js_1.NumericValue;
|
|
1278
|
+
if (!goodBlank) {
|
|
1279
|
+
throw new utils_js_2.RuntimeExecutionError(`Invalid blank specifier`, ctx);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
else {
|
|
1283
|
+
if (!(value instanceof ParamDefinition_js_1.NumericValue) && !(typeof value === 'string')) {
|
|
1284
|
+
throw new utils_js_2.RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx);
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
let useValue;
|
|
1288
|
+
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
1289
|
+
useValue = value.toNumber();
|
|
1290
|
+
}
|
|
1291
|
+
else if (typeof value === 'string') {
|
|
1292
|
+
useValue = value;
|
|
1293
|
+
}
|
|
1294
|
+
value && checkPinExistsAndNotDuplicated(useValue, ctx);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
else if (keyName === 'params') {
|
|
1301
|
+
const [, subKeyName] = path[1];
|
|
1302
|
+
switch (subKeyName) {
|
|
1303
|
+
case 'mpn':
|
|
1304
|
+
case 'refdes':
|
|
1305
|
+
case 'footprint':
|
|
1306
|
+
this.validateString(value, ctx);
|
|
1307
|
+
break;
|
|
1308
|
+
case 'place':
|
|
1309
|
+
this.validateBoolean(value, ctx);
|
|
1310
|
+
break;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
else if (keyName === 'pins') {
|
|
1314
|
+
if (path.length === 2) {
|
|
1315
|
+
const idName = path[1][1];
|
|
1316
|
+
definedPinIds.push(idName);
|
|
1317
|
+
if (value.length === 2) {
|
|
1318
|
+
const [pinType,] = value;
|
|
1319
|
+
if (pinType instanceof types_js_1.UndeclaredReference) {
|
|
1320
|
+
throw new utils_js_2.RuntimeExecutionError(`Invalid pin type: ${pinType.reference.name}`, ctx);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1296
1328
|
expandModuleContains(component, netNamespace) {
|
|
1297
1329
|
this.getExecutor().log('expanding module `contains`');
|
|
1298
1330
|
const executionStack = this.executionStack;
|
|
@@ -1341,6 +1373,40 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1341
1373
|
}
|
|
1342
1374
|
}
|
|
1343
1375
|
}
|
|
1376
|
+
setCurrentComponentRefdes(refdesValue, forceSave = false) {
|
|
1377
|
+
const currentComponent = this.getScope().currentComponent;
|
|
1378
|
+
if (currentComponent !== null) {
|
|
1379
|
+
if (refdesValue.indexOf('_') === -1) {
|
|
1380
|
+
currentComponent.setParam('refdes', refdesValue);
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
currentComponent.placeHolderRefDes = refdesValue;
|
|
1384
|
+
}
|
|
1385
|
+
currentComponent.forceSaveRefdesAnnotation = forceSave;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
async checkModuleHasRefdesFile(filePath) {
|
|
1389
|
+
const dir = this.environment.dirname(filePath);
|
|
1390
|
+
const ext = this.environment.extname(filePath);
|
|
1391
|
+
const basename = this.environment.basename(filePath, ext);
|
|
1392
|
+
const annotatedFilePath = this.environment.join(dir, `${basename}${globals_js_1.RefdesFileSuffix}`);
|
|
1393
|
+
const exists = await this.environment.exists(annotatedFilePath);
|
|
1394
|
+
if (exists) {
|
|
1395
|
+
this.log(`Import has refdes file: ${annotatedFilePath}`);
|
|
1396
|
+
const fileData = await this.environment.readFile(annotatedFilePath);
|
|
1397
|
+
const jsonData = JSON.parse(fileData);
|
|
1398
|
+
const baseFilePath = this.environment.getAbsolutePath(this.filePathStack[0]);
|
|
1399
|
+
const basePathDirectory = this.environment.dirname(baseFilePath);
|
|
1400
|
+
const { file, items } = jsonData;
|
|
1401
|
+
for (const item of items) {
|
|
1402
|
+
const parts = item.split(':');
|
|
1403
|
+
const refdes = parts[4];
|
|
1404
|
+
const useFilePath = this.environment.join(basePathDirectory, file);
|
|
1405
|
+
const key = this.getRefdesFileAnnotation(useFilePath, Number(parts[0]), Number(parts[1]), Number(parts[2]), Number(parts[3]));
|
|
1406
|
+
this.refdesFileAnnotations.set(key, refdes);
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1344
1410
|
resolveDataExpr(data_expr) {
|
|
1345
1411
|
const value = this.visitResult(data_expr);
|
|
1346
1412
|
if (value instanceof types_js_1.UndeclaredReference) {
|
|
@@ -1360,13 +1426,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1360
1426
|
return value;
|
|
1361
1427
|
}
|
|
1362
1428
|
}
|
|
1363
|
-
|
|
1429
|
+
extractPinDefintion(pinData, lastNumericPinId = 0) {
|
|
1364
1430
|
const pins = [];
|
|
1365
1431
|
if (pinData instanceof ParamDefinition_js_1.NumericValue) {
|
|
1366
1432
|
const tmpMap = new Map();
|
|
1367
1433
|
const lastPin = pinData.toNumber();
|
|
1368
1434
|
for (let i = 0; i < lastPin; i++) {
|
|
1369
|
-
const pinId = i + 1;
|
|
1435
|
+
const pinId = lastNumericPinId + i + 1;
|
|
1370
1436
|
tmpMap.set(pinId, (0, ParamDefinition_js_1.numeric)(pinId));
|
|
1371
1437
|
}
|
|
1372
1438
|
pinData = tmpMap;
|
|
@@ -1539,6 +1605,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1539
1605
|
const refdes = instance.getParam('refdes');
|
|
1540
1606
|
if (refdes) {
|
|
1541
1607
|
instance.assignedRefDes = refdes;
|
|
1608
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1542
1609
|
annotater.trackRefDes(refdes);
|
|
1543
1610
|
this.log(refdes, '-', instance.instanceName);
|
|
1544
1611
|
continue;
|
|
@@ -1552,6 +1619,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1552
1619
|
if (newRefDes !== null) {
|
|
1553
1620
|
instance.assignedRefDes = newRefDes;
|
|
1554
1621
|
this.log(newRefDes, '-', instance.instanceName);
|
|
1622
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1555
1623
|
}
|
|
1556
1624
|
else {
|
|
1557
1625
|
this.log('Failed to annotate:', instance.instanceName);
|
|
@@ -1562,6 +1630,24 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1562
1630
|
this.renameNetsWithRefdes();
|
|
1563
1631
|
this.log('===== rename nets done =====');
|
|
1564
1632
|
}
|
|
1633
|
+
setComponentUnitRefdesSuffix(instance) {
|
|
1634
|
+
if (instance.assignedRefDes) {
|
|
1635
|
+
const { units } = instance;
|
|
1636
|
+
if (units.length > 1) {
|
|
1637
|
+
units.forEach((unit, index) => {
|
|
1638
|
+
let useRefdes = String.fromCharCode("A".charCodeAt(0) + index);
|
|
1639
|
+
if (unit.suffix !== null) {
|
|
1640
|
+
useRefdes = unit.suffix;
|
|
1641
|
+
}
|
|
1642
|
+
unit.refdesSuffix = useRefdes;
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
else {
|
|
1646
|
+
const [firstUnit] = units;
|
|
1647
|
+
firstUnit.refdesSuffix = '';
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1565
1651
|
renameNetsWithRefdes() {
|
|
1566
1652
|
const nets = this.getScope().getNets();
|
|
1567
1653
|
const seenNets = [];
|
|
@@ -1620,10 +1706,17 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1620
1706
|
}
|
|
1621
1707
|
getPropertyExprList(items) {
|
|
1622
1708
|
const properties = new Map();
|
|
1709
|
+
const keyCounter = new Map();
|
|
1623
1710
|
items.forEach((item) => {
|
|
1624
1711
|
const result = this.visitResult(item);
|
|
1625
1712
|
for (const [key, value] of result) {
|
|
1626
|
-
|
|
1713
|
+
let useKey = key;
|
|
1714
|
+
const counterValue = keyCounter.get(key) ?? 0;
|
|
1715
|
+
keyCounter.set(key, counterValue + 1);
|
|
1716
|
+
if (counterValue > 0) {
|
|
1717
|
+
useKey = key + ':' + counterValue;
|
|
1718
|
+
}
|
|
1719
|
+
properties.set(useKey, value);
|
|
1627
1720
|
}
|
|
1628
1721
|
});
|
|
1629
1722
|
return properties;
|