circuitscript 0.0.17 → 0.0.19
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/__tests__/parseScripts.ts +160 -1
- package/__tests__/renderData/script1.cst.svg +1 -1
- package/__tests__/renderData/script5.cst.svg +1 -1
- package/__tests__/renderData/script6.cst +28 -0
- package/__tests__/renderData/script6.cst.svg +1 -0
- package/__tests__/renderData/script7.cst +26 -0
- package/__tests__/renderData/script7.cst.svg +1 -0
- package/__tests__/renderData/script8.cst +37 -0
- package/__tests__/renderData/script8.cst.svg +1 -0
- package/__tests__/testParse.ts +6 -2
- package/__tests__/testRender.ts +4 -1
- package/build/src/antlr/CircuitScriptLexer.js +152 -143
- package/build/src/antlr/CircuitScriptParser.js +731 -619
- package/build/src/antlr/CircuitScriptVisitor.js +2 -2
- package/build/src/draw_symbols.js +5 -2
- package/build/src/execute.js +140 -73
- package/build/src/export.js +2 -2
- package/build/src/globals.js +8 -0
- package/build/src/layout.js +27 -13
- package/build/src/objects/ExecutionScope.js +1 -1
- package/build/src/visitor.js +51 -25
- package/package.json +1 -1
- package/src/antlr/CircuitScript.g4 +9 -7
- package/src/antlr/CircuitScriptLexer.ts +152 -143
- package/src/antlr/CircuitScriptParser.ts +728 -616
- package/src/antlr/CircuitScriptVisitor.ts +6 -6
- package/src/draw_symbols.ts +7 -2
- package/src/execute.ts +185 -91
- package/src/export.ts +2 -2
- package/src/globals.ts +8 -0
- package/src/layout.ts +54 -29
- package/src/objects/ExecutionScope.ts +11 -3
- package/src/visitor.ts +64 -37
|
@@ -7,8 +7,8 @@ import {ParseTreeVisitor} from 'antlr4';
|
|
|
7
7
|
|
|
8
8
|
import { ScriptContext } from "./CircuitScriptParser";
|
|
9
9
|
import { ExpressionContext } from "./CircuitScriptParser";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { Path_blocksContext } from "./CircuitScriptParser";
|
|
11
|
+
import { Path_block_innerContext } from "./CircuitScriptParser";
|
|
12
12
|
import { Property_set_expr2Context } from "./CircuitScriptParser";
|
|
13
13
|
import { Assignment_expr2Context } from "./CircuitScriptParser";
|
|
14
14
|
import { Data_expr_with_assignmentContext } from "./CircuitScriptParser";
|
|
@@ -82,17 +82,17 @@ export default class CircuitScriptVisitor<Result> extends ParseTreeVisitor<Resul
|
|
|
82
82
|
*/
|
|
83
83
|
visitExpression?: (ctx: ExpressionContext) => Result;
|
|
84
84
|
/**
|
|
85
|
-
* Visit a parse tree produced by `CircuitScriptParser.
|
|
85
|
+
* Visit a parse tree produced by `CircuitScriptParser.path_blocks`.
|
|
86
86
|
* @param ctx the parse tree
|
|
87
87
|
* @return the visitor result
|
|
88
88
|
*/
|
|
89
|
-
|
|
89
|
+
visitPath_blocks?: (ctx: Path_blocksContext) => Result;
|
|
90
90
|
/**
|
|
91
|
-
* Visit a parse tree produced by `CircuitScriptParser.
|
|
91
|
+
* Visit a parse tree produced by `CircuitScriptParser.path_block_inner`.
|
|
92
92
|
* @param ctx the parse tree
|
|
93
93
|
* @return the visitor result
|
|
94
94
|
*/
|
|
95
|
-
|
|
95
|
+
visitPath_block_inner?: (ctx: Path_block_innerContext) => Result;
|
|
96
96
|
/**
|
|
97
97
|
* Visit a parse tree produced by `CircuitScriptParser.property_set_expr2`.
|
|
98
98
|
* @param ctx the parse tree
|
package/src/draw_symbols.ts
CHANGED
|
@@ -93,10 +93,15 @@ export abstract class SymbolGraphic {
|
|
|
93
93
|
pinPosition(id: number): { x: number; y: number; angle: number; } {
|
|
94
94
|
const pin = this.drawing.getPinPosition(id);
|
|
95
95
|
|
|
96
|
+
// Allow pin position values to be rounded to 4 d.p
|
|
97
|
+
const [x, y] = pin.start;
|
|
98
|
+
const useX = Math.round(x * 10000) / 10000;
|
|
99
|
+
const useY = Math.round(y * 10000 / 10000);
|
|
100
|
+
|
|
96
101
|
if (pin) {
|
|
97
102
|
return {
|
|
98
|
-
x:
|
|
99
|
-
y:
|
|
103
|
+
x: useX,
|
|
104
|
+
y: useY,
|
|
100
105
|
angle: pin.angle,
|
|
101
106
|
}
|
|
102
107
|
}
|
package/src/execute.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentTypes, GlobalNames, ParamKeys, ReferenceTypes } from './globals.js';
|
|
1
|
+
import { BlockTypes, ComponentTypes, GlobalNames, NoNetText, ParamKeys, ReferenceTypes } from './globals.js';
|
|
2
2
|
import { ClassComponent } from './objects/ClassComponent.js';
|
|
3
3
|
import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.js';
|
|
4
4
|
import { Net } from './objects/Net.js';
|
|
@@ -26,6 +26,8 @@ export class ExecutionContext {
|
|
|
26
26
|
|
|
27
27
|
scope: ExecutionScope;
|
|
28
28
|
|
|
29
|
+
tmpPointId = 0; // Counter for points created within the context
|
|
30
|
+
|
|
29
31
|
resolveNet: (name: string, netNamespace:string) => ({
|
|
30
32
|
found: boolean, net?: Net
|
|
31
33
|
}) = null;
|
|
@@ -316,12 +318,22 @@ export class ExecutionContext {
|
|
|
316
318
|
return component;
|
|
317
319
|
}
|
|
318
320
|
|
|
319
|
-
printPoint(): void {
|
|
321
|
+
printPoint(extra = ''): void {
|
|
322
|
+
let netName = NoNetText;
|
|
323
|
+
if (this.scope.hasNet(
|
|
324
|
+
this.scope.currentComponent,
|
|
325
|
+
this.scope.currentPin
|
|
326
|
+
)) {
|
|
327
|
+
netName = this.scope
|
|
328
|
+
.getNet(this.scope.currentComponent, this.scope.currentPin)
|
|
329
|
+
.toString();
|
|
330
|
+
}
|
|
331
|
+
|
|
320
332
|
this.print(
|
|
321
|
-
'point: ' +
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
333
|
+
(extra !== '' ? (extra + ' ') : '') + 'point: ' +
|
|
334
|
+
this.scope.currentComponent.instanceName +
|
|
335
|
+
' ' +
|
|
336
|
+
this.scope.currentPin + ' ' + netName
|
|
325
337
|
);
|
|
326
338
|
}
|
|
327
339
|
|
|
@@ -524,117 +536,183 @@ export class ExecutionContext {
|
|
|
524
536
|
return clonedComponent;
|
|
525
537
|
}
|
|
526
538
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
539
|
+
enterBlocks(blockType: BlockTypes): void {
|
|
540
|
+
// Create object to track all the inner blocks of
|
|
541
|
+
// the block group
|
|
542
|
+
|
|
543
|
+
if (blockType === BlockTypes.Point) {
|
|
544
|
+
this.addPoint(`_point.${this.name}.${this.tmpPointId}`, false);
|
|
545
|
+
this.tmpPointId += 1;
|
|
546
|
+
} else if (blockType === BlockTypes.Parallel) {
|
|
547
|
+
this.addPoint(`_parallel.${this.name}.${this.tmpPointId}`, false);
|
|
548
|
+
this.tmpPointId += 1;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
this.scope.blockStack.set(this.scope.indentLevel, {
|
|
552
|
+
// Tracks the position when the block is entered
|
|
553
|
+
entered_at: [
|
|
554
|
+
this.scope.currentComponent,
|
|
555
|
+
this.scope.currentPin,
|
|
556
|
+
this.scope.currentWireId],
|
|
557
|
+
inner_blocks: new Map<number, any>(),
|
|
532
558
|
current_index: null,
|
|
559
|
+
type: blockType,
|
|
533
560
|
});
|
|
534
561
|
|
|
535
|
-
this.print('enter
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
exitBranches(): void {
|
|
539
|
-
false && this.joinBranches();
|
|
540
|
-
|
|
541
|
-
this.print('exit branches');
|
|
562
|
+
this.print('enter blocks');
|
|
542
563
|
}
|
|
543
564
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
const innerBranches = this.scope.branchStack.get(
|
|
565
|
+
exitBlocks(): void {
|
|
566
|
+
const stackRef = this.scope.blockStack.get(
|
|
547
567
|
this.scope.indentLevel,
|
|
548
|
-
)
|
|
568
|
+
);
|
|
549
569
|
|
|
550
|
-
const
|
|
570
|
+
const { type: blockType } = stackRef;
|
|
551
571
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
572
|
+
if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
|
|
573
|
+
// Move to the end location of the first block
|
|
574
|
+
const { final_point: finalPoint } = stackRef;
|
|
575
|
+
const [component, pin, wireId] = finalPoint;
|
|
556
576
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}
|
|
577
|
+
this.scope.currentComponent = component;
|
|
578
|
+
this.scope.currentPin = pin;
|
|
579
|
+
this.scope.currentWireId = wireId;
|
|
561
580
|
|
|
562
|
-
|
|
581
|
+
if (wireId !== -1) {
|
|
582
|
+
this.scope.sequence.push([
|
|
583
|
+
SequenceAction.WireJump, wireId, 1
|
|
584
|
+
]);
|
|
563
585
|
}
|
|
564
|
-
}
|
|
586
|
+
} else if (blockType === BlockTypes.Point) {
|
|
587
|
+
const { entered_at: [component, pin,] } =
|
|
588
|
+
stackRef;
|
|
565
589
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
// Sort the nets so that the net with the highest priority is first
|
|
570
|
-
const sortedNets = lastNets.sort((a, b) => {
|
|
571
|
-
if (a[0] > b[0]) {
|
|
572
|
-
return -1;
|
|
573
|
-
} else if (a[0] < b[0]) {
|
|
574
|
-
return 1;
|
|
575
|
-
} else {
|
|
576
|
-
return 0;
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
|
|
580
|
-
// Not always a good idea to always use the first item for combining...
|
|
581
|
-
const [comp1, pin1] = sortedNets[0][1];
|
|
582
|
-
|
|
583
|
-
const tmpList = sortedNets.slice(1);
|
|
584
|
-
tmpList.forEach((item) => {
|
|
585
|
-
const [, [comp2, pin2]] = item;
|
|
586
|
-
|
|
587
|
-
this.atComponent(comp1, pin1, {addSequence: true});
|
|
588
|
-
this.toComponent(comp2, pin2, {addSequence: true});
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
this.scope.currentComponent = comp1;
|
|
592
|
-
this.scope.currentPin = pin1;
|
|
590
|
+
// Preblock location should be a created point without any wires
|
|
591
|
+
this.atComponent(component, pin, { addSequence: true });
|
|
593
592
|
}
|
|
594
|
-
}
|
|
595
593
|
|
|
596
|
-
|
|
597
|
-
|
|
594
|
+
this.print('exit blocks');
|
|
595
|
+
}
|
|
598
596
|
|
|
599
|
-
|
|
600
|
-
|
|
597
|
+
enterBlock(blockIndex: number): void {
|
|
598
|
+
// Current net before any blocks is already stored in enterBlocks()
|
|
599
|
+
const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
|
|
600
|
+
stackRef['block_index'] = blockIndex;
|
|
601
601
|
|
|
602
|
-
|
|
602
|
+
const { type: blockType } = stackRef;
|
|
603
603
|
|
|
604
|
-
// Setup the state for the inner
|
|
605
|
-
stackRef['
|
|
604
|
+
// Setup the state for the inner block at the given index
|
|
605
|
+
stackRef['inner_blocks'].set(blockIndex, {
|
|
606
606
|
last_net: null,
|
|
607
607
|
ignore_last_net: false,
|
|
608
608
|
});
|
|
609
609
|
|
|
610
|
+
if (blockType === BlockTypes.Join || blockType === BlockTypes.Point) {
|
|
611
|
+
// Clear current component, pin, wire before entering the block
|
|
612
|
+
this.scope.currentComponent = null;
|
|
613
|
+
this.scope.currentPin = null;
|
|
614
|
+
this.scope.currentWireId = -1;
|
|
615
|
+
} else if (blockType === BlockTypes.Parallel) {
|
|
616
|
+
// Move to starting point of the parallel blocks
|
|
617
|
+
const { entered_at: [component, pin,] } = stackRef;
|
|
618
|
+
this.atComponent(component, pin, { addSequence: true });
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
this.print(`enter inner block of type (${blockType}) >>>`);
|
|
622
|
+
|
|
610
623
|
this.scope.indentLevel += 1;
|
|
611
624
|
}
|
|
612
625
|
|
|
613
|
-
|
|
614
|
-
const stackRef = this.scope.
|
|
626
|
+
exitBlock(blockIndex: number): void {
|
|
627
|
+
const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1);
|
|
628
|
+
const { type: blockType } = stackRef;
|
|
615
629
|
|
|
616
630
|
// Save the last net reference
|
|
617
|
-
const
|
|
618
|
-
|
|
631
|
+
const blockIndexRef = stackRef['inner_blocks'].get(blockIndex);
|
|
632
|
+
blockIndexRef['last_net'] = [
|
|
619
633
|
this.scope.currentComponent,
|
|
620
634
|
this.scope.currentPin,
|
|
635
|
+
this.scope.currentWireId
|
|
621
636
|
];
|
|
622
637
|
|
|
623
|
-
stackRef['
|
|
638
|
+
stackRef['block_index'] = null;
|
|
639
|
+
this.scope.indentLevel -= 1;
|
|
624
640
|
|
|
625
|
-
|
|
626
|
-
const [preBranchComponent, preBranchPin, preBranchWireId] = stackRef['entered_at'];
|
|
641
|
+
this.print('exit inner block <<<');
|
|
627
642
|
|
|
628
|
-
|
|
643
|
+
if (blockType === BlockTypes.Branch) {
|
|
644
|
+
|
|
645
|
+
// Restore the latest entry in the branch stack
|
|
646
|
+
const { entered_at: [component, pin, wireId] } =
|
|
647
|
+
stackRef;
|
|
648
|
+
|
|
649
|
+
// Do not duplicate any net symbol since this is a branch
|
|
650
|
+
this.atComponent(component, pin, { addSequence: true });
|
|
651
|
+
|
|
652
|
+
if (wireId !== -1) {
|
|
653
|
+
// If previous node is a wire, then jump to END of wire
|
|
654
|
+
this.scope.sequence.push([SequenceAction.WireJump, wireId, 1]);
|
|
655
|
+
}
|
|
656
|
+
} else if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
|
|
657
|
+
if (blockIndex === 0) {
|
|
658
|
+
// First join block will determine the final join location
|
|
659
|
+
|
|
660
|
+
const pointIdName = (blockType === BlockTypes.Join) ? '_join' : '_parallel';
|
|
661
|
+
|
|
662
|
+
// Add point to current location, start with _join keyword to
|
|
663
|
+
// indicate that this is a point for join keyword
|
|
664
|
+
this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
|
|
665
|
+
this.tmpPointId += 1;
|
|
666
|
+
|
|
667
|
+
stackRef['final_point'] = [
|
|
668
|
+
this.scope.currentComponent,
|
|
669
|
+
this.scope.currentPin,
|
|
670
|
+
this.scope.currentWireId
|
|
671
|
+
];
|
|
672
|
+
|
|
673
|
+
} else {
|
|
674
|
+
const { final_point: finalPoint } = stackRef;
|
|
675
|
+
const [component, pin,] = finalPoint;
|
|
676
|
+
|
|
677
|
+
// Link the current component to the join component and join pin
|
|
678
|
+
this.toComponent(component, pin, { addSequence: true });
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
atPointBlock(): void {
|
|
684
|
+
const [component, pin,] = this.getPointBlockLocation();
|
|
685
|
+
this.atComponent(component, pin, {
|
|
686
|
+
addSequence: true
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
toPointBlock(): void {
|
|
691
|
+
// Point has been specifically created for block, wireId should be -1
|
|
692
|
+
const [component, pin,] = this.getPointBlockLocation();
|
|
693
|
+
this.toComponent(component, pin, {
|
|
694
|
+
addSequence: true
|
|
695
|
+
});
|
|
696
|
+
}
|
|
629
697
|
|
|
630
|
-
|
|
698
|
+
getPointBlockLocation(): [component: ClassComponent, pin: number, wireId: number] {
|
|
699
|
+
// Returns the position at the nearest `point:` block, searches within
|
|
700
|
+
// previous block stacks
|
|
701
|
+
this.print('get block point');
|
|
631
702
|
|
|
632
|
-
|
|
633
|
-
|
|
703
|
+
for (let i = 0; i < this.scope.indentLevel; i++) {
|
|
704
|
+
const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
|
|
705
|
+
const { entered_at } = stackRef;
|
|
706
|
+
const component: ClassComponent = entered_at[0];
|
|
634
707
|
|
|
635
|
-
|
|
636
|
-
|
|
708
|
+
if (component.instanceName.startsWith('_point.')) {
|
|
709
|
+
return entered_at;
|
|
710
|
+
}
|
|
637
711
|
}
|
|
712
|
+
|
|
713
|
+
this.print('did not find block point');
|
|
714
|
+
|
|
715
|
+
return null;
|
|
638
716
|
}
|
|
639
717
|
|
|
640
718
|
breakBranch(): void {
|
|
@@ -642,12 +720,12 @@ export class ExecutionContext {
|
|
|
642
720
|
// Mark that the branch stack at the current indent level
|
|
643
721
|
// should be ignored
|
|
644
722
|
|
|
645
|
-
const branchesInfo = this.scope.
|
|
723
|
+
const branchesInfo = this.scope.blockStack.get(
|
|
646
724
|
this.scope.indentLevel - 1,
|
|
647
725
|
);
|
|
648
|
-
const branchIndex = branchesInfo['
|
|
726
|
+
const branchIndex = branchesInfo['block_index'];
|
|
649
727
|
|
|
650
|
-
const branchIndexRef = branchesInfo['
|
|
728
|
+
const branchIndexRef = branchesInfo['inner_blocks'].get(branchIndex);
|
|
651
729
|
branchIndexRef['ignore_last_net'] = true;
|
|
652
730
|
}
|
|
653
731
|
|
|
@@ -748,7 +826,7 @@ export class ExecutionContext {
|
|
|
748
826
|
{ netNamespace });
|
|
749
827
|
|
|
750
828
|
this.print(`done call function '${functionName}'`);
|
|
751
|
-
|
|
829
|
+
|
|
752
830
|
return functionResult;
|
|
753
831
|
} else {
|
|
754
832
|
throw `Invalid function '${functionName}'`;
|
|
@@ -855,7 +933,7 @@ export class ExecutionContext {
|
|
|
855
933
|
// Wire IDs in wire jumps need to be updated.
|
|
856
934
|
const jumpWireId = wireIdOffset + sequenceAction[1];
|
|
857
935
|
this.scope.sequence.push(
|
|
858
|
-
[SequenceAction.WireJump, jumpWireId]
|
|
936
|
+
[SequenceAction.WireJump, jumpWireId, 1]
|
|
859
937
|
);
|
|
860
938
|
} else if (action === SequenceAction.At || action === SequenceAction.To) {
|
|
861
939
|
const tmpComponent: ClassComponent = sequenceAction[1];
|
|
@@ -895,9 +973,24 @@ export class ExecutionContext {
|
|
|
895
973
|
}
|
|
896
974
|
});
|
|
897
975
|
|
|
898
|
-
|
|
899
|
-
|
|
976
|
+
if (childScope.currentComponent === childScope.componentRoot) {
|
|
977
|
+
// If child scope is current at the root node, then use the
|
|
978
|
+
// location in the parent scope as the current component
|
|
979
|
+
// since that would be equivalent
|
|
980
|
+
this.scope.currentComponent = currentComponent;
|
|
981
|
+
this.scope.currentPin = currentPin;
|
|
982
|
+
this.scope.currentWireId = currentWireId;
|
|
900
983
|
|
|
984
|
+
} else {
|
|
985
|
+
// Otherwise move the current scope to the current node within
|
|
986
|
+
// the child scope
|
|
987
|
+
this.scope.currentComponent = childScope.currentComponent;
|
|
988
|
+
this.scope.currentPin = childScope.currentPin;
|
|
989
|
+
this.scope.currentWireId = childScope.currentWireId + wireIdOffset;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
this.printPoint('resume at');
|
|
993
|
+
|
|
901
994
|
this.print('-- nets --');
|
|
902
995
|
|
|
903
996
|
// dump the list of nets in the current scope
|
|
@@ -947,17 +1040,18 @@ export class ExecutionContext {
|
|
|
947
1040
|
)
|
|
948
1041
|
}
|
|
949
1042
|
|
|
950
|
-
addPoint(pointId: string): ComponentPin {
|
|
1043
|
+
addPoint(pointId: string, userDefined = true): ComponentPin {
|
|
951
1044
|
if (this.scope.instances.has(pointId)) {
|
|
952
1045
|
this.print('Warning: ' + pointId + ' is being redefined');
|
|
953
1046
|
}
|
|
954
1047
|
|
|
955
|
-
const
|
|
1048
|
+
const useName = userDefined ? 'point.' + pointId : pointId;
|
|
1049
|
+
const componentPoint = ClassComponent.simple(useName, 1, "point");
|
|
956
1050
|
componentPoint.displayProp = "point";
|
|
957
1051
|
componentPoint.typeProp = ComponentTypes.point;
|
|
958
1052
|
|
|
959
1053
|
this.scope.instances.set(pointId, componentPoint);
|
|
960
|
-
this.toComponent(componentPoint, 1, {addSequence: true});
|
|
1054
|
+
this.toComponent(componentPoint, 1, { addSequence: true });
|
|
961
1055
|
|
|
962
1056
|
return this.getCurrentPoint();
|
|
963
1057
|
}
|
package/src/export.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentTypes } from "./globals.js";
|
|
1
|
+
import { ComponentTypes, NoNetText } from "./globals.js";
|
|
2
2
|
import { NumericValue } from "./objects/ParamDefinition.js";
|
|
3
3
|
import { NetListItem } from "./visitor.js";
|
|
4
4
|
|
|
@@ -39,7 +39,7 @@ export function generateKiCADNetList(netlist: NetListItem[]): string {
|
|
|
39
39
|
const netInfo = pins[key];
|
|
40
40
|
const netName = netInfo.netName;
|
|
41
41
|
|
|
42
|
-
if (netName ===
|
|
42
|
+
if (netName === NoNetText){
|
|
43
43
|
continue;
|
|
44
44
|
}
|
|
45
45
|
|
package/src/globals.ts
CHANGED
|
@@ -9,6 +9,7 @@ export enum GlobalNames {
|
|
|
9
9
|
symbol = 'symbol',
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export const NoNetText = 'NO_NET';
|
|
12
13
|
|
|
13
14
|
export enum ParamKeys {
|
|
14
15
|
|
|
@@ -56,4 +57,11 @@ export enum ReferenceTypes {
|
|
|
56
57
|
value = 'value',
|
|
57
58
|
variable = 'variable',
|
|
58
59
|
instance = 'instance',
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export enum BlockTypes {
|
|
63
|
+
Branch = 1, // split off circuit paths, same starting insertion point
|
|
64
|
+
Join = 2, // join circuit paths, same ending insertion point
|
|
65
|
+
Parallel = 3, // same starting and ending points for the circuit paths
|
|
66
|
+
Point = 4, // to this point
|
|
59
67
|
}
|
package/src/layout.ts
CHANGED
|
@@ -121,12 +121,29 @@ export class LayoutEngine {
|
|
|
121
121
|
wireGroups.get(netName).push(wire);
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
const { junctions, mergedWires } = this.findJunctions(wireGroups);
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
components: placedComponents,
|
|
128
|
+
wires: placedWires,
|
|
129
|
+
mergedWires,
|
|
130
|
+
junctions,
|
|
131
|
+
|
|
132
|
+
frameObjects,
|
|
133
|
+
textObjects,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
findJunctions(wireGroups: Map<string, RenderWire[]>): {
|
|
138
|
+
junctions: RenderJunction[],
|
|
139
|
+
mergedWires: MergedWire[],
|
|
140
|
+
} {
|
|
124
141
|
const junctions: RenderJunction[] = [];
|
|
125
|
-
|
|
126
|
-
const mergedWires:MergedWire[] = [];
|
|
127
|
-
|
|
142
|
+
|
|
143
|
+
const mergedWires: MergedWire[] = [];
|
|
144
|
+
|
|
128
145
|
for (const [key, wires] of wireGroups) {
|
|
129
|
-
|
|
146
|
+
|
|
130
147
|
// Create array of all wires with the same net name
|
|
131
148
|
const allLines = wires.map(wire => {
|
|
132
149
|
return wire.points.map(pt => {
|
|
@@ -136,28 +153,23 @@ export class LayoutEngine {
|
|
|
136
153
|
}
|
|
137
154
|
});
|
|
138
155
|
});
|
|
139
|
-
|
|
156
|
+
|
|
140
157
|
const { intersectPoints, segments } = Geometry.mergeWires(allLines);
|
|
141
158
|
mergedWires.push({
|
|
142
159
|
netName: key,
|
|
143
160
|
segments,
|
|
144
161
|
intersectPoints,
|
|
145
162
|
});
|
|
146
|
-
|
|
163
|
+
|
|
147
164
|
intersectPoints.forEach(([x, y]) => {
|
|
148
165
|
junctions.push(new RenderJunction(x, y));
|
|
149
166
|
});
|
|
150
167
|
}
|
|
151
168
|
|
|
152
169
|
return {
|
|
153
|
-
components: placedComponents,
|
|
154
|
-
wires: placedWires,
|
|
155
|
-
mergedWires,
|
|
156
170
|
junctions,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
textObjects,
|
|
160
|
-
};
|
|
171
|
+
mergedWires
|
|
172
|
+
}
|
|
161
173
|
}
|
|
162
174
|
|
|
163
175
|
placeFrames(graph: graphlib.Graph, subgraphInfo: SubGraphInfo[],
|
|
@@ -635,7 +647,7 @@ export class LayoutEngine {
|
|
|
635
647
|
}
|
|
636
648
|
|
|
637
649
|
if (action === SequenceAction.To) {
|
|
638
|
-
|
|
650
|
+
this.setGraphEdge(graph, previousNode, tmpInstanceName,
|
|
639
651
|
makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, i));
|
|
640
652
|
}
|
|
641
653
|
|
|
@@ -649,9 +661,8 @@ export class LayoutEngine {
|
|
|
649
661
|
|
|
650
662
|
const wire = new RenderWire(0, 0, wireSegments);
|
|
651
663
|
wire.id = wireId;
|
|
652
|
-
|
|
653
664
|
let useNetName = null;
|
|
654
|
-
|
|
665
|
+
|
|
655
666
|
if (previousNode !== null) {
|
|
656
667
|
const [prevNodeType, prevNodeItem] = graph.node(previousNode);
|
|
657
668
|
if (prevNodeType === RenderItemType.Component) {
|
|
@@ -674,9 +685,9 @@ export class LayoutEngine {
|
|
|
674
685
|
graph.setNode(wireName, [RenderItemType.Wire, wire, i]);
|
|
675
686
|
|
|
676
687
|
// Connect previous node to pin:0 of the wire
|
|
677
|
-
|
|
688
|
+
this.setGraphEdge(graph, previousNode, wireName,
|
|
678
689
|
makeEdgeValue(previousNode, previousPin, wireName, 0, i));
|
|
679
|
-
|
|
690
|
+
|
|
680
691
|
previousNode = wireName;
|
|
681
692
|
previousPin = 1;
|
|
682
693
|
|
|
@@ -707,10 +718,17 @@ export class LayoutEngine {
|
|
|
707
718
|
|
|
708
719
|
} else if (action === SequenceAction.WireJump) {
|
|
709
720
|
this.print(...sequence[i]);
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
|
|
721
|
+
const wireId = sequence[i][1] as number;
|
|
722
|
+
const wireName = getWireName(wireId);
|
|
723
|
+
|
|
724
|
+
let wirePin = 1;
|
|
713
725
|
|
|
726
|
+
if (sequence[i].length === 3) {
|
|
727
|
+
wirePin = sequence[i][2] as number;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
previousNode = wireName;
|
|
731
|
+
previousPin = wirePin;
|
|
714
732
|
} else if (action === SequenceAction.Frame){
|
|
715
733
|
const [, frameObject, frameAction] = sequence[i];
|
|
716
734
|
|
|
@@ -754,6 +772,11 @@ export class LayoutEngine {
|
|
|
754
772
|
}
|
|
755
773
|
}
|
|
756
774
|
|
|
775
|
+
setGraphEdge(graph: graphlib.Graph, node1: string, node2: string,
|
|
776
|
+
edgeValue: EdgeValue): void {
|
|
777
|
+
graph.setEdge(node1, node2, edgeValue);
|
|
778
|
+
}
|
|
779
|
+
|
|
757
780
|
sizeSubGraphs(graph: graphlib.Graph): SubGraphInfo[] {
|
|
758
781
|
|
|
759
782
|
// Layouts out all nodes within a subgraph and determines the size
|
|
@@ -966,13 +989,11 @@ export class LayoutEngine {
|
|
|
966
989
|
const [x1, y1] = getNodePositionAtPin(node1, pin1);
|
|
967
990
|
const [x2, y2] = getNodePositionAtPin(node2, pin2);
|
|
968
991
|
if (x1 !== x2 && y1 !== y2) {
|
|
969
|
-
|
|
970
992
|
if (node1 instanceof RenderWire &&
|
|
971
993
|
node2 instanceof RenderComponent) {
|
|
972
994
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
' may not be placed correctly');
|
|
995
|
+
const refdes = node2.component.assignedRefDes;
|
|
996
|
+
this.layoutWarnings.push(`component ${refdes} may not be placed correctly`);
|
|
976
997
|
}
|
|
977
998
|
}
|
|
978
999
|
}
|
|
@@ -1189,10 +1210,10 @@ export class LayoutEngine {
|
|
|
1189
1210
|
item.y = fromY - pinPosition.y;
|
|
1190
1211
|
|
|
1191
1212
|
} else if (item instanceof RenderWire){
|
|
1192
|
-
if (pin === 0){
|
|
1213
|
+
if (pin === 0) { // Start of the wire
|
|
1193
1214
|
item.x = fromX;
|
|
1194
1215
|
item.y = fromY;
|
|
1195
|
-
} else {
|
|
1216
|
+
} else { // End of wire
|
|
1196
1217
|
const wireEnd = item.getWireEnd();
|
|
1197
1218
|
item.x = fromX - wireEnd.x;
|
|
1198
1219
|
item.y = fromY - wireEnd.y;
|
|
@@ -1281,8 +1302,12 @@ function getNeighbours(graph: graphlib.Graph, nodeIds: string[]): [from: string,
|
|
|
1281
1302
|
}, [] as [from: string, to: string][]);
|
|
1282
1303
|
}
|
|
1283
1304
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1305
|
+
type EdgeValue = [instance1: string, instancePin1: number,
|
|
1306
|
+
instance2: string, instancePin2: number, priority: number];
|
|
1307
|
+
|
|
1308
|
+
function makeEdgeValue(instanceName1: string, instancePin1: number,
|
|
1309
|
+
instanceName2: string, instancePin2: number, priority: number)
|
|
1310
|
+
: EdgeValue {
|
|
1286
1311
|
return [instanceName1, instancePin1, instanceName2, instancePin2, priority];
|
|
1287
1312
|
// return `${instanceName1}:pin:${instancePin1} -- ${instanceName2}:pin:${instancePin2}`;
|
|
1288
1313
|
}
|