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/esm/visitor.js
CHANGED
|
@@ -3,7 +3,7 @@ import { NumberOperator, numeric, NumericValue, ParamDefinition } from './object
|
|
|
3
3
|
import { PinDefinition, PinId, PinIdType } from './objects/PinDefinition.js';
|
|
4
4
|
import { PinTypes } from './objects/PinTypes.js';
|
|
5
5
|
import { AnyReference, DeclaredReference, TypeProps, UndeclaredReference } from './objects/types.js';
|
|
6
|
-
import { BlockTypes, ComponentTypes, Delimiter1, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide, ValidPinSides, WireAutoDirection } from './globals.js';
|
|
6
|
+
import { BlockTypes, ComponentTypes, Delimiter1, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, RefdesFileSuffix, ReferenceTypes, SymbolPinSide, ValidPinSides, WireAutoDirection } from './globals.js';
|
|
7
7
|
import { unwrapValue } from "./utils.js";
|
|
8
8
|
import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.js';
|
|
9
9
|
import { BaseVisitor } from './BaseVisitor.js';
|
|
@@ -13,6 +13,16 @@ import { FrameParamKeys } from './objects/Frame.js';
|
|
|
13
13
|
import { ComponentAnnotater } from './ComponentAnnotater.js';
|
|
14
14
|
import { applyPartConditions, extractPartConditions, flattenConditionNodes } from './ComponentMatchConditions.js';
|
|
15
15
|
export class ParserVisitor extends BaseVisitor {
|
|
16
|
+
constructor(silent = false, onErrorHandler = null, environment) {
|
|
17
|
+
super(silent, onErrorHandler, environment);
|
|
18
|
+
if (environment) {
|
|
19
|
+
this.log('-- Environment --');
|
|
20
|
+
this.log('Module directory: ' + environment.getModuleDirectory());
|
|
21
|
+
this.log('Default libs path: ' + environment.getDefaultLibsPath());
|
|
22
|
+
this.log('Current file: ' + environment.getCurrentFile());
|
|
23
|
+
this.log('-----------------');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
16
26
|
componentCreationIndex = 0;
|
|
17
27
|
creationCtx = new Map();
|
|
18
28
|
visitKeyword_assignment_expr = (ctx) => {
|
|
@@ -162,11 +172,117 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
162
172
|
if (ctxNotPathBlock) {
|
|
163
173
|
this.visit(ctxNotPathBlock);
|
|
164
174
|
}
|
|
175
|
+
if (ctx.start && ctx.stop) {
|
|
176
|
+
const startToken = ctx.start;
|
|
177
|
+
const stopToken = ctx.stop;
|
|
178
|
+
const annotationKey = this.getRefdesFileAnnotation(this.getCurrentFile(), startToken.line, startToken.column, stopToken.line, stopToken.column);
|
|
179
|
+
if (this.refdesFileAnnotations.has(annotationKey)) {
|
|
180
|
+
let refdesValue = this.refdesFileAnnotations.get(annotationKey);
|
|
181
|
+
refdesValue = refdesValue.split(',')[0];
|
|
182
|
+
this.setCurrentComponentRefdes(refdesValue, true);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
165
185
|
};
|
|
166
186
|
visitCreate_component_expr = (ctx) => {
|
|
167
187
|
const scope = this.getScope();
|
|
188
|
+
scope.setOnPropertyHandler(this.createComponentPropertyValidator());
|
|
189
|
+
scope.enterContext(ctx);
|
|
190
|
+
ctx.property_expr().forEach(item => {
|
|
191
|
+
this.visitResult(item);
|
|
192
|
+
});
|
|
193
|
+
scope.exitContext();
|
|
194
|
+
scope.popOnPropertyHandler();
|
|
195
|
+
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
196
|
+
let instanceName = this.getExecutor().getUniqueInstanceName();
|
|
197
|
+
const propParams = properties.get('params');
|
|
198
|
+
const params = this.parseCreateComponentParams(propParams);
|
|
199
|
+
if (params.length > 0) {
|
|
200
|
+
const firstParam = params[0];
|
|
201
|
+
const paramValue = firstParam.paramValue;
|
|
202
|
+
let appendValue = paramValue.toString();
|
|
203
|
+
if (paramValue instanceof NumericValue) {
|
|
204
|
+
appendValue = paramValue.value;
|
|
205
|
+
}
|
|
206
|
+
instanceName += `${Delimiter1}${appendValue}`;
|
|
207
|
+
}
|
|
208
|
+
const typeProp = properties.get('type') ?? null;
|
|
209
|
+
const copy = properties.get('copy') ?? false;
|
|
210
|
+
const unitDefinitions = this.extractComponentUnitProperties(properties, typeProp);
|
|
211
|
+
const props = {
|
|
212
|
+
type: typeProp,
|
|
213
|
+
copy,
|
|
214
|
+
units: unitDefinitions
|
|
215
|
+
};
|
|
216
|
+
try {
|
|
217
|
+
const createdComponent = this.getExecutor().createComponent(instanceName, [], params, props);
|
|
218
|
+
this.setResult(ctx, createdComponent);
|
|
219
|
+
createdComponent._creationIndex = this.componentCreationIndex++;
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
this.throwWithContext(ctx, error.message);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
extractComponentUnitDefinition(properties, typeProp = null, lastNumericPinId = 0) {
|
|
226
|
+
const width = properties.get('width') ?? null;
|
|
227
|
+
const height = properties.get('height') ?? null;
|
|
228
|
+
const angle = properties.get(ParamKeys.angle) ?? null;
|
|
229
|
+
const followWireOrientation = properties.get('followWireOrientation') ?? true;
|
|
230
|
+
const arrange = properties.get('arrange') ?? null;
|
|
231
|
+
const display = properties.get('display') ?? null;
|
|
232
|
+
const suffix = properties.get('suffix') ?? null;
|
|
233
|
+
let pins = [];
|
|
234
|
+
if (display !== null && arrange === null && typeProp !== TypeProps.Graphic) {
|
|
235
|
+
const drawCommands = display.getCommands();
|
|
236
|
+
drawCommands.forEach(command => {
|
|
237
|
+
const [commandValue,] = command;
|
|
238
|
+
if (commandValue === PlaceHolderCommands.vpin
|
|
239
|
+
|| commandValue === PlaceHolderCommands.hpin
|
|
240
|
+
|| commandValue === PlaceHolderCommands.pin) {
|
|
241
|
+
const id = PinId.from(command[1][0]);
|
|
242
|
+
const pinType = id.getType();
|
|
243
|
+
const pinName = id.toString();
|
|
244
|
+
pins.push(new PinDefinition(id, pinType, pinName, PinTypes.Any));
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
pins = this.extractPinDefintion(properties.get('pins'), lastNumericPinId);
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
width,
|
|
253
|
+
height,
|
|
254
|
+
angle,
|
|
255
|
+
followWireOrientation,
|
|
256
|
+
display, arrange,
|
|
257
|
+
pins,
|
|
258
|
+
suffix
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
extractComponentUnitProperties(properties, typeProp) {
|
|
262
|
+
let lastNumericPinId = 0;
|
|
263
|
+
const unitsProperties = [];
|
|
264
|
+
for (const [key, value] of properties) {
|
|
265
|
+
if (key.split(':')[0] === 'unit') {
|
|
266
|
+
const unitDef = this.extractComponentUnitDefinition(value, typeProp, lastNumericPinId);
|
|
267
|
+
unitDef.pins.forEach(pin => {
|
|
268
|
+
if (pin.id.isNumeric()) {
|
|
269
|
+
lastNumericPinId = Math.max(lastNumericPinId, pin.id.getValue());
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
unitsProperties.push([key, unitDef]);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (unitsProperties.length === 0) {
|
|
276
|
+
unitsProperties.push(['unit',
|
|
277
|
+
this.extractComponentUnitDefinition(properties, typeProp)]);
|
|
278
|
+
}
|
|
279
|
+
return unitsProperties;
|
|
280
|
+
}
|
|
281
|
+
createComponentPropertyValidator() {
|
|
168
282
|
const definedPinIds = [];
|
|
169
283
|
const arrangedPinIds = [];
|
|
284
|
+
let didDefineArrangeProp = false;
|
|
285
|
+
let didDefineDisplayProp = false;
|
|
170
286
|
const checkPinExistsAndNotDuplicated = (pinId, ctx) => {
|
|
171
287
|
if (definedPinIds.indexOf(pinId) === -1) {
|
|
172
288
|
this.warnings.push({
|
|
@@ -181,9 +297,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
181
297
|
}
|
|
182
298
|
arrangedPinIds.push(pinId);
|
|
183
299
|
};
|
|
184
|
-
|
|
185
|
-
let didDefineDisplayProp = false;
|
|
186
|
-
scope.setOnPropertyHandler((path, value, ctx) => {
|
|
300
|
+
return (path, value, ctx) => {
|
|
187
301
|
if (path.length === 1) {
|
|
188
302
|
const [, keyName] = path[0];
|
|
189
303
|
switch (keyName) {
|
|
@@ -292,76 +406,8 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
292
406
|
}
|
|
293
407
|
}
|
|
294
408
|
}
|
|
295
|
-
});
|
|
296
|
-
scope.enterContext(ctx);
|
|
297
|
-
ctx.property_expr().forEach(item => {
|
|
298
|
-
this.visitResult(item);
|
|
299
|
-
});
|
|
300
|
-
scope.exitContext();
|
|
301
|
-
scope.popOnPropertyHandler();
|
|
302
|
-
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
303
|
-
let instanceName = this.getExecutor().getUniqueInstanceName();
|
|
304
|
-
const propParams = properties.get('params');
|
|
305
|
-
const params = this.parseCreateComponentParams(propParams);
|
|
306
|
-
if (params.length > 0) {
|
|
307
|
-
const firstParam = params[0];
|
|
308
|
-
const paramValue = firstParam.paramValue;
|
|
309
|
-
let appendValue = paramValue.toString();
|
|
310
|
-
if (paramValue instanceof NumericValue) {
|
|
311
|
-
appendValue = paramValue.value;
|
|
312
|
-
}
|
|
313
|
-
instanceName += `${Delimiter1}${appendValue}`;
|
|
314
|
-
}
|
|
315
|
-
const arrangeProp = properties.has('arrange') ?
|
|
316
|
-
properties.get('arrange') : null;
|
|
317
|
-
const displayProp = properties.has('display') ?
|
|
318
|
-
properties.get('display') : null;
|
|
319
|
-
const typeProp = properties.has('type') ?
|
|
320
|
-
properties.get('type') : null;
|
|
321
|
-
const copy = properties.has('copy') ?
|
|
322
|
-
properties.get('copy') : false;
|
|
323
|
-
const width = properties.has('width') ?
|
|
324
|
-
properties.get('width') : null;
|
|
325
|
-
const height = properties.has('height') ?
|
|
326
|
-
properties.get('height') : null;
|
|
327
|
-
const angle = properties.has(ParamKeys.angle) ?
|
|
328
|
-
properties.get(ParamKeys.angle) : null;
|
|
329
|
-
const followWireOrientation = properties.has('followWireOrientation') ?
|
|
330
|
-
properties.get('followWireOrientation') : true;
|
|
331
|
-
let pins = [];
|
|
332
|
-
if (displayProp !== null && arrangeProp === null
|
|
333
|
-
&& typeProp !== TypeProps.Graphic) {
|
|
334
|
-
const drawCommands = displayProp.getCommands();
|
|
335
|
-
drawCommands.forEach(command => {
|
|
336
|
-
const [commandValue,] = command;
|
|
337
|
-
if (commandValue === PlaceHolderCommands.vpin
|
|
338
|
-
|| commandValue === PlaceHolderCommands.hpin
|
|
339
|
-
|| commandValue === PlaceHolderCommands.pin) {
|
|
340
|
-
const id = PinId.from(command[1][0]);
|
|
341
|
-
const pinType = id.getType();
|
|
342
|
-
const pinName = id.toString();
|
|
343
|
-
pins.push(new PinDefinition(id, pinType, pinName, PinTypes.Any));
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
else {
|
|
348
|
-
pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
349
|
-
}
|
|
350
|
-
const props = {
|
|
351
|
-
arrange: arrangeProp,
|
|
352
|
-
display: displayProp,
|
|
353
|
-
type: typeProp, width, height, copy,
|
|
354
|
-
angle, followWireOrientation
|
|
355
409
|
};
|
|
356
|
-
|
|
357
|
-
const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
|
|
358
|
-
this.setResult(ctx, createdComponent);
|
|
359
|
-
createdComponent._creationIndex = this.componentCreationIndex++;
|
|
360
|
-
}
|
|
361
|
-
catch (error) {
|
|
362
|
-
this.throwWithContext(ctx, error.message);
|
|
363
|
-
}
|
|
364
|
-
};
|
|
410
|
+
}
|
|
365
411
|
visitCreate_graphic_expr = (ctx) => {
|
|
366
412
|
const ctxId = ctx.ID();
|
|
367
413
|
const paramIds = [];
|
|
@@ -496,19 +542,18 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
496
542
|
return new PinDefinition(index + 1, PinIdType.Int, portName, PinTypes.Any);
|
|
497
543
|
});
|
|
498
544
|
const arrange = this.getArrangePropFromModulePorts(modulePorts, nameToPinId);
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
545
|
+
const unitProperties = this.extractComponentUnitProperties(properties, TypeProps.Module);
|
|
546
|
+
const firstUnitDef = unitProperties[0][1];
|
|
547
|
+
firstUnitDef.pins = tmpPorts;
|
|
548
|
+
firstUnitDef.arrange = arrange;
|
|
503
549
|
const blankParams = [];
|
|
504
550
|
const props = {
|
|
505
|
-
arrange, width, height,
|
|
506
551
|
copy: false,
|
|
507
|
-
|
|
552
|
+
units: unitProperties,
|
|
508
553
|
};
|
|
509
554
|
const moduleInstanceName = this.getExecutor().getUniqueInstanceName();
|
|
510
555
|
const moduleComponent = this.getExecutor().createComponent(moduleInstanceName, tmpPorts, blankParams, props, true);
|
|
511
|
-
moduleComponent.typeProp =
|
|
556
|
+
moduleComponent.typeProp = TypeProps.Module;
|
|
512
557
|
const ctxPropertyBlock = ctx.property_block_expr();
|
|
513
558
|
if (ctxPropertyBlock) {
|
|
514
559
|
const [firstBlock] = ctxPropertyBlock;
|
|
@@ -531,6 +576,10 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
531
576
|
visitProperty_expr = (ctx) => {
|
|
532
577
|
const ctxKey = ctx.property_key_expr();
|
|
533
578
|
const ctxValue = ctx.property_value_expr();
|
|
579
|
+
const extraValue = ctx._extra;
|
|
580
|
+
if (extraValue) {
|
|
581
|
+
console.log('extra', extraValue.text);
|
|
582
|
+
}
|
|
534
583
|
const scope = this.getScope();
|
|
535
584
|
this.getScope().enterContext(ctxKey);
|
|
536
585
|
this.getScope().enterContext(ctxValue);
|
|
@@ -625,6 +674,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
625
674
|
dataResult = this.getExecutor().copyComponent(dataResult);
|
|
626
675
|
}
|
|
627
676
|
if (dataResult && dataResult instanceof ClassComponent) {
|
|
677
|
+
const defaultUnit = dataResult.getUnit();
|
|
628
678
|
const modifiers = ctx.component_modifier_expr();
|
|
629
679
|
modifiers.forEach(modifier => {
|
|
630
680
|
const modifierText = modifier.ID(0).getText();
|
|
@@ -641,23 +691,23 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
641
691
|
if (modifierText === ParamKeys.flip) {
|
|
642
692
|
const flipValue = result;
|
|
643
693
|
if (flipValue.indexOf('x') !== -1) {
|
|
644
|
-
|
|
694
|
+
defaultUnit.setParam(ParamKeys.flipX, numeric(1));
|
|
645
695
|
shouldIgnoreWireOrientation = true;
|
|
646
696
|
}
|
|
647
697
|
if (flipValue.indexOf('y') !== -1) {
|
|
648
|
-
|
|
698
|
+
defaultUnit.setParam(ParamKeys.flipY, numeric(1));
|
|
649
699
|
shouldIgnoreWireOrientation = true;
|
|
650
700
|
}
|
|
651
701
|
}
|
|
652
702
|
else if (modifierText === ParamKeys.angle) {
|
|
653
|
-
|
|
703
|
+
defaultUnit.setParam(ParamKeys.angle, result);
|
|
654
704
|
shouldIgnoreWireOrientation = true;
|
|
655
705
|
}
|
|
656
706
|
else if (modifierText === 'anchor') {
|
|
657
707
|
dataResult.setParam('anchor', result);
|
|
658
708
|
}
|
|
659
709
|
if (shouldIgnoreWireOrientation) {
|
|
660
|
-
|
|
710
|
+
defaultUnit.useWireOrientationAngle = false;
|
|
661
711
|
}
|
|
662
712
|
});
|
|
663
713
|
}
|
|
@@ -685,10 +735,8 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
685
735
|
+ component.instanceName
|
|
686
736
|
+ Delimiter1 + component.moduleCounter;
|
|
687
737
|
const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + Delimiter1 + component.moduleCounter);
|
|
688
|
-
|
|
738
|
+
this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
|
|
689
739
|
component.moduleCounter += 1;
|
|
690
|
-
newExecutor.resolveNet = this.createNetResolver(executionStack);
|
|
691
|
-
newExecutor.resolveComponentPinNet = this.createComponentPinNetResolver(executionStack);
|
|
692
740
|
this.visit(component.moduleContainsExpressions);
|
|
693
741
|
const executionContext = executionStack.pop();
|
|
694
742
|
component.moduleExecutionContext = executionContext;
|
|
@@ -886,7 +934,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
886
934
|
visitFunction_def_expr = (ctx) => {
|
|
887
935
|
const functionName = ctx.ID().getText();
|
|
888
936
|
const uniqueFunctionID = '__._' + ctx.start.line + '_'
|
|
889
|
-
+ ctx.start.column + '_' + functionName + '_' + ctx.getText();
|
|
937
|
+
+ ctx.start.column + '_' + functionName + '_' + this.environment.hashStringSHA256(ctx.getText());
|
|
890
938
|
let funcDefinedParameters = [];
|
|
891
939
|
const ctxFunctionArgsExpr = ctx.function_args_expr();
|
|
892
940
|
if (ctxFunctionArgsExpr) {
|
|
@@ -898,54 +946,17 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
898
946
|
const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
|
|
899
947
|
const __runFunc = (passedInParameters, options) => {
|
|
900
948
|
const executor = this.getExecutor();
|
|
901
|
-
const parentBreakContext = executor.getParentBreakContext();
|
|
902
|
-
executor.addBreakContext(ctx);
|
|
903
|
-
let useIndex = -1;
|
|
904
|
-
if (parentBreakContext === null) {
|
|
905
|
-
useIndex = options.functionCallIndex;
|
|
906
|
-
}
|
|
907
|
-
else {
|
|
908
|
-
const parentEntry = executor.indexedStack.get(parentBreakContext);
|
|
909
|
-
const { funcCallIndex } = parentEntry;
|
|
910
|
-
if (!funcCallIndex.has(ctx)) {
|
|
911
|
-
funcCallIndex.set(ctx, 0);
|
|
912
|
-
useIndex = 0;
|
|
913
|
-
}
|
|
914
|
-
else {
|
|
915
|
-
useIndex = funcCallIndex.get(ctx) + 1;
|
|
916
|
-
funcCallIndex.set(ctx, useIndex);
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
executor.setBreakContextIndex(useIndex);
|
|
920
949
|
const functionCounterIndex = functionCounter['counter'];
|
|
921
|
-
const executionContextName = `${functionName}-${functionCounterIndex}`;
|
|
922
|
-
const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
|
|
923
950
|
functionCounter['counter'] += 1;
|
|
951
|
+
const executionContextName = `${functionName}-${functionCounterIndex}`;
|
|
952
|
+
const newExecutor = this.handleEnterContext(executor, executionStack, executionContextName, ctx, options, funcDefinedParameters, passedInParameters);
|
|
924
953
|
newExecutor.resolveNet = resolveNet;
|
|
925
954
|
newExecutor.resolveComponentPinNet = resolveComponentPinNet;
|
|
926
955
|
const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
|
|
927
|
-
const lastExecution =
|
|
928
|
-
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
929
|
-
const mergedComponents = nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
930
|
-
const scope = this.getScope();
|
|
931
|
-
const indexedStack = [];
|
|
932
|
-
if (scope.breakStack.length > 0) {
|
|
933
|
-
const executor = this.getExecutor();
|
|
934
|
-
scope.breakStack.forEach(stackCtx => {
|
|
935
|
-
const entry = executor.indexedStack.get(stackCtx);
|
|
936
|
-
const { index } = entry;
|
|
937
|
-
indexedStack.push([stackCtx, index]);
|
|
938
|
-
});
|
|
939
|
-
mergedComponents.forEach(component => {
|
|
940
|
-
component.ctxReferences.forEach(ref => {
|
|
941
|
-
ref.indexedStack = [...indexedStack, ...ref.indexedStack];
|
|
942
|
-
});
|
|
943
|
-
});
|
|
944
|
-
}
|
|
945
|
-
executor.popBreakContext();
|
|
956
|
+
const lastExecution = this.handlePopContext(executor, executionStack, executionContextName);
|
|
946
957
|
return [lastExecution, returnValue];
|
|
947
958
|
};
|
|
948
|
-
this.getExecutor().createFunction(functionName, __runFunc, ctx, uniqueFunctionID);
|
|
959
|
+
this.getExecutor().createFunction(this.getExecutor().namespace, functionName, __runFunc, ctx, uniqueFunctionID);
|
|
949
960
|
};
|
|
950
961
|
visitPin_select_expr2 = (ctx) => {
|
|
951
962
|
const ctxStringValue = ctx.STRING_VALUE();
|
|
@@ -1235,17 +1246,21 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1235
1246
|
}
|
|
1236
1247
|
executor.popBreakContext();
|
|
1237
1248
|
};
|
|
1238
|
-
|
|
1239
|
-
const refdesID = ctx.ID().getText();
|
|
1249
|
+
setCurrentComponentRefdes(refdesValue, forceSave = false) {
|
|
1240
1250
|
const currentComponent = this.getScope().currentComponent;
|
|
1241
1251
|
if (currentComponent !== null) {
|
|
1242
|
-
if (
|
|
1243
|
-
currentComponent.setParam('refdes',
|
|
1252
|
+
if (refdesValue.indexOf('_') === -1) {
|
|
1253
|
+
currentComponent.setParam('refdes', refdesValue);
|
|
1244
1254
|
}
|
|
1245
1255
|
else {
|
|
1246
|
-
currentComponent.placeHolderRefDes =
|
|
1256
|
+
currentComponent.placeHolderRefDes = refdesValue;
|
|
1247
1257
|
}
|
|
1258
|
+
currentComponent.forceSaveRefdesAnnotation = forceSave;
|
|
1248
1259
|
}
|
|
1260
|
+
}
|
|
1261
|
+
visitAnnotation_comment_expr = (ctx) => {
|
|
1262
|
+
const refdesID = ctx.ID().getText();
|
|
1263
|
+
this.setCurrentComponentRefdes(refdesID);
|
|
1249
1264
|
};
|
|
1250
1265
|
visitPart_set_expr = (ctx) => {
|
|
1251
1266
|
const paramKeys = ctx.data_expr().map(ctx => {
|
|
@@ -1360,6 +1375,28 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1360
1375
|
children,
|
|
1361
1376
|
});
|
|
1362
1377
|
};
|
|
1378
|
+
async checkModuleHasRefdesFile(filePath) {
|
|
1379
|
+
const dir = this.environment.dirname(filePath);
|
|
1380
|
+
const ext = this.environment.extname(filePath);
|
|
1381
|
+
const basename = this.environment.basename(filePath, ext);
|
|
1382
|
+
const annotatedFilePath = this.environment.join(dir, `${basename}${RefdesFileSuffix}`);
|
|
1383
|
+
const exists = await this.environment.exists(annotatedFilePath);
|
|
1384
|
+
if (exists) {
|
|
1385
|
+
this.log(`Import has refdes file: ${annotatedFilePath}`);
|
|
1386
|
+
const fileData = await this.environment.readFile(annotatedFilePath);
|
|
1387
|
+
const jsonData = JSON.parse(fileData);
|
|
1388
|
+
const baseFilePath = this.environment.getAbsolutePath(this.filePathStack[0]);
|
|
1389
|
+
const basePathDirectory = this.environment.dirname(baseFilePath);
|
|
1390
|
+
const { file, items } = jsonData;
|
|
1391
|
+
for (const item of items) {
|
|
1392
|
+
const parts = item.split(':');
|
|
1393
|
+
const refdes = parts[4];
|
|
1394
|
+
const useFilePath = this.environment.join(basePathDirectory, file);
|
|
1395
|
+
const key = this.getRefdesFileAnnotation(useFilePath, Number(parts[0]), Number(parts[1]), Number(parts[2]), Number(parts[3]));
|
|
1396
|
+
this.refdesFileAnnotations.set(key, refdes);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1363
1400
|
resolveDataExpr(data_expr) {
|
|
1364
1401
|
const value = this.visitResult(data_expr);
|
|
1365
1402
|
if (value instanceof UndeclaredReference) {
|
|
@@ -1386,13 +1423,13 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1386
1423
|
PinTypes.Output,
|
|
1387
1424
|
PinTypes.Power,
|
|
1388
1425
|
];
|
|
1389
|
-
|
|
1426
|
+
extractPinDefintion(pinData, lastNumericPinId = 0) {
|
|
1390
1427
|
const pins = [];
|
|
1391
1428
|
if (pinData instanceof NumericValue) {
|
|
1392
1429
|
const tmpMap = new Map();
|
|
1393
1430
|
const lastPin = pinData.toNumber();
|
|
1394
1431
|
for (let i = 0; i < lastPin; i++) {
|
|
1395
|
-
const pinId = i + 1;
|
|
1432
|
+
const pinId = lastNumericPinId + i + 1;
|
|
1396
1433
|
tmpMap.set(pinId, numeric(pinId));
|
|
1397
1434
|
}
|
|
1398
1435
|
pinData = tmpMap;
|
|
@@ -1565,6 +1602,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1565
1602
|
const refdes = instance.getParam('refdes');
|
|
1566
1603
|
if (refdes) {
|
|
1567
1604
|
instance.assignedRefDes = refdes;
|
|
1605
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1568
1606
|
annotater.trackRefDes(refdes);
|
|
1569
1607
|
this.log(refdes, '-', instance.instanceName);
|
|
1570
1608
|
continue;
|
|
@@ -1578,6 +1616,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1578
1616
|
if (newRefDes !== null) {
|
|
1579
1617
|
instance.assignedRefDes = newRefDes;
|
|
1580
1618
|
this.log(newRefDes, '-', instance.instanceName);
|
|
1619
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1581
1620
|
}
|
|
1582
1621
|
else {
|
|
1583
1622
|
this.log('Failed to annotate:', instance.instanceName);
|
|
@@ -1588,6 +1627,24 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1588
1627
|
this.renameNetsWithRefdes();
|
|
1589
1628
|
this.log('===== rename nets done =====');
|
|
1590
1629
|
}
|
|
1630
|
+
setComponentUnitRefdesSuffix(instance) {
|
|
1631
|
+
if (instance.assignedRefDes) {
|
|
1632
|
+
const { units } = instance;
|
|
1633
|
+
if (units.length > 1) {
|
|
1634
|
+
units.forEach((unit, index) => {
|
|
1635
|
+
let useRefdes = String.fromCharCode("A".charCodeAt(0) + index);
|
|
1636
|
+
if (unit.suffix !== null) {
|
|
1637
|
+
useRefdes = unit.suffix;
|
|
1638
|
+
}
|
|
1639
|
+
unit.refdesSuffix = useRefdes;
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
else {
|
|
1643
|
+
const [firstUnit] = units;
|
|
1644
|
+
firstUnit.refdesSuffix = '';
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1591
1648
|
renameNetsWithRefdes() {
|
|
1592
1649
|
const nets = this.getScope().getNets();
|
|
1593
1650
|
const seenNets = [];
|
|
@@ -1646,10 +1703,17 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1646
1703
|
}
|
|
1647
1704
|
getPropertyExprList(items) {
|
|
1648
1705
|
const properties = new Map();
|
|
1706
|
+
const keyCounter = new Map();
|
|
1649
1707
|
items.forEach((item) => {
|
|
1650
1708
|
const result = this.visitResult(item);
|
|
1651
1709
|
for (const [key, value] of result) {
|
|
1652
|
-
|
|
1710
|
+
let useKey = key;
|
|
1711
|
+
const counterValue = keyCounter.get(key) ?? 0;
|
|
1712
|
+
keyCounter.set(key, counterValue + 1);
|
|
1713
|
+
if (counterValue > 0) {
|
|
1714
|
+
useKey = key + ':' + counterValue;
|
|
1715
|
+
}
|
|
1716
|
+
properties.set(useKey, value);
|
|
1653
1717
|
}
|
|
1654
1718
|
});
|
|
1655
1719
|
return properties;
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import { Array_exprContext, ArrayExprContext, ArrayIndexExprContext, Assignment_exprContext, Atom_exprContext, ExpressionContext, Flow_expressionsContext, Function_args_exprContext, Function_call_exprContext, Function_exprContext, Function_return_exprContext, FunctionCallExprContext, Import_exprContext, Operator_assignment_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, Trailer_expr2Context, Value_exprContext, ValueAtomExprContext } from "./antlr/CircuitScriptParser.js";
|
|
1
|
+
import { Array_exprContext, ArrayExprContext, ArrayIndexExprContext, Assignment_exprContext, Atom_exprContext, ExpressionContext, Flow_expressionsContext, Function_args_exprContext, Function_call_exprContext, Function_exprContext, Function_return_exprContext, FunctionCallExprContext, Import_all_simpleContext, Import_exprContext, Import_simpleContext, Import_specificContext, Operator_assignment_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, Trailer_expr2Context, Value_exprContext, ValueAtomExprContext } from "./antlr/CircuitScriptParser.js";
|
|
2
2
|
import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor.js";
|
|
3
3
|
import { ExecutionContext } from "./execute.js";
|
|
4
4
|
import { Logger } from "./logger.js";
|
|
5
5
|
import { ClassComponent } from "./objects/ClassComponent.js";
|
|
6
6
|
import { Net } from "./objects/Net.js";
|
|
7
|
-
import { CallableParameter,
|
|
8
|
-
import { ParserRuleContext } from 'antlr4ng';
|
|
7
|
+
import { CallableParameter, ComplexType, Direction, FunctionDefinedParameter, AnyReference, ImportedModule, NewContextOptions, ImportFunctionHandling as ImportFunctionHandling } from "./objects/types.js";
|
|
8
|
+
import { CommonTokenStream, ParserRuleContext } from 'antlr4ng';
|
|
9
9
|
import { ExecutionWarning } from "./utils.js";
|
|
10
10
|
import { BaseError } from './utils.js';
|
|
11
11
|
import { ExecutionScope } from './objects/ExecutionScope.js';
|
|
12
12
|
import { NodeScriptEnvironment } from "./environment.js";
|
|
13
13
|
import { PinId } from './objects/PinDefinition.js';
|
|
14
14
|
export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyReference | any> {
|
|
15
|
-
indentLevel: number;
|
|
16
15
|
startingContext: ExecutionContext;
|
|
17
16
|
executionStack: ExecutionContext[];
|
|
17
|
+
filePathStack: string[];
|
|
18
18
|
silent: boolean;
|
|
19
19
|
logger: Logger;
|
|
20
20
|
printStream: string[];
|
|
21
21
|
printToConsole: boolean;
|
|
22
|
+
allowParseImports: boolean;
|
|
22
23
|
acceptedDirections: Direction[];
|
|
23
24
|
protected resultData: Map<ParserRuleContext, any>;
|
|
24
25
|
protected componentCtxLinks: Map<ParserRuleContext, ClassComponent>;
|
|
@@ -27,10 +28,8 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
|
|
|
27
28
|
environment: NodeScriptEnvironment;
|
|
28
29
|
protected importedFiles: ImportFile[];
|
|
29
30
|
protected warnings: ExecutionWarning[];
|
|
30
|
-
onImportFile: (visitor: BaseVisitor, filePath: string, fileData: string, onErrorHandler: OnErrorHandler) => Promise<
|
|
31
|
-
|
|
32
|
-
hasParseError: boolean;
|
|
33
|
-
}>;
|
|
31
|
+
onImportFile: (visitor: BaseVisitor, filePath: string, fileData: string, onErrorHandler: OnErrorHandler) => Promise<ImportFileResult>;
|
|
32
|
+
refdesFileAnnotations: Map<string, string>;
|
|
34
33
|
constructor(silent: boolean | undefined, onErrorHandler: OnErrorHandler | null | undefined, environment: NodeScriptEnvironment);
|
|
35
34
|
getExecutor(): ExecutionContext;
|
|
36
35
|
getScope(): ExecutionScope;
|
|
@@ -45,6 +44,10 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
|
|
|
45
44
|
log2(message: string): void;
|
|
46
45
|
visitAsync(ctx: ParserRuleContext): Promise<void>;
|
|
47
46
|
visitScript: (ctx: ScriptContext) => Promise<void>;
|
|
47
|
+
private importCommon;
|
|
48
|
+
visitImport_simple: (ctx: Import_simpleContext) => Promise<void>;
|
|
49
|
+
visitImport_all_simple: (ctx: Import_all_simpleContext) => Promise<void>;
|
|
50
|
+
visitImport_specific: (ctx: Import_specificContext) => Promise<void>;
|
|
48
51
|
visitAssignment_expr: (ctx: Assignment_exprContext) => void;
|
|
49
52
|
visitOperator_assignment_expr: (ctx: Operator_assignment_exprContext) => void;
|
|
50
53
|
private getReference;
|
|
@@ -53,6 +56,8 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
|
|
|
53
56
|
visitFunctionCallExpr: (ctx: FunctionCallExprContext) => void;
|
|
54
57
|
visitFunction_call_expr: (ctx: Function_call_exprContext) => void;
|
|
55
58
|
private handleFunctionCall;
|
|
59
|
+
protected handleEnterContext(executor: ExecutionContext, executionStack: ExecutionContext[], contextName: string, ctx: ParserRuleContext, options: NewContextOptions, funcDefinedParameters: FunctionDefinedParameter[], passedInParameters: CallableParameter[], isBreakContext?: boolean): ExecutionContext;
|
|
60
|
+
protected handlePopContext(executor: ExecutionContext, executionStack: ExecutionContext[], namespaceExtension: string, isBreakContext?: boolean): ExecutionContext;
|
|
56
61
|
visitValue_expr: (ctx: Value_exprContext) => void;
|
|
57
62
|
visitValueAtomExpr: (ctx: ValueAtomExprContext) => void;
|
|
58
63
|
visitFunction_args_expr: (ctx: Function_args_exprContext) => void;
|
|
@@ -68,20 +73,25 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
|
|
|
68
73
|
protected linkComponentToCtx(ctx: ParserRuleContext, instance: ClassComponent, creationFlag?: boolean): void;
|
|
69
74
|
getComponentCtxLinks(): Map<ParserRuleContext, ClassComponent>;
|
|
70
75
|
visitResult(ctx: ParserRuleContext): any;
|
|
71
|
-
protected handleImportFile(name: string, throwErrors?: boolean, ctx?: ParserRuleContext | null): Promise<ImportFile>;
|
|
76
|
+
protected handleImportFile(name: string, importHandling: ImportFunctionHandling, throwErrors?: boolean, ctx?: ParserRuleContext | null, specificImports?: string[]): Promise<ImportFile>;
|
|
77
|
+
checkModuleHasRefdesFile(filePath: string): Promise<void>;
|
|
78
|
+
getRefdesFileAnnotation(filePath: string, startLine: number, startColumn: number, stopLine: number, stopColumn: number): string;
|
|
72
79
|
visitRoundedBracketsExpr: (ctx: RoundedBracketsExprContext) => void;
|
|
73
80
|
protected setupDefinedParameters(funcDefinedParameters: FunctionDefinedParameter[], passedInParameters: CallableParameter[], executor: ExecutionContext): void;
|
|
74
81
|
protected runExpressions(executor: ExecutionContext, expressions: ExpressionContext[] | Function_exprContext[]): ComplexType;
|
|
75
82
|
protected getNetNamespace(executorNetNamespace: string, passedNetNamespace: string | null): string;
|
|
76
83
|
protected setInstanceParam(object: ClassComponent, trailers: string[], value: any): void;
|
|
77
84
|
protected getInstanceParam<T>(object: ClassComponent, trailers: string[]): T;
|
|
78
|
-
protected enterNewChildContext(executionStack: ExecutionContext[], parentContext: ExecutionContext, executionContextName: string, options:
|
|
85
|
+
protected enterNewChildContext(executionStack: ExecutionContext[], parentContext: ExecutionContext, executionContextName: string, options: NewContextOptions, funcDefinedParameters: FunctionDefinedParameter[], passedInParameters: CallableParameter[]): ExecutionContext;
|
|
79
86
|
protected prepareStringValue(value: string): string;
|
|
80
87
|
protected throwWithContext(context: ParserRuleContext, messageOrError: string | BaseError): void;
|
|
81
88
|
protected validateType(value: any, context: ParserRuleContext, validateFunction: (value: any) => boolean, expectedType: string): boolean;
|
|
82
89
|
protected validateString(value: any, context: ParserRuleContext): void;
|
|
83
90
|
protected validateBoolean(value: any, context: ParserRuleContext): void;
|
|
84
91
|
protected validateNumeric(value: any, context: ParserRuleContext): void;
|
|
92
|
+
enterFile(filePath: string): void;
|
|
93
|
+
exitFile(): void;
|
|
94
|
+
getCurrentFile(): string;
|
|
85
95
|
}
|
|
86
96
|
export type OnErrorHandler = (message: string, context: ParserRuleContext, e?: any) => void;
|
|
87
97
|
type ImportFile = {
|
|
@@ -89,5 +99,12 @@ type ImportFile = {
|
|
|
89
99
|
hasError: boolean;
|
|
90
100
|
hasParseError: boolean;
|
|
91
101
|
pathExists: boolean;
|
|
102
|
+
importedModule: ImportedModule;
|
|
103
|
+
};
|
|
104
|
+
export type ImportFileResult = {
|
|
105
|
+
hasError: boolean;
|
|
106
|
+
hasParseError: boolean;
|
|
107
|
+
tree: ScriptContext;
|
|
108
|
+
tokens: CommonTokenStream;
|
|
92
109
|
};
|
|
93
110
|
export {};
|
|
@@ -27,9 +27,11 @@ export declare class RefdesAnnotationVisitor extends BaseVisitor {
|
|
|
27
27
|
private generateRefdesAnnotationComment;
|
|
28
28
|
private addRefdesAnnotationComment;
|
|
29
29
|
getOutput(): string;
|
|
30
|
+
getOutputForExternalRefdesFile(): string[];
|
|
30
31
|
private generateModifiedText;
|
|
31
32
|
private buildContextTokenRanges;
|
|
32
33
|
private findContextForToken;
|
|
33
34
|
private markTokensAsProcessed;
|
|
34
35
|
private log;
|
|
36
|
+
private generateReplacementText;
|
|
35
37
|
}
|