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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { renderScript } from './helpers.js';
|
|
3
3
|
import { NodeScriptEnvironment } from "./environment.js";
|
|
4
|
-
const mainDir = './__tests__/renderData/';
|
|
4
|
+
const mainDir = './__tests__/testData/renderData/';
|
|
5
5
|
const env = new NodeScriptEnvironment();
|
|
6
6
|
NodeScriptEnvironment.setInstance(env);
|
|
7
7
|
async function regenerateTests(extra = "") {
|
|
@@ -9,7 +9,7 @@ async function regenerateTests(extra = "") {
|
|
|
9
9
|
const cstFiles = [];
|
|
10
10
|
const files = fs.readdirSync(mainDir);
|
|
11
11
|
files.forEach(file => {
|
|
12
|
-
if (file.endsWith('.cst')) {
|
|
12
|
+
if (file.endsWith('.cst') && file.startsWith('script')) {
|
|
13
13
|
cstFiles.push(file);
|
|
14
14
|
}
|
|
15
15
|
});
|
|
@@ -19,7 +19,7 @@ async function regenerateTests(extra = "") {
|
|
|
19
19
|
const scriptData = fs.readFileSync(inputPath, { encoding: 'utf-8' });
|
|
20
20
|
const outputPath = mainDir + 'svgs/' + file + extra + '.svg';
|
|
21
21
|
env.setModuleDirectory(mainDir);
|
|
22
|
-
env.setDefaultLibsPath(mainDir + '
|
|
22
|
+
env.setDefaultLibsPath(mainDir + '../../../libs/');
|
|
23
23
|
await renderScript(scriptData, outputPath, {
|
|
24
24
|
dumpNets: false,
|
|
25
25
|
dumpData: false,
|
package/dist/esm/render.js
CHANGED
|
@@ -36,10 +36,11 @@ export function renderSheetsToSVG(sheetFrames, logger) {
|
|
|
36
36
|
const frameComponent = sheet.frame.frame.parameters
|
|
37
37
|
.get(FrameParamKeys.SheetType);
|
|
38
38
|
if (frameComponent) {
|
|
39
|
-
|
|
39
|
+
const frameComponentUnit = frameComponent.getUnit();
|
|
40
|
+
if (frameComponentUnit.displayProp === null) {
|
|
40
41
|
throw 'Invalid graphic object for sheet frame';
|
|
41
42
|
}
|
|
42
|
-
const frameRects = ExtractDrawingRects(
|
|
43
|
+
const frameRects = ExtractDrawingRects(frameComponentUnit.displayProp) ?? [];
|
|
43
44
|
let originalWidthMM = numeric(0);
|
|
44
45
|
let originalHeightMM = numeric(0);
|
|
45
46
|
let widthMM = numeric(0);
|
|
@@ -325,7 +326,8 @@ function drawSheetFrameBorder(frameGroup, frame) {
|
|
|
325
326
|
const frameParams = frame.frame.parameters;
|
|
326
327
|
if (frameParams.has(FrameParamKeys.SheetType)) {
|
|
327
328
|
const frameComponent = frameParams.get(FrameParamKeys.SheetType);
|
|
328
|
-
const
|
|
329
|
+
const frameComponentUnit = frameComponent.getUnit();
|
|
330
|
+
const { displayProp = null } = frameComponentUnit ?? {};
|
|
329
331
|
if (displayProp) {
|
|
330
332
|
const sheetFrameGroup = frameGroup.group();
|
|
331
333
|
const symbol = new SymbolPlaceholder(displayProp);
|
|
@@ -8,25 +8,26 @@ export function RuleCheck_NoConnectOnConnectedPin(graph, nets) {
|
|
|
8
8
|
const makeComponentPinHash = (instanceName, pin) => {
|
|
9
9
|
return instanceName + '-' + pin.getHashValue();
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
const [component, pin, net] = item;
|
|
11
|
+
for (const [component, pin, net] of nets) {
|
|
13
12
|
if (!netComponentPins.has(net)) {
|
|
14
13
|
netComponentPins.set(net, []);
|
|
15
14
|
}
|
|
16
15
|
const items = netComponentPins.get(net);
|
|
16
|
+
const unit = component.getUnitForPin(pin);
|
|
17
17
|
items.push([
|
|
18
|
-
|
|
18
|
+
unit.instanceName,
|
|
19
19
|
pin
|
|
20
20
|
]);
|
|
21
21
|
netComponentPins.set(net, items);
|
|
22
|
-
pinMapping.set(makeComponentPinHash(
|
|
23
|
-
}
|
|
24
|
-
|
|
22
|
+
pinMapping.set(makeComponentPinHash(unit.instanceName, pin), net);
|
|
23
|
+
}
|
|
24
|
+
;
|
|
25
|
+
for (const node of allNodes) {
|
|
25
26
|
const nodeInfo = graph.node(node);
|
|
26
27
|
if (nodeInfo[0] === RenderItemType.Component) {
|
|
27
28
|
const { component } = nodeInfo[1];
|
|
28
29
|
if (component.hasParam('no_connect')) {
|
|
29
|
-
const instanceName = component.instanceName;
|
|
30
|
+
const instanceName = component.getUnit().instanceName;
|
|
30
31
|
const edges = graph.nodeEdges(node);
|
|
31
32
|
const otherNodes = [];
|
|
32
33
|
edges.forEach(edge => {
|
|
@@ -72,6 +73,6 @@ export function RuleCheck_NoConnectOnConnectedPin(graph, nets) {
|
|
|
72
73
|
});
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
|
-
}
|
|
76
|
+
}
|
|
76
77
|
return items;
|
|
77
78
|
}
|
|
@@ -22,7 +22,7 @@ export function EvaluateERCRules(visitor, graph, nets) {
|
|
|
22
22
|
reportItems.push({
|
|
23
23
|
type,
|
|
24
24
|
start: token,
|
|
25
|
-
message: `Unconnected pin ${item.pin}
|
|
25
|
+
message: `Unconnected pin: ${instance.assignedRefDes} pin ${item.pin}`
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -44,12 +44,17 @@ export function EvaluateERCRules(visitor, graph, nets) {
|
|
|
44
44
|
case ERC_Rules.NoConnectOnConnectedPin:
|
|
45
45
|
{
|
|
46
46
|
const instance = item.instance;
|
|
47
|
+
const { instance: targetComponent, pin: targetPin } = item.target;
|
|
48
|
+
let extra = '';
|
|
49
|
+
if (targetComponent && targetComponent.assignedRefDes) {
|
|
50
|
+
extra = `: ${targetComponent.assignedRefDes} pin ${targetPin}`;
|
|
51
|
+
}
|
|
47
52
|
const token = getComponentFirstCtxToken(instance);
|
|
48
53
|
if (token) {
|
|
49
54
|
reportItems.push({
|
|
50
55
|
type,
|
|
51
56
|
start: token,
|
|
52
|
-
message: `No connect on connected pin`
|
|
57
|
+
message: `No connect on connected pin${extra}`
|
|
53
58
|
});
|
|
54
59
|
}
|
|
55
60
|
}
|
|
@@ -3,13 +3,15 @@ import { ERC_Rules } from "./rules.js";
|
|
|
3
3
|
export function RuleCheck_UnconnectedPinsWires(graph) {
|
|
4
4
|
const items = [];
|
|
5
5
|
const allNodes = graph.nodes();
|
|
6
|
-
|
|
6
|
+
for (const node of allNodes) {
|
|
7
7
|
const nodeInfo = graph.node(node);
|
|
8
8
|
if (nodeInfo[0] === RenderItemType.Component) {
|
|
9
|
-
const
|
|
9
|
+
const renderComponent = nodeInfo[1];
|
|
10
|
+
const { component, unitId } = renderComponent;
|
|
10
11
|
const edges = graph.nodeEdges(node);
|
|
11
|
-
const
|
|
12
|
-
const
|
|
12
|
+
const componentUnit = component.getUnit(unitId);
|
|
13
|
+
const instanceName = componentUnit.instanceName;
|
|
14
|
+
const connectedUnitPins = [];
|
|
13
15
|
edges.forEach(edge => {
|
|
14
16
|
const edgeInfo = graph.edge(edge.v, edge.w);
|
|
15
17
|
let pin;
|
|
@@ -19,12 +21,12 @@ export function RuleCheck_UnconnectedPinsWires(graph) {
|
|
|
19
21
|
else if (edge.w === instanceName) {
|
|
20
22
|
pin = edgeInfo[3];
|
|
21
23
|
}
|
|
22
|
-
|
|
24
|
+
connectedUnitPins.push(pin.getHashValue());
|
|
23
25
|
});
|
|
24
|
-
const pinIds = Array.from(
|
|
26
|
+
const pinIds = Array.from(componentUnit.pins.keys());
|
|
25
27
|
pinIds.forEach(pinId => {
|
|
26
28
|
const hashValue = pinId.getHashValue();
|
|
27
|
-
if (
|
|
29
|
+
if (connectedUnitPins.indexOf(hashValue) === -1) {
|
|
28
30
|
items.push({
|
|
29
31
|
type: ERC_Rules.UnconnectedPin,
|
|
30
32
|
instance: component,
|
|
@@ -43,6 +45,6 @@ export function RuleCheck_UnconnectedPinsWires(graph) {
|
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
|
-
}
|
|
48
|
+
}
|
|
47
49
|
return items;
|
|
48
50
|
}
|
package/dist/esm/utils.js
CHANGED
|
@@ -58,7 +58,8 @@ export function getBoundsSize(bounds) {
|
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
export function getPortType(component) {
|
|
61
|
-
const
|
|
61
|
+
const targetUnit = component.getUnit();
|
|
62
|
+
const drawingCommands = targetUnit.displayProp;
|
|
62
63
|
let foundPinType = null;
|
|
63
64
|
const commands = drawingCommands.getCommands();
|
|
64
65
|
commands.some(item => {
|
|
@@ -7,16 +7,6 @@ import { BaseVisitor } from "../BaseVisitor.js";
|
|
|
7
7
|
import { BaseNamespace, SymbolValidatorContext } from "../globals.js";
|
|
8
8
|
export class SymbolValidatorVisitor extends BaseVisitor {
|
|
9
9
|
symbolTable = new SymbolTable();
|
|
10
|
-
filePathStack = [];
|
|
11
|
-
enterFile(filePath) {
|
|
12
|
-
this.filePathStack.push(filePath);
|
|
13
|
-
}
|
|
14
|
-
exitFile() {
|
|
15
|
-
this.filePathStack.pop();
|
|
16
|
-
}
|
|
17
|
-
getCurrentFile() {
|
|
18
|
-
return this.filePathStack[this.filePathStack.length - 1];
|
|
19
|
-
}
|
|
20
10
|
addSymbolVariable(token, name, value, executor = null) {
|
|
21
11
|
const useExecutor = executor === null ? this.getExecutor() : executor;
|
|
22
12
|
this.symbolTable.addVariable(token, this.getCurrentFile(), useExecutor, name, value);
|
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';
|
|
@@ -172,11 +172,117 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
172
172
|
if (ctxNotPathBlock) {
|
|
173
173
|
this.visit(ctxNotPathBlock);
|
|
174
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
|
+
}
|
|
175
185
|
};
|
|
176
186
|
visitCreate_component_expr = (ctx) => {
|
|
177
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() {
|
|
178
282
|
const definedPinIds = [];
|
|
179
283
|
const arrangedPinIds = [];
|
|
284
|
+
let didDefineArrangeProp = false;
|
|
285
|
+
let didDefineDisplayProp = false;
|
|
180
286
|
const checkPinExistsAndNotDuplicated = (pinId, ctx) => {
|
|
181
287
|
if (definedPinIds.indexOf(pinId) === -1) {
|
|
182
288
|
this.warnings.push({
|
|
@@ -191,9 +297,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
191
297
|
}
|
|
192
298
|
arrangedPinIds.push(pinId);
|
|
193
299
|
};
|
|
194
|
-
|
|
195
|
-
let didDefineDisplayProp = false;
|
|
196
|
-
scope.setOnPropertyHandler((path, value, ctx) => {
|
|
300
|
+
return (path, value, ctx) => {
|
|
197
301
|
if (path.length === 1) {
|
|
198
302
|
const [, keyName] = path[0];
|
|
199
303
|
switch (keyName) {
|
|
@@ -302,76 +406,8 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
302
406
|
}
|
|
303
407
|
}
|
|
304
408
|
}
|
|
305
|
-
});
|
|
306
|
-
scope.enterContext(ctx);
|
|
307
|
-
ctx.property_expr().forEach(item => {
|
|
308
|
-
this.visitResult(item);
|
|
309
|
-
});
|
|
310
|
-
scope.exitContext();
|
|
311
|
-
scope.popOnPropertyHandler();
|
|
312
|
-
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
313
|
-
let instanceName = this.getExecutor().getUniqueInstanceName();
|
|
314
|
-
const propParams = properties.get('params');
|
|
315
|
-
const params = this.parseCreateComponentParams(propParams);
|
|
316
|
-
if (params.length > 0) {
|
|
317
|
-
const firstParam = params[0];
|
|
318
|
-
const paramValue = firstParam.paramValue;
|
|
319
|
-
let appendValue = paramValue.toString();
|
|
320
|
-
if (paramValue instanceof NumericValue) {
|
|
321
|
-
appendValue = paramValue.value;
|
|
322
|
-
}
|
|
323
|
-
instanceName += `${Delimiter1}${appendValue}`;
|
|
324
|
-
}
|
|
325
|
-
const arrangeProp = properties.has('arrange') ?
|
|
326
|
-
properties.get('arrange') : null;
|
|
327
|
-
const displayProp = properties.has('display') ?
|
|
328
|
-
properties.get('display') : null;
|
|
329
|
-
const typeProp = properties.has('type') ?
|
|
330
|
-
properties.get('type') : null;
|
|
331
|
-
const copy = properties.has('copy') ?
|
|
332
|
-
properties.get('copy') : false;
|
|
333
|
-
const width = properties.has('width') ?
|
|
334
|
-
properties.get('width') : null;
|
|
335
|
-
const height = properties.has('height') ?
|
|
336
|
-
properties.get('height') : null;
|
|
337
|
-
const angle = properties.has(ParamKeys.angle) ?
|
|
338
|
-
properties.get(ParamKeys.angle) : null;
|
|
339
|
-
const followWireOrientation = properties.has('followWireOrientation') ?
|
|
340
|
-
properties.get('followWireOrientation') : true;
|
|
341
|
-
let pins = [];
|
|
342
|
-
if (displayProp !== null && arrangeProp === null
|
|
343
|
-
&& typeProp !== TypeProps.Graphic) {
|
|
344
|
-
const drawCommands = displayProp.getCommands();
|
|
345
|
-
drawCommands.forEach(command => {
|
|
346
|
-
const [commandValue,] = command;
|
|
347
|
-
if (commandValue === PlaceHolderCommands.vpin
|
|
348
|
-
|| commandValue === PlaceHolderCommands.hpin
|
|
349
|
-
|| commandValue === PlaceHolderCommands.pin) {
|
|
350
|
-
const id = PinId.from(command[1][0]);
|
|
351
|
-
const pinType = id.getType();
|
|
352
|
-
const pinName = id.toString();
|
|
353
|
-
pins.push(new PinDefinition(id, pinType, pinName, PinTypes.Any));
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
359
|
-
}
|
|
360
|
-
const props = {
|
|
361
|
-
arrange: arrangeProp,
|
|
362
|
-
display: displayProp,
|
|
363
|
-
type: typeProp, width, height, copy,
|
|
364
|
-
angle, followWireOrientation
|
|
365
409
|
};
|
|
366
|
-
|
|
367
|
-
const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
|
|
368
|
-
this.setResult(ctx, createdComponent);
|
|
369
|
-
createdComponent._creationIndex = this.componentCreationIndex++;
|
|
370
|
-
}
|
|
371
|
-
catch (error) {
|
|
372
|
-
this.throwWithContext(ctx, error.message);
|
|
373
|
-
}
|
|
374
|
-
};
|
|
410
|
+
}
|
|
375
411
|
visitCreate_graphic_expr = (ctx) => {
|
|
376
412
|
const ctxId = ctx.ID();
|
|
377
413
|
const paramIds = [];
|
|
@@ -506,19 +542,18 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
506
542
|
return new PinDefinition(index + 1, PinIdType.Int, portName, PinTypes.Any);
|
|
507
543
|
});
|
|
508
544
|
const arrange = this.getArrangePropFromModulePorts(modulePorts, nameToPinId);
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
545
|
+
const unitProperties = this.extractComponentUnitProperties(properties, TypeProps.Module);
|
|
546
|
+
const firstUnitDef = unitProperties[0][1];
|
|
547
|
+
firstUnitDef.pins = tmpPorts;
|
|
548
|
+
firstUnitDef.arrange = arrange;
|
|
513
549
|
const blankParams = [];
|
|
514
550
|
const props = {
|
|
515
|
-
arrange, width, height,
|
|
516
551
|
copy: false,
|
|
517
|
-
|
|
552
|
+
units: unitProperties,
|
|
518
553
|
};
|
|
519
554
|
const moduleInstanceName = this.getExecutor().getUniqueInstanceName();
|
|
520
555
|
const moduleComponent = this.getExecutor().createComponent(moduleInstanceName, tmpPorts, blankParams, props, true);
|
|
521
|
-
moduleComponent.typeProp =
|
|
556
|
+
moduleComponent.typeProp = TypeProps.Module;
|
|
522
557
|
const ctxPropertyBlock = ctx.property_block_expr();
|
|
523
558
|
if (ctxPropertyBlock) {
|
|
524
559
|
const [firstBlock] = ctxPropertyBlock;
|
|
@@ -541,6 +576,10 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
541
576
|
visitProperty_expr = (ctx) => {
|
|
542
577
|
const ctxKey = ctx.property_key_expr();
|
|
543
578
|
const ctxValue = ctx.property_value_expr();
|
|
579
|
+
const extraValue = ctx._extra;
|
|
580
|
+
if (extraValue) {
|
|
581
|
+
console.log('extra', extraValue.text);
|
|
582
|
+
}
|
|
544
583
|
const scope = this.getScope();
|
|
545
584
|
this.getScope().enterContext(ctxKey);
|
|
546
585
|
this.getScope().enterContext(ctxValue);
|
|
@@ -635,6 +674,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
635
674
|
dataResult = this.getExecutor().copyComponent(dataResult);
|
|
636
675
|
}
|
|
637
676
|
if (dataResult && dataResult instanceof ClassComponent) {
|
|
677
|
+
const defaultUnit = dataResult.getUnit();
|
|
638
678
|
const modifiers = ctx.component_modifier_expr();
|
|
639
679
|
modifiers.forEach(modifier => {
|
|
640
680
|
const modifierText = modifier.ID(0).getText();
|
|
@@ -651,23 +691,23 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
651
691
|
if (modifierText === ParamKeys.flip) {
|
|
652
692
|
const flipValue = result;
|
|
653
693
|
if (flipValue.indexOf('x') !== -1) {
|
|
654
|
-
|
|
694
|
+
defaultUnit.setParam(ParamKeys.flipX, numeric(1));
|
|
655
695
|
shouldIgnoreWireOrientation = true;
|
|
656
696
|
}
|
|
657
697
|
if (flipValue.indexOf('y') !== -1) {
|
|
658
|
-
|
|
698
|
+
defaultUnit.setParam(ParamKeys.flipY, numeric(1));
|
|
659
699
|
shouldIgnoreWireOrientation = true;
|
|
660
700
|
}
|
|
661
701
|
}
|
|
662
702
|
else if (modifierText === ParamKeys.angle) {
|
|
663
|
-
|
|
703
|
+
defaultUnit.setParam(ParamKeys.angle, result);
|
|
664
704
|
shouldIgnoreWireOrientation = true;
|
|
665
705
|
}
|
|
666
706
|
else if (modifierText === 'anchor') {
|
|
667
707
|
dataResult.setParam('anchor', result);
|
|
668
708
|
}
|
|
669
709
|
if (shouldIgnoreWireOrientation) {
|
|
670
|
-
|
|
710
|
+
defaultUnit.useWireOrientationAngle = false;
|
|
671
711
|
}
|
|
672
712
|
});
|
|
673
713
|
}
|
|
@@ -1206,17 +1246,21 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1206
1246
|
}
|
|
1207
1247
|
executor.popBreakContext();
|
|
1208
1248
|
};
|
|
1209
|
-
|
|
1210
|
-
const refdesID = ctx.ID().getText();
|
|
1249
|
+
setCurrentComponentRefdes(refdesValue, forceSave = false) {
|
|
1211
1250
|
const currentComponent = this.getScope().currentComponent;
|
|
1212
1251
|
if (currentComponent !== null) {
|
|
1213
|
-
if (
|
|
1214
|
-
currentComponent.setParam('refdes',
|
|
1252
|
+
if (refdesValue.indexOf('_') === -1) {
|
|
1253
|
+
currentComponent.setParam('refdes', refdesValue);
|
|
1215
1254
|
}
|
|
1216
1255
|
else {
|
|
1217
|
-
currentComponent.placeHolderRefDes =
|
|
1256
|
+
currentComponent.placeHolderRefDes = refdesValue;
|
|
1218
1257
|
}
|
|
1258
|
+
currentComponent.forceSaveRefdesAnnotation = forceSave;
|
|
1219
1259
|
}
|
|
1260
|
+
}
|
|
1261
|
+
visitAnnotation_comment_expr = (ctx) => {
|
|
1262
|
+
const refdesID = ctx.ID().getText();
|
|
1263
|
+
this.setCurrentComponentRefdes(refdesID);
|
|
1220
1264
|
};
|
|
1221
1265
|
visitPart_set_expr = (ctx) => {
|
|
1222
1266
|
const paramKeys = ctx.data_expr().map(ctx => {
|
|
@@ -1331,6 +1375,28 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1331
1375
|
children,
|
|
1332
1376
|
});
|
|
1333
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
|
+
}
|
|
1334
1400
|
resolveDataExpr(data_expr) {
|
|
1335
1401
|
const value = this.visitResult(data_expr);
|
|
1336
1402
|
if (value instanceof UndeclaredReference) {
|
|
@@ -1357,13 +1423,13 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1357
1423
|
PinTypes.Output,
|
|
1358
1424
|
PinTypes.Power,
|
|
1359
1425
|
];
|
|
1360
|
-
|
|
1426
|
+
extractPinDefintion(pinData, lastNumericPinId = 0) {
|
|
1361
1427
|
const pins = [];
|
|
1362
1428
|
if (pinData instanceof NumericValue) {
|
|
1363
1429
|
const tmpMap = new Map();
|
|
1364
1430
|
const lastPin = pinData.toNumber();
|
|
1365
1431
|
for (let i = 0; i < lastPin; i++) {
|
|
1366
|
-
const pinId = i + 1;
|
|
1432
|
+
const pinId = lastNumericPinId + i + 1;
|
|
1367
1433
|
tmpMap.set(pinId, numeric(pinId));
|
|
1368
1434
|
}
|
|
1369
1435
|
pinData = tmpMap;
|
|
@@ -1536,6 +1602,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1536
1602
|
const refdes = instance.getParam('refdes');
|
|
1537
1603
|
if (refdes) {
|
|
1538
1604
|
instance.assignedRefDes = refdes;
|
|
1605
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1539
1606
|
annotater.trackRefDes(refdes);
|
|
1540
1607
|
this.log(refdes, '-', instance.instanceName);
|
|
1541
1608
|
continue;
|
|
@@ -1549,6 +1616,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1549
1616
|
if (newRefDes !== null) {
|
|
1550
1617
|
instance.assignedRefDes = newRefDes;
|
|
1551
1618
|
this.log(newRefDes, '-', instance.instanceName);
|
|
1619
|
+
this.setComponentUnitRefdesSuffix(instance);
|
|
1552
1620
|
}
|
|
1553
1621
|
else {
|
|
1554
1622
|
this.log('Failed to annotate:', instance.instanceName);
|
|
@@ -1559,6 +1627,24 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1559
1627
|
this.renameNetsWithRefdes();
|
|
1560
1628
|
this.log('===== rename nets done =====');
|
|
1561
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
|
+
}
|
|
1562
1648
|
renameNetsWithRefdes() {
|
|
1563
1649
|
const nets = this.getScope().getNets();
|
|
1564
1650
|
const seenNets = [];
|
|
@@ -1617,10 +1703,17 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1617
1703
|
}
|
|
1618
1704
|
getPropertyExprList(items) {
|
|
1619
1705
|
const properties = new Map();
|
|
1706
|
+
const keyCounter = new Map();
|
|
1620
1707
|
items.forEach((item) => {
|
|
1621
1708
|
const result = this.visitResult(item);
|
|
1622
1709
|
for (const [key, value] of result) {
|
|
1623
|
-
|
|
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);
|
|
1624
1717
|
}
|
|
1625
1718
|
});
|
|
1626
1719
|
return properties;
|
|
@@ -5,7 +5,7 @@ import { Logger } from "./logger.js";
|
|
|
5
5
|
import { ClassComponent } from "./objects/ClassComponent.js";
|
|
6
6
|
import { Net } from "./objects/Net.js";
|
|
7
7
|
import { CallableParameter, ComplexType, Direction, FunctionDefinedParameter, AnyReference, ImportedModule, NewContextOptions, ImportFunctionHandling as ImportFunctionHandling } from "./objects/types.js";
|
|
8
|
-
import { ParserRuleContext } from 'antlr4ng';
|
|
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';
|
|
@@ -14,6 +14,7 @@ import { PinId } from './objects/PinDefinition.js';
|
|
|
14
14
|
export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyReference | any> {
|
|
15
15
|
startingContext: ExecutionContext;
|
|
16
16
|
executionStack: ExecutionContext[];
|
|
17
|
+
filePathStack: string[];
|
|
17
18
|
silent: boolean;
|
|
18
19
|
logger: Logger;
|
|
19
20
|
printStream: string[];
|
|
@@ -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;
|
|
@@ -75,6 +74,8 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
|
|
|
75
74
|
getComponentCtxLinks(): Map<ParserRuleContext, ClassComponent>;
|
|
76
75
|
visitResult(ctx: ParserRuleContext): any;
|
|
77
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;
|
|
78
79
|
visitRoundedBracketsExpr: (ctx: RoundedBracketsExprContext) => void;
|
|
79
80
|
protected setupDefinedParameters(funcDefinedParameters: FunctionDefinedParameter[], passedInParameters: CallableParameter[], executor: ExecutionContext): void;
|
|
80
81
|
protected runExpressions(executor: ExecutionContext, expressions: ExpressionContext[] | Function_exprContext[]): ComplexType;
|
|
@@ -88,6 +89,9 @@ export declare class BaseVisitor extends CircuitScriptVisitor<ComplexType | AnyR
|
|
|
88
89
|
protected validateString(value: any, context: ParserRuleContext): void;
|
|
89
90
|
protected validateBoolean(value: any, context: ParserRuleContext): void;
|
|
90
91
|
protected validateNumeric(value: any, context: ParserRuleContext): void;
|
|
92
|
+
enterFile(filePath: string): void;
|
|
93
|
+
exitFile(): void;
|
|
94
|
+
getCurrentFile(): string;
|
|
91
95
|
}
|
|
92
96
|
export type OnErrorHandler = (message: string, context: ParserRuleContext, e?: any) => void;
|
|
93
97
|
type ImportFile = {
|
|
@@ -97,4 +101,10 @@ type ImportFile = {
|
|
|
97
101
|
pathExists: boolean;
|
|
98
102
|
importedModule: ImportedModule;
|
|
99
103
|
};
|
|
104
|
+
export type ImportFileResult = {
|
|
105
|
+
hasError: boolean;
|
|
106
|
+
hasParseError: boolean;
|
|
107
|
+
tree: ScriptContext;
|
|
108
|
+
tokens: CommonTokenStream;
|
|
109
|
+
};
|
|
100
110
|
export {};
|