circuitscript 0.1.29 → 0.1.32
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 +185 -22
- package/dist/cjs/RefdesAnnotationVisitor.js +27 -10
- package/dist/cjs/antlr/CircuitScriptLexer.js +241 -236
- package/dist/cjs/antlr/CircuitScriptParser.js +1197 -901
- package/dist/cjs/builtinMethods.js +6 -2
- package/dist/cjs/draw_symbols.js +38 -34
- package/dist/cjs/environment.js +28 -4
- package/dist/cjs/execute.js +195 -125
- package/dist/cjs/globals.js +6 -1
- package/dist/cjs/graph.js +14 -12
- package/dist/cjs/helpers.js +90 -17
- package/dist/cjs/layout.js +50 -25
- package/dist/cjs/main.js +16 -14
- package/dist/cjs/objects/ClassComponent.js +199 -30
- package/dist/cjs/objects/ExecutionScope.js +9 -0
- package/dist/cjs/objects/types.js +25 -2
- package/dist/cjs/parser.js +6 -2
- 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/SymbolTable.js +7 -1
- package/dist/cjs/validate/SymbolValidatorVisitor.js +54 -17
- package/dist/cjs/visitor.js +299 -238
- package/dist/esm/BaseVisitor.js +187 -24
- package/dist/esm/RefdesAnnotationVisitor.js +27 -10
- package/dist/esm/antlr/CircuitScriptLexer.js +241 -236
- package/dist/esm/antlr/CircuitScriptParser.js +1196 -899
- package/dist/esm/antlr/CircuitScriptVisitor.js +4 -1
- package/dist/esm/builtinMethods.js +7 -3
- package/dist/esm/draw_symbols.js +38 -34
- package/dist/esm/environment.js +25 -1
- package/dist/esm/execute.js +197 -127
- package/dist/esm/globals.js +4 -0
- package/dist/esm/graph.js +14 -12
- package/dist/esm/helpers.js +91 -18
- package/dist/esm/layout.js +51 -26
- package/dist/esm/main.js +16 -14
- package/dist/esm/objects/ClassComponent.js +201 -30
- package/dist/esm/objects/ExecutionScope.js +9 -0
- package/dist/esm/objects/types.js +33 -1
- package/dist/esm/parser.js +6 -2
- 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/SymbolTable.js +5 -0
- package/dist/esm/validate/SymbolValidatorVisitor.js +53 -16
- package/dist/esm/visitor.js +201 -137
- package/dist/types/BaseVisitor.d.ts +27 -10
- package/dist/types/RefdesAnnotationVisitor.d.ts +2 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +43 -42
- package/dist/types/antlr/CircuitScriptParser.d.ts +102 -58
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +8 -2
- package/dist/types/environment.d.ts +8 -1
- package/dist/types/execute.d.ts +6 -3
- package/dist/types/globals.d.ts +4 -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/ExecutionScope.d.ts +3 -1
- package/dist/types/objects/types.d.ts +40 -3
- package/dist/types/validate/SymbolTable.d.ts +1 -0
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +6 -6
- package/dist/types/visitor.d.ts +10 -2
- package/package.json +4 -1
package/dist/cjs/visitor.js
CHANGED
|
@@ -16,8 +16,8 @@ const Frame_js_1 = require("./objects/Frame.js");
|
|
|
16
16
|
const ComponentAnnotater_js_1 = require("./ComponentAnnotater.js");
|
|
17
17
|
const ComponentMatchConditions_js_1 = require("./ComponentMatchConditions.js");
|
|
18
18
|
class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
19
|
-
constructor() {
|
|
20
|
-
super(
|
|
19
|
+
constructor(silent = false, onErrorHandler = null, environment) {
|
|
20
|
+
super(silent, onErrorHandler, environment);
|
|
21
21
|
this.componentCreationIndex = 0;
|
|
22
22
|
this.creationCtx = new Map();
|
|
23
23
|
this.visitKeyword_assignment_expr = (ctx) => {
|
|
@@ -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
|
}
|
|
@@ -841,7 +695,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
841
695
|
this.visitFunction_def_expr = (ctx) => {
|
|
842
696
|
const functionName = ctx.ID().getText();
|
|
843
697
|
const uniqueFunctionID = '__._' + ctx.start.line + '_'
|
|
844
|
-
+ ctx.start.column + '_' + functionName + '_' + ctx.getText();
|
|
698
|
+
+ ctx.start.column + '_' + functionName + '_' + this.environment.hashStringSHA256(ctx.getText());
|
|
845
699
|
let funcDefinedParameters = [];
|
|
846
700
|
const ctxFunctionArgsExpr = ctx.function_args_expr();
|
|
847
701
|
if (ctxFunctionArgsExpr) {
|
|
@@ -853,54 +707,17 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
853
707
|
const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
|
|
854
708
|
const __runFunc = (passedInParameters, options) => {
|
|
855
709
|
const executor = this.getExecutor();
|
|
856
|
-
const parentBreakContext = executor.getParentBreakContext();
|
|
857
|
-
executor.addBreakContext(ctx);
|
|
858
|
-
let useIndex = -1;
|
|
859
|
-
if (parentBreakContext === null) {
|
|
860
|
-
useIndex = options.functionCallIndex;
|
|
861
|
-
}
|
|
862
|
-
else {
|
|
863
|
-
const parentEntry = executor.indexedStack.get(parentBreakContext);
|
|
864
|
-
const { funcCallIndex } = parentEntry;
|
|
865
|
-
if (!funcCallIndex.has(ctx)) {
|
|
866
|
-
funcCallIndex.set(ctx, 0);
|
|
867
|
-
useIndex = 0;
|
|
868
|
-
}
|
|
869
|
-
else {
|
|
870
|
-
useIndex = funcCallIndex.get(ctx) + 1;
|
|
871
|
-
funcCallIndex.set(ctx, useIndex);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
executor.setBreakContextIndex(useIndex);
|
|
875
710
|
const functionCounterIndex = functionCounter['counter'];
|
|
876
|
-
const executionContextName = `${functionName}-${functionCounterIndex}`;
|
|
877
|
-
const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
|
|
878
711
|
functionCounter['counter'] += 1;
|
|
712
|
+
const executionContextName = `${functionName}-${functionCounterIndex}`;
|
|
713
|
+
const newExecutor = this.handleEnterContext(executor, executionStack, executionContextName, ctx, options, funcDefinedParameters, passedInParameters);
|
|
879
714
|
newExecutor.resolveNet = resolveNet;
|
|
880
715
|
newExecutor.resolveComponentPinNet = resolveComponentPinNet;
|
|
881
716
|
const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
|
|
882
|
-
const lastExecution =
|
|
883
|
-
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
884
|
-
const mergedComponents = nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
885
|
-
const scope = this.getScope();
|
|
886
|
-
const indexedStack = [];
|
|
887
|
-
if (scope.breakStack.length > 0) {
|
|
888
|
-
const executor = this.getExecutor();
|
|
889
|
-
scope.breakStack.forEach(stackCtx => {
|
|
890
|
-
const entry = executor.indexedStack.get(stackCtx);
|
|
891
|
-
const { index } = entry;
|
|
892
|
-
indexedStack.push([stackCtx, index]);
|
|
893
|
-
});
|
|
894
|
-
mergedComponents.forEach(component => {
|
|
895
|
-
component.ctxReferences.forEach(ref => {
|
|
896
|
-
ref.indexedStack = [...indexedStack, ...ref.indexedStack];
|
|
897
|
-
});
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
executor.popBreakContext();
|
|
717
|
+
const lastExecution = this.handlePopContext(executor, executionStack, executionContextName);
|
|
901
718
|
return [lastExecution, returnValue];
|
|
902
719
|
};
|
|
903
|
-
this.getExecutor().createFunction(functionName, __runFunc, ctx, uniqueFunctionID);
|
|
720
|
+
this.getExecutor().createFunction(this.getExecutor().namespace, functionName, __runFunc, ctx, uniqueFunctionID);
|
|
904
721
|
};
|
|
905
722
|
this.visitPin_select_expr2 = (ctx) => {
|
|
906
723
|
const ctxStringValue = ctx.STRING_VALUE();
|
|
@@ -1192,15 +1009,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1192
1009
|
};
|
|
1193
1010
|
this.visitAnnotation_comment_expr = (ctx) => {
|
|
1194
1011
|
const refdesID = ctx.ID().getText();
|
|
1195
|
-
|
|
1196
|
-
if (currentComponent !== null) {
|
|
1197
|
-
if (refdesID.indexOf('_') === -1) {
|
|
1198
|
-
currentComponent.setParam('refdes', refdesID);
|
|
1199
|
-
}
|
|
1200
|
-
else {
|
|
1201
|
-
currentComponent.placeHolderRefDes = refdesID;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1012
|
+
this.setCurrentComponentRefdes(refdesID);
|
|
1204
1013
|
};
|
|
1205
1014
|
this.visitPart_set_expr = (ctx) => {
|
|
1206
1015
|
const paramKeys = ctx.data_expr().map(ctx => {
|
|
@@ -1322,6 +1131,199 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1322
1131
|
PinTypes_js_1.PinTypes.Output,
|
|
1323
1132
|
PinTypes_js_1.PinTypes.Power,
|
|
1324
1133
|
];
|
|
1134
|
+
if (environment) {
|
|
1135
|
+
this.log('-- Environment --');
|
|
1136
|
+
this.log('Module directory: ' + environment.getModuleDirectory());
|
|
1137
|
+
this.log('Default libs path: ' + environment.getDefaultLibsPath());
|
|
1138
|
+
this.log('Current file: ' + environment.getCurrentFile());
|
|
1139
|
+
this.log('-----------------');
|
|
1140
|
+
}
|
|
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
|
+
};
|
|
1325
1327
|
}
|
|
1326
1328
|
expandModuleContains(component, netNamespace) {
|
|
1327
1329
|
this.getExecutor().log('expanding module `contains`');
|
|
@@ -1331,10 +1333,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1331
1333
|
+ component.instanceName
|
|
1332
1334
|
+ globals_js_1.Delimiter1 + component.moduleCounter;
|
|
1333
1335
|
const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + globals_js_1.Delimiter1 + component.moduleCounter);
|
|
1334
|
-
|
|
1336
|
+
this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
|
|
1335
1337
|
component.moduleCounter += 1;
|
|
1336
|
-
newExecutor.resolveNet = this.createNetResolver(executionStack);
|
|
1337
|
-
newExecutor.resolveComponentPinNet = this.createComponentPinNetResolver(executionStack);
|
|
1338
1338
|
this.visit(component.moduleContainsExpressions);
|
|
1339
1339
|
const executionContext = executionStack.pop();
|
|
1340
1340
|
component.moduleExecutionContext = executionContext;
|
|
@@ -1373,6 +1373,40 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1373
1373
|
}
|
|
1374
1374
|
}
|
|
1375
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
|
+
}
|
|
1376
1410
|
resolveDataExpr(data_expr) {
|
|
1377
1411
|
const value = this.visitResult(data_expr);
|
|
1378
1412
|
if (value instanceof types_js_1.UndeclaredReference) {
|
|
@@ -1392,13 +1426,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1392
1426
|
return value;
|
|
1393
1427
|
}
|
|
1394
1428
|
}
|
|
1395
|
-
|
|
1429
|
+
extractPinDefintion(pinData, lastNumericPinId = 0) {
|
|
1396
1430
|
const pins = [];
|
|
1397
1431
|
if (pinData instanceof ParamDefinition_js_1.NumericValue) {
|
|
1398
1432
|
const tmpMap = new Map();
|
|
1399
1433
|
const lastPin = pinData.toNumber();
|
|
1400
1434
|
for (let i = 0; i < lastPin; i++) {
|
|
1401
|
-
const pinId = i + 1;
|
|
1435
|
+
const pinId = lastNumericPinId + i + 1;
|
|
1402
1436
|
tmpMap.set(pinId, (0, ParamDefinition_js_1.numeric)(pinId));
|
|
1403
1437
|
}
|
|
1404
1438
|
pinData = tmpMap;
|
|
@@ -1571,6 +1605,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1571
1605
|
const refdes = instance.getParam('refdes');
|
|
1572
1606
|
if (refdes) {
|
|
1573
1607
|
instance.assignedRefDes = refdes;
|
|
1608
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1574
1609
|
annotater.trackRefDes(refdes);
|
|
1575
1610
|
this.log(refdes, '-', instance.instanceName);
|
|
1576
1611
|
continue;
|
|
@@ -1584,6 +1619,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1584
1619
|
if (newRefDes !== null) {
|
|
1585
1620
|
instance.assignedRefDes = newRefDes;
|
|
1586
1621
|
this.log(newRefDes, '-', instance.instanceName);
|
|
1622
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1587
1623
|
}
|
|
1588
1624
|
else {
|
|
1589
1625
|
this.log('Failed to annotate:', instance.instanceName);
|
|
@@ -1594,6 +1630,24 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1594
1630
|
this.renameNetsWithRefdes();
|
|
1595
1631
|
this.log('===== rename nets done =====');
|
|
1596
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
|
+
}
|
|
1597
1651
|
renameNetsWithRefdes() {
|
|
1598
1652
|
const nets = this.getScope().getNets();
|
|
1599
1653
|
const seenNets = [];
|
|
@@ -1652,10 +1706,17 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1652
1706
|
}
|
|
1653
1707
|
getPropertyExprList(items) {
|
|
1654
1708
|
const properties = new Map();
|
|
1709
|
+
const keyCounter = new Map();
|
|
1655
1710
|
items.forEach((item) => {
|
|
1656
1711
|
const result = this.visitResult(item);
|
|
1657
1712
|
for (const [key, value] of result) {
|
|
1658
|
-
|
|
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);
|
|
1659
1720
|
}
|
|
1660
1721
|
});
|
|
1661
1722
|
return properties;
|