circuitscript 0.0.24 → 0.0.25
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 +487 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +209 -195
- package/dist/cjs/antlr/CircuitScriptParser.js +2310 -2087
- package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
- package/dist/cjs/draw_symbols.js +67 -22
- package/dist/cjs/execute.js +51 -53
- package/dist/cjs/geometry.js +28 -8
- package/dist/cjs/helpers.js +175 -5
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/layout.js +8 -0
- package/dist/cjs/lexer.js +19 -22
- package/dist/cjs/main.js +6 -11
- package/dist/cjs/objects/ClassComponent.js +3 -0
- package/dist/cjs/objects/ExecutionScope.js +1 -0
- package/dist/cjs/objects/types.js +7 -1
- package/dist/cjs/parser.js +29 -258
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +529 -820
- package/dist/esm/BaseVisitor.mjs +488 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +184 -194
- package/dist/esm/antlr/CircuitScriptParser.mjs +2279 -2084
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +8 -3
- package/dist/esm/draw_symbols.mjs +67 -22
- package/dist/esm/execute.mjs +50 -52
- package/dist/esm/geometry.mjs +28 -8
- package/dist/esm/helpers.mjs +165 -6
- package/dist/esm/index.mjs +2 -0
- package/dist/esm/layout.mjs +8 -0
- package/dist/esm/lexer.mjs +10 -10
- package/dist/esm/main.mjs +7 -12
- package/dist/esm/objects/ClassComponent.mjs +3 -0
- package/dist/esm/objects/ExecutionScope.mjs +1 -0
- package/dist/esm/objects/types.mjs +6 -0
- package/dist/esm/parser.mjs +25 -230
- package/dist/esm/validate.mjs +74 -0
- package/dist/esm/visitor.mjs +343 -640
- package/dist/types/BaseVisitor.d.ts +69 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +8 -7
- package/dist/types/antlr/CircuitScriptParser.d.ts +513 -469
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +69 -59
- package/dist/types/draw_symbols.d.ts +9 -0
- package/dist/types/execute.d.ts +5 -8
- package/dist/types/geometry.d.ts +4 -0
- package/dist/types/helpers.d.ts +32 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lexer.d.ts +2 -2
- package/dist/types/objects/ExecutionScope.d.ts +4 -1
- package/dist/types/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +15 -28
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +40 -95
- package/fonts/Inter-Bold.ttf +0 -0
- package/fonts/Inter-Regular.ttf +0 -0
- package/fonts/OpenSans-Regular.ttf +0 -0
- package/fonts/Roboto-Regular.ttf +0 -0
- package/libs/lib.cst +183 -0
- package/package.json +11 -6
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
|
+
export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
|
|
3
3
|
visitScript;
|
|
4
4
|
visitExpression;
|
|
5
5
|
visitPath_blocks;
|
|
6
6
|
visitPath_block_inner;
|
|
7
7
|
visitProperty_set_expr2;
|
|
8
8
|
visitAssignment_expr2;
|
|
9
|
+
visitPin_select_expr;
|
|
10
|
+
visitComponent_modifier_expr;
|
|
9
11
|
visitData_expr_with_assignment;
|
|
10
12
|
visitAdd_component_expr;
|
|
11
13
|
visitComponent_select_expr;
|
|
12
|
-
visitPin_select_expr;
|
|
13
14
|
visitPin_select_expr2;
|
|
14
15
|
visitAt_component_expr;
|
|
15
16
|
visitTo_component_expr;
|
|
@@ -27,6 +28,7 @@ export default class CircuitScriptVisitor extends ParseTreeVisitor {
|
|
|
27
28
|
visitParameters;
|
|
28
29
|
visitProperty_set_expr;
|
|
29
30
|
visitDouble_dot_property_set_expr;
|
|
31
|
+
visitFunctionCallExpr;
|
|
30
32
|
visitAdditionExpr;
|
|
31
33
|
visitMultiplyExpr;
|
|
32
34
|
visitDataExpr;
|
|
@@ -42,6 +44,7 @@ export default class CircuitScriptVisitor extends ParseTreeVisitor {
|
|
|
42
44
|
visitFunction_args_expr;
|
|
43
45
|
visitAtom_expr;
|
|
44
46
|
visitTrailer_expr;
|
|
47
|
+
visitFunction_call_expr;
|
|
45
48
|
visitNet_namespace_expr;
|
|
46
49
|
visitFunction_return_expr;
|
|
47
50
|
visitCreate_component_expr;
|
|
@@ -52,6 +55,8 @@ export default class CircuitScriptVisitor extends ParseTreeVisitor {
|
|
|
52
55
|
visitNested_properties;
|
|
53
56
|
visitSingle_line_property;
|
|
54
57
|
visitBlank_expr;
|
|
58
|
+
visitWire_expr_direction_value;
|
|
59
|
+
visitWire_expr_direction_only;
|
|
55
60
|
visitWire_expr;
|
|
56
61
|
visitPoint_expr;
|
|
57
62
|
visitImport_expr;
|
|
@@ -6,6 +6,8 @@ export class SymbolGraphic {
|
|
|
6
6
|
displayBounds = true;
|
|
7
7
|
drawing;
|
|
8
8
|
_angle = 0;
|
|
9
|
+
_flipX = 0;
|
|
10
|
+
_flipY = 0;
|
|
9
11
|
width;
|
|
10
12
|
height;
|
|
11
13
|
labelTexts = new Map();
|
|
@@ -15,6 +17,18 @@ export class SymbolGraphic {
|
|
|
15
17
|
set angle(value) {
|
|
16
18
|
this._angle = value;
|
|
17
19
|
}
|
|
20
|
+
get flipX() {
|
|
21
|
+
return this._flipX;
|
|
22
|
+
}
|
|
23
|
+
set flipX(value) {
|
|
24
|
+
this._flipX = value;
|
|
25
|
+
}
|
|
26
|
+
get flipY() {
|
|
27
|
+
return this._flipY;
|
|
28
|
+
}
|
|
29
|
+
set flipY(value) {
|
|
30
|
+
this._flipY = value;
|
|
31
|
+
}
|
|
18
32
|
refreshDrawing(calculateSize = true) {
|
|
19
33
|
this.generateDrawing();
|
|
20
34
|
calculateSize && this.calculateSize();
|
|
@@ -40,10 +54,11 @@ export class SymbolGraphic {
|
|
|
40
54
|
drawPlaceRemove(group, extra) {
|
|
41
55
|
if (extra && extra.place === false) {
|
|
42
56
|
const { start, end } = this.drawing.getBoundingBox(true);
|
|
43
|
-
|
|
57
|
+
const path = Geometry.roundPathValues([
|
|
44
58
|
"M", start[0], start[1], "L", end[0], end[1],
|
|
45
59
|
"M", end[0], start[1], "L", start[0], end[1]
|
|
46
|
-
]
|
|
60
|
+
]);
|
|
61
|
+
group.path(path)
|
|
47
62
|
.stroke({
|
|
48
63
|
width: defaultSymbolLineWidth,
|
|
49
64
|
color: 'red'
|
|
@@ -110,27 +125,33 @@ export class SymbolGraphic {
|
|
|
110
125
|
}
|
|
111
126
|
switch (useAnchor) {
|
|
112
127
|
case HorizontalAlign.Left:
|
|
113
|
-
anchorStyle = 'start';
|
|
128
|
+
anchorStyle = (this.flipX === 0) ? 'start' : 'end';
|
|
114
129
|
break;
|
|
115
130
|
case HorizontalAlign.Middle:
|
|
116
131
|
anchorStyle = 'middle';
|
|
117
132
|
break;
|
|
118
133
|
case HorizontalAlign.Right:
|
|
119
|
-
anchorStyle = 'end';
|
|
134
|
+
anchorStyle = (this.flipX === 0) ? 'end' : 'start';
|
|
120
135
|
break;
|
|
121
136
|
}
|
|
122
137
|
switch (useDominantBaseline) {
|
|
123
138
|
case VerticalAlign.Top:
|
|
124
|
-
dominantBaseline = 'hanging';
|
|
139
|
+
dominantBaseline = (this.flipY === 0) ? 'hanging' : 'text-top';
|
|
125
140
|
break;
|
|
126
141
|
case VerticalAlign.Middle:
|
|
127
142
|
dominantBaseline = 'middle';
|
|
128
143
|
break;
|
|
129
144
|
case VerticalAlign.Bottom:
|
|
130
|
-
dominantBaseline = 'text-top';
|
|
145
|
+
dominantBaseline = (this.flipY === 0) ? 'text-top' : 'hanging';
|
|
131
146
|
break;
|
|
132
147
|
}
|
|
133
148
|
const position = tmpLabel.getLabelPosition();
|
|
149
|
+
if (this.flipX !== 0) {
|
|
150
|
+
position[0] *= -1;
|
|
151
|
+
}
|
|
152
|
+
if (this.flipY !== 0) {
|
|
153
|
+
position[1] *= -1;
|
|
154
|
+
}
|
|
134
155
|
const useFont = defaultFont;
|
|
135
156
|
const textContainer = group.group();
|
|
136
157
|
const text = textContainer.text(tmpLabel.text)
|
|
@@ -154,11 +175,26 @@ export class SymbolGraphic {
|
|
|
154
175
|
translateY = position[1];
|
|
155
176
|
useRotateAngle = this.angle;
|
|
156
177
|
}
|
|
178
|
+
translateX = this.roundValues(translateX);
|
|
179
|
+
translateY = this.roundValues(translateY);
|
|
157
180
|
text.rotate(labelAngle);
|
|
158
181
|
textContainer.translate(translateX, translateY)
|
|
159
182
|
.rotate(useRotateAngle, -translateX, -translateY);
|
|
183
|
+
const { a, b, c, d, e, f } = textContainer.matrix();
|
|
184
|
+
const newMatrix = {
|
|
185
|
+
a: this.roundValues(a),
|
|
186
|
+
b: this.roundValues(b),
|
|
187
|
+
c: this.roundValues(c),
|
|
188
|
+
d: this.roundValues(d),
|
|
189
|
+
e: this.roundValues(e),
|
|
190
|
+
f: this.roundValues(f),
|
|
191
|
+
};
|
|
192
|
+
textContainer.transform(newMatrix);
|
|
160
193
|
});
|
|
161
194
|
}
|
|
195
|
+
roundValues(value) {
|
|
196
|
+
return +value.toFixed(7);
|
|
197
|
+
}
|
|
162
198
|
flipTextAnchor(value) {
|
|
163
199
|
if (value === HorizontalAlign.Left) {
|
|
164
200
|
return HorizontalAlign.Right;
|
|
@@ -229,6 +265,8 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
229
265
|
drawing.log("=== start generate drawing ===");
|
|
230
266
|
drawing.clear();
|
|
231
267
|
drawing.angle = this._angle;
|
|
268
|
+
drawing.flipX = this._flipX;
|
|
269
|
+
drawing.flipY = this._flipY;
|
|
232
270
|
const commands = drawing.getCommands();
|
|
233
271
|
drawing.log('id: ', drawing.id, 'angle: ', this._angle, "commands:", commands.length);
|
|
234
272
|
commands.forEach(([commandName, positionParams, keywordParams]) => {
|
|
@@ -305,10 +343,9 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
305
343
|
drawing.log('add pin', ...positionParams);
|
|
306
344
|
const keywordDisplayPinId = 'display_pin_id';
|
|
307
345
|
let displayPinId = true;
|
|
308
|
-
if (keywordParams.has(keywordDisplayPinId)
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
346
|
+
if (keywordParams.has(keywordDisplayPinId)
|
|
347
|
+
&& keywordParams.get(keywordDisplayPinId) === 0) {
|
|
348
|
+
displayPinId = false;
|
|
312
349
|
}
|
|
313
350
|
let pinNameParam = null;
|
|
314
351
|
if (typeof positionParams[1] === 'string') {
|
|
@@ -338,8 +375,8 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
338
375
|
];
|
|
339
376
|
}
|
|
340
377
|
drawing.addPin(...positionParams);
|
|
341
|
-
const
|
|
342
|
-
const [pinId, , angle] =
|
|
378
|
+
const lastAddedPin = this.drawing.pins[this.drawing.pins.length - 1];
|
|
379
|
+
const [pinId, , angle] = lastAddedPin;
|
|
343
380
|
const [, , , endX, endY] = positionParams;
|
|
344
381
|
let pinNameAlignment = HorizontalAlign.Left;
|
|
345
382
|
let pinNameOffsetX = 4;
|
|
@@ -433,6 +470,8 @@ export class SymbolCustom extends SymbolGraphic {
|
|
|
433
470
|
const maxRightPins = Math.max(...rightPins.map(item => item.position)) + 1;
|
|
434
471
|
const drawing = new SymbolDrawing();
|
|
435
472
|
drawing.angle = this._angle;
|
|
473
|
+
drawing.flipX = this._flipX;
|
|
474
|
+
drawing.flipY = this._flipY;
|
|
436
475
|
const bodyWidth = this.bodyWidth;
|
|
437
476
|
const bodyHeight = (1 + Math.max(maxLeftPins, maxRightPins)) * this.pinSpacing;
|
|
438
477
|
drawing.addRect(0, 0, bodyWidth, bodyHeight);
|
|
@@ -498,6 +537,8 @@ export class SymbolDrawing {
|
|
|
498
537
|
items = [];
|
|
499
538
|
pins = [];
|
|
500
539
|
angle = 0;
|
|
540
|
+
flipX = 0;
|
|
541
|
+
flipY = 0;
|
|
501
542
|
mainOrigin = [0, 0];
|
|
502
543
|
logger = null;
|
|
503
544
|
clear() {
|
|
@@ -676,8 +717,9 @@ export class SymbolDrawing {
|
|
|
676
717
|
}
|
|
677
718
|
}
|
|
678
719
|
else {
|
|
679
|
-
|
|
680
|
-
|
|
720
|
+
let tmpResult = Geometry.groupFlip([item], this.flipX, this.flipY);
|
|
721
|
+
tmpResult = Geometry.groupRotate(tmpResult, this.angle, this.mainOrigin);
|
|
722
|
+
const { path, isClosedPolygon } = this.featuresToPath(tmpResult);
|
|
681
723
|
pathItems.push({
|
|
682
724
|
path: path,
|
|
683
725
|
lineWidth: currentLineWidth,
|
|
@@ -690,9 +732,10 @@ export class SymbolDrawing {
|
|
|
690
732
|
return pathItems;
|
|
691
733
|
}
|
|
692
734
|
getPinsPath() {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
735
|
+
let features = this.pins.map(item => item[1]);
|
|
736
|
+
features = Geometry.groupFlip(features, this.flipX, this.flipY);
|
|
737
|
+
features = Geometry.groupRotate(features, this.angle, this.mainOrigin);
|
|
738
|
+
const { path } = this.featuresToPath(features);
|
|
696
739
|
return path;
|
|
697
740
|
}
|
|
698
741
|
getLabels() {
|
|
@@ -713,9 +756,10 @@ export class SymbolDrawing {
|
|
|
713
756
|
}
|
|
714
757
|
return accum;
|
|
715
758
|
}, []);
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
759
|
+
let features = [...drawingFeatures, ...pinFeatures];
|
|
760
|
+
features = Geometry.groupFlip(features, this.flipX, this.flipY);
|
|
761
|
+
features = Geometry.groupRotate(features, this.angle, this.mainOrigin);
|
|
762
|
+
return Geometry.groupBounds(features);
|
|
719
763
|
}
|
|
720
764
|
getPinPosition(pinId) {
|
|
721
765
|
const pin = this.pins.find(item => {
|
|
@@ -723,8 +767,9 @@ export class SymbolDrawing {
|
|
|
723
767
|
});
|
|
724
768
|
if (pin) {
|
|
725
769
|
const [, feature, angle] = pin;
|
|
726
|
-
|
|
727
|
-
|
|
770
|
+
let tmpFeature = Geometry.flip(feature, this.flipX, this.flipY);
|
|
771
|
+
tmpFeature = Geometry.rotateDegs(tmpFeature, this.angle, this.mainOrigin);
|
|
772
|
+
const coords = Geometry.getCoords(tmpFeature);
|
|
728
773
|
return {
|
|
729
774
|
start: coords[0],
|
|
730
775
|
end: coords[1],
|
package/dist/esm/execute.mjs
CHANGED
|
@@ -18,7 +18,8 @@ export class ExecutionContext {
|
|
|
18
18
|
silent = false;
|
|
19
19
|
logger;
|
|
20
20
|
__functionCache = {};
|
|
21
|
-
|
|
21
|
+
parentContext;
|
|
22
|
+
constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, parent) {
|
|
22
23
|
this.name = name;
|
|
23
24
|
this.namespace = namespace;
|
|
24
25
|
this.netNamespace = netNamespace;
|
|
@@ -27,10 +28,18 @@ export class ExecutionContext {
|
|
|
27
28
|
this.scope = ExecutionScope.create();
|
|
28
29
|
this.scope.indentLevel = indentLevel;
|
|
29
30
|
this.setupRoot();
|
|
31
|
+
if (name === '__') {
|
|
32
|
+
this.scope.sequence.push([
|
|
33
|
+
SequenceAction.At,
|
|
34
|
+
this.scope.componentRoot,
|
|
35
|
+
this.scope.currentPin
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
30
38
|
this.silent = silent;
|
|
31
|
-
this.
|
|
39
|
+
this.log('create new execution context', this.namespace, this.name, this.scope.indentLevel);
|
|
40
|
+
this.parentContext = parent;
|
|
32
41
|
}
|
|
33
|
-
|
|
42
|
+
log(...params) {
|
|
34
43
|
const indentOutput = ''.padStart(this.scope.indentLevel * 4, ' ');
|
|
35
44
|
const indentLevelText = this.scope.indentLevel
|
|
36
45
|
.toString()
|
|
@@ -44,18 +53,13 @@ export class ExecutionContext {
|
|
|
44
53
|
}
|
|
45
54
|
setupRoot() {
|
|
46
55
|
const componentRoot = ClassComponent.simple(GlobalNames.__root, 1, '__root');
|
|
47
|
-
componentRoot.typeProp = ComponentTypes.
|
|
56
|
+
componentRoot.typeProp = ComponentTypes.point;
|
|
57
|
+
componentRoot.displayProp = 'point';
|
|
48
58
|
this.scope.instances.set(GlobalNames.__root, componentRoot);
|
|
49
59
|
this.scope.currentComponent = componentRoot;
|
|
50
60
|
this.scope.currentPin = componentRoot.getDefaultPin();
|
|
51
61
|
this.scope.componentRoot = componentRoot;
|
|
52
62
|
}
|
|
53
|
-
instanceExists(instanceName) {
|
|
54
|
-
return this.scope.instances.has(instanceName);
|
|
55
|
-
}
|
|
56
|
-
getComponent(instanceName) {
|
|
57
|
-
return this.scope.instances.get(instanceName);
|
|
58
|
-
}
|
|
59
63
|
getUniqueInstanceName(className) {
|
|
60
64
|
let extraPrefix = '';
|
|
61
65
|
switch (className) {
|
|
@@ -90,7 +94,7 @@ export class ExecutionContext {
|
|
|
90
94
|
const net2 = net2_exists
|
|
91
95
|
? this.scope.getNet(component2, component2Pin)
|
|
92
96
|
: null;
|
|
93
|
-
this.
|
|
97
|
+
this.log('link nets', component1, component1Pin, net1, 'to', component2, component2Pin, net2);
|
|
94
98
|
let returnNet;
|
|
95
99
|
if (net1 === null && net2 === null) {
|
|
96
100
|
const tmpNet = new Net(this.netNamespace, this.getUniqueNetName());
|
|
@@ -152,14 +156,14 @@ export class ExecutionContext {
|
|
|
152
156
|
let tmpNet;
|
|
153
157
|
if (result.found) {
|
|
154
158
|
tmpNet = result.net;
|
|
155
|
-
this.
|
|
159
|
+
this.log('net found', tmpNet.namespace, tmpNet.name);
|
|
156
160
|
}
|
|
157
161
|
else {
|
|
158
162
|
tmpNet = new Net(this.netNamespace, netName, priority);
|
|
159
|
-
this.
|
|
163
|
+
this.log('net not found, added net instance', tmpNet.namespace, tmpNet.name);
|
|
160
164
|
}
|
|
161
165
|
this.scope.setNet(component, 1, tmpNet);
|
|
162
|
-
this.
|
|
166
|
+
this.log('set net', netName, 'component', component);
|
|
163
167
|
}
|
|
164
168
|
const { arrange = null } = props;
|
|
165
169
|
component.arrangeProps = arrange;
|
|
@@ -178,7 +182,7 @@ export class ExecutionContext {
|
|
|
178
182
|
const pinsOutput = pins.map((pin) => {
|
|
179
183
|
return pin.id + ':' + pin.name;
|
|
180
184
|
});
|
|
181
|
-
this.
|
|
185
|
+
this.log('add symbol', instanceName, '[' + pinsOutput.join(', ') + ']');
|
|
182
186
|
return component;
|
|
183
187
|
}
|
|
184
188
|
printPoint(extra = '') {
|
|
@@ -188,7 +192,7 @@ export class ExecutionContext {
|
|
|
188
192
|
.getNet(this.scope.currentComponent, this.scope.currentPin)
|
|
189
193
|
.toString();
|
|
190
194
|
}
|
|
191
|
-
this.
|
|
195
|
+
this.log((extra !== '' ? (extra + ' ') : '') + 'point: ' +
|
|
192
196
|
this.scope.currentComponent.instanceName +
|
|
193
197
|
' ' +
|
|
194
198
|
this.scope.currentPin + ' ' + netName);
|
|
@@ -197,7 +201,7 @@ export class ExecutionContext {
|
|
|
197
201
|
const startPin = pin;
|
|
198
202
|
const nextPin = component.getNextPinAfter(startPin);
|
|
199
203
|
this.toComponent(component, startPin, { addSequence: true });
|
|
200
|
-
this.
|
|
204
|
+
this.log('move to next pin: ' + nextPin);
|
|
201
205
|
this.atComponent(component, nextPin, {
|
|
202
206
|
addSequence: true
|
|
203
207
|
});
|
|
@@ -205,11 +209,8 @@ export class ExecutionContext {
|
|
|
205
209
|
return this.getCurrentPoint();
|
|
206
210
|
}
|
|
207
211
|
toComponent(component, pinId, options) {
|
|
208
|
-
this.
|
|
209
|
-
const { addSequence = false
|
|
210
|
-
if (cloneNetComponent && this.isNetOnlyComponent(component)) {
|
|
211
|
-
component = this.cloneComponent(component);
|
|
212
|
-
}
|
|
212
|
+
this.log('to component');
|
|
213
|
+
const { addSequence = false } = options ?? {};
|
|
213
214
|
if (!(component instanceof ClassComponent)) {
|
|
214
215
|
throw "Not a valid component!";
|
|
215
216
|
}
|
|
@@ -229,7 +230,7 @@ export class ExecutionContext {
|
|
|
229
230
|
}
|
|
230
231
|
}
|
|
231
232
|
if (this.scope.hasNet(this.scope.currentComponent, this.scope.currentPin)) {
|
|
232
|
-
this.
|
|
233
|
+
this.log('net: ', this.scope
|
|
233
234
|
.getNet(this.scope.currentComponent, this.scope.currentPin)
|
|
234
235
|
.toString());
|
|
235
236
|
}
|
|
@@ -256,11 +257,8 @@ export class ExecutionContext {
|
|
|
256
257
|
return this.getCurrentPoint();
|
|
257
258
|
}
|
|
258
259
|
atComponent(component, pinId, options) {
|
|
259
|
-
this.
|
|
260
|
-
const { addSequence = false
|
|
261
|
-
if (cloneNetComponent && this.isNetOnlyComponent(component)) {
|
|
262
|
-
component = this.cloneComponent(component);
|
|
263
|
-
}
|
|
260
|
+
this.log('at component');
|
|
261
|
+
const { addSequence = false } = options ?? {};
|
|
264
262
|
this.scope.currentComponent = component;
|
|
265
263
|
let usePinId;
|
|
266
264
|
if (pinId === null) {
|
|
@@ -285,9 +283,6 @@ export class ExecutionContext {
|
|
|
285
283
|
this.printPoint();
|
|
286
284
|
return this.getCurrentPoint();
|
|
287
285
|
}
|
|
288
|
-
isNetOnlyComponent(component) {
|
|
289
|
-
return isNetComponent(component) && !isLabelComponent(component);
|
|
290
|
-
}
|
|
291
286
|
cloneComponent(component) {
|
|
292
287
|
let clonedComponent = null;
|
|
293
288
|
if (!this.scope.copyIDs.has(component.instanceName)) {
|
|
@@ -302,7 +297,7 @@ export class ExecutionContext {
|
|
|
302
297
|
this.scope.instances.set(cloneInstanceName, clonedComponent);
|
|
303
298
|
clonedComponent.instanceName = cloneInstanceName;
|
|
304
299
|
this.linkComponentPinNet(component, 1, clonedComponent, 1);
|
|
305
|
-
this.
|
|
300
|
+
this.log('created clone of net component:', cloneInstanceName);
|
|
306
301
|
return clonedComponent;
|
|
307
302
|
}
|
|
308
303
|
enterBlocks(blockType) {
|
|
@@ -324,7 +319,7 @@ export class ExecutionContext {
|
|
|
324
319
|
current_index: null,
|
|
325
320
|
type: blockType,
|
|
326
321
|
});
|
|
327
|
-
this.
|
|
322
|
+
this.log('enter blocks');
|
|
328
323
|
}
|
|
329
324
|
exitBlocks() {
|
|
330
325
|
const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
|
|
@@ -345,7 +340,7 @@ export class ExecutionContext {
|
|
|
345
340
|
const { entered_at: [component, pin,] } = stackRef;
|
|
346
341
|
this.atComponent(component, pin, { addSequence: true });
|
|
347
342
|
}
|
|
348
|
-
this.
|
|
343
|
+
this.log('exit blocks');
|
|
349
344
|
}
|
|
350
345
|
enterBlock(blockIndex) {
|
|
351
346
|
const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
|
|
@@ -364,7 +359,7 @@ export class ExecutionContext {
|
|
|
364
359
|
const { entered_at: [component, pin,] } = stackRef;
|
|
365
360
|
this.atComponent(component, pin, { addSequence: true });
|
|
366
361
|
}
|
|
367
|
-
this.
|
|
362
|
+
this.log(`enter inner block of type (${blockType}) >>>`);
|
|
368
363
|
this.scope.indentLevel += 1;
|
|
369
364
|
}
|
|
370
365
|
exitBlock(blockIndex) {
|
|
@@ -378,7 +373,7 @@ export class ExecutionContext {
|
|
|
378
373
|
];
|
|
379
374
|
stackRef['block_index'] = null;
|
|
380
375
|
this.scope.indentLevel -= 1;
|
|
381
|
-
this.
|
|
376
|
+
this.log('exit inner block <<<');
|
|
382
377
|
if (blockType === BlockTypes.Branch) {
|
|
383
378
|
const { entered_at: [component, pin, wireId] } = stackRef;
|
|
384
379
|
this.atComponent(component, pin, { addSequence: true });
|
|
@@ -417,7 +412,7 @@ export class ExecutionContext {
|
|
|
417
412
|
});
|
|
418
413
|
}
|
|
419
414
|
getPointBlockLocation() {
|
|
420
|
-
this.
|
|
415
|
+
this.log('get block point');
|
|
421
416
|
for (let i = 0; i < this.scope.indentLevel; i++) {
|
|
422
417
|
const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
|
|
423
418
|
const { entered_at } = stackRef;
|
|
@@ -426,11 +421,11 @@ export class ExecutionContext {
|
|
|
426
421
|
return entered_at;
|
|
427
422
|
}
|
|
428
423
|
}
|
|
429
|
-
this.
|
|
424
|
+
this.log('did not find block point');
|
|
430
425
|
return null;
|
|
431
426
|
}
|
|
432
427
|
breakBranch() {
|
|
433
|
-
this.
|
|
428
|
+
this.log('break branch');
|
|
434
429
|
const branchesInfo = this.scope.blockStack.get(this.scope.indentLevel - 1);
|
|
435
430
|
const branchIndex = branchesInfo['block_index'];
|
|
436
431
|
const branchIndexRef = branchesInfo['inner_blocks'].get(branchIndex);
|
|
@@ -439,7 +434,7 @@ export class ExecutionContext {
|
|
|
439
434
|
createFunction(functionName, __runFunc) {
|
|
440
435
|
this.scope.functions.set(functionName, __runFunc);
|
|
441
436
|
this.__functionCache[functionName] = __runFunc;
|
|
442
|
-
this.
|
|
437
|
+
this.log(`defined new function '${functionName}'`);
|
|
443
438
|
}
|
|
444
439
|
hasFunction(functionName) {
|
|
445
440
|
return this.scope.functions.has(functionName);
|
|
@@ -488,7 +483,7 @@ export class ExecutionContext {
|
|
|
488
483
|
__runFunc = this.getFunction(functionName);
|
|
489
484
|
}
|
|
490
485
|
if (__runFunc === null) {
|
|
491
|
-
this.
|
|
486
|
+
this.log(`searching for function ${functionName} in upper context`);
|
|
492
487
|
const tmpResolveResult = this.resolveVariable(executionStack, functionName);
|
|
493
488
|
if (tmpResolveResult.found) {
|
|
494
489
|
__runFunc = tmpResolveResult.value;
|
|
@@ -497,17 +492,17 @@ export class ExecutionContext {
|
|
|
497
492
|
throw `Invalid function ${functionName}`;
|
|
498
493
|
}
|
|
499
494
|
}
|
|
500
|
-
this.
|
|
495
|
+
this.log('save function to cache:', functionName);
|
|
501
496
|
this.__functionCache[functionName] = __runFunc;
|
|
502
497
|
}
|
|
503
498
|
else {
|
|
504
|
-
this.
|
|
499
|
+
this.log('found function in cache:', functionName);
|
|
505
500
|
__runFunc = this.__functionCache[functionName];
|
|
506
501
|
}
|
|
507
502
|
if (__runFunc !== null) {
|
|
508
|
-
this.
|
|
503
|
+
this.log(`call function '${functionName}'`);
|
|
509
504
|
const functionResult = __runFunc(functionParams, { netNamespace });
|
|
510
|
-
this.
|
|
505
|
+
this.log(`done call function '${functionName}'`);
|
|
511
506
|
return functionResult;
|
|
512
507
|
}
|
|
513
508
|
else {
|
|
@@ -515,7 +510,7 @@ export class ExecutionContext {
|
|
|
515
510
|
}
|
|
516
511
|
}
|
|
517
512
|
mergeScope(childScope, namespace) {
|
|
518
|
-
this.
|
|
513
|
+
this.log('-- merging scope to parent --');
|
|
519
514
|
const currentComponent = this.scope.currentComponent;
|
|
520
515
|
const currentPin = this.scope.currentPin;
|
|
521
516
|
const currentWireId = this.scope.currentWireId;
|
|
@@ -605,16 +600,16 @@ export class ExecutionContext {
|
|
|
605
600
|
this.scope.currentWireId = childScope.currentWireId + wireIdOffset;
|
|
606
601
|
}
|
|
607
602
|
this.printPoint('resume at');
|
|
608
|
-
this.
|
|
603
|
+
this.log('-- nets --');
|
|
609
604
|
const currentNets = this.scope.getNets();
|
|
610
605
|
currentNets.reduce((accum, [, , net]) => {
|
|
611
606
|
if (accum.indexOf(net) === -1) {
|
|
612
607
|
accum.push(net);
|
|
613
|
-
this.
|
|
608
|
+
this.log(`${net.namespace}${net.name} ${net.priority}`);
|
|
614
609
|
}
|
|
615
610
|
return accum;
|
|
616
611
|
}, []);
|
|
617
|
-
this.
|
|
612
|
+
this.log('-- done merging scope --');
|
|
618
613
|
}
|
|
619
614
|
addWire(segments) {
|
|
620
615
|
if (this.scope.currentComponent === null) {
|
|
@@ -633,14 +628,14 @@ export class ExecutionContext {
|
|
|
633
628
|
segments.forEach(item => {
|
|
634
629
|
output.push(item.join(","));
|
|
635
630
|
});
|
|
636
|
-
this.
|
|
631
|
+
this.log('add wire: ', output.join("|"));
|
|
637
632
|
this.scope.setActive(ActiveObject.Wire, wireId);
|
|
638
633
|
this.scope.sequence.push([SequenceAction.Wire, wireId, tmp]);
|
|
639
634
|
this.scope.currentComponent.pinWires.set(this.scope.currentPin, tmp);
|
|
640
635
|
}
|
|
641
636
|
addPoint(pointId, userDefined = true) {
|
|
642
637
|
if (this.scope.instances.has(pointId)) {
|
|
643
|
-
this.
|
|
638
|
+
this.log('Warning: ' + pointId + ' is being redefined');
|
|
644
639
|
}
|
|
645
640
|
const useName = userDefined ? 'point.' + pointId : pointId;
|
|
646
641
|
const componentPoint = ClassComponent.simple(useName, 1, "point");
|
|
@@ -651,7 +646,7 @@ export class ExecutionContext {
|
|
|
651
646
|
return this.getCurrentPoint();
|
|
652
647
|
}
|
|
653
648
|
setProperty(nameWithProp, value) {
|
|
654
|
-
this.
|
|
649
|
+
this.log('set property', nameWithProp, 'value', value);
|
|
655
650
|
let idName;
|
|
656
651
|
let paramName;
|
|
657
652
|
let useActive = false;
|
|
@@ -717,6 +712,9 @@ export function isNetComponent(component) {
|
|
|
717
712
|
export function isLabelComponent(component) {
|
|
718
713
|
return component.parameters.has(ParamKeys.__is_label);
|
|
719
714
|
}
|
|
715
|
+
export function isNetOnlyComponent(component) {
|
|
716
|
+
return isNetComponent(component) && !isLabelComponent(component);
|
|
717
|
+
}
|
|
720
718
|
export function getPortSide(pins, arrangeProps) {
|
|
721
719
|
const result = [];
|
|
722
720
|
if (arrangeProps === null) {
|
package/dist/esm/geometry.mjs
CHANGED
|
@@ -52,8 +52,12 @@ export class Label extends Flatten.Polygon {
|
|
|
52
52
|
return new Label(id, useText, [x, y], polygon, style, box);
|
|
53
53
|
}
|
|
54
54
|
rotate(angle, origin) {
|
|
55
|
-
const
|
|
56
|
-
return new Label(this.id, this.text, this.anchorPoint,
|
|
55
|
+
const feature = super.rotate(angle, origin);
|
|
56
|
+
return new Label(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds);
|
|
57
|
+
}
|
|
58
|
+
transform(matrix) {
|
|
59
|
+
const feature = super.transform(matrix);
|
|
60
|
+
return new Label(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds);
|
|
57
61
|
}
|
|
58
62
|
getLabelPosition() {
|
|
59
63
|
return this.anchorPoint;
|
|
@@ -103,6 +107,10 @@ export class Geometry {
|
|
|
103
107
|
const angleRads = angleDegrees * Math.PI / 180;
|
|
104
108
|
return feature.rotate(angleRads, Geometry.point(center[0], center[1]));
|
|
105
109
|
}
|
|
110
|
+
static flip(feature, flipX, flipY) {
|
|
111
|
+
const flipMatrix = (new Flatten.Matrix()).scale(flipX === 0 ? 1 : -1, flipY == 0 ? 1 : -1);
|
|
112
|
+
return feature.transform(flipMatrix);
|
|
113
|
+
}
|
|
106
114
|
static groupRotate(features, angle, center) {
|
|
107
115
|
const angleRads = angle * Math.PI / 180;
|
|
108
116
|
const rotateAboutPoint = Geometry.point(center[0], center[1]);
|
|
@@ -110,6 +118,12 @@ export class Geometry {
|
|
|
110
118
|
return feature.rotate(angleRads, rotateAboutPoint);
|
|
111
119
|
});
|
|
112
120
|
}
|
|
121
|
+
static groupFlip(features, flipX, flipY) {
|
|
122
|
+
const flipMatrix = (new Flatten.Matrix()).scale(flipX === 0 ? 1 : -1, flipY == 0 ? 1 : -1);
|
|
123
|
+
return features.map(feature => {
|
|
124
|
+
return feature.transform(flipMatrix);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
113
127
|
static groupBounds(features) {
|
|
114
128
|
let minX = Number.POSITIVE_INFINITY;
|
|
115
129
|
let minY = Number.POSITIVE_INFINITY;
|
|
@@ -171,9 +185,7 @@ export class Geometry {
|
|
|
171
185
|
}
|
|
172
186
|
const startPoint = getArcPointRadians(x, y, radius, item.startAngle);
|
|
173
187
|
const endPoint = getArcPointRadians(x, y, radius, useEndAngle);
|
|
174
|
-
paths.push('M
|
|
175
|
-
+ 'A ' + radius + ' ' + radius + ' 0 1 1 '
|
|
176
|
-
+ endPoint[0] + ' ' + endPoint[1] + extraEnd);
|
|
188
|
+
paths.push('M', startPoint[0], startPoint[1], 'A', radius, radius, 0, 1, 1, endPoint[0], endPoint[1], extraEnd);
|
|
177
189
|
}
|
|
178
190
|
else {
|
|
179
191
|
const coords = Geometry.getCoords(item);
|
|
@@ -183,19 +195,27 @@ export class Geometry {
|
|
|
183
195
|
for (let i = 0; i < coords.length; i++) {
|
|
184
196
|
const [x, y] = coords[i];
|
|
185
197
|
const command = (i === 0) ? 'M' : 'L';
|
|
186
|
-
path.push(`${command}
|
|
198
|
+
path.push(`${command}`, x, y);
|
|
187
199
|
}
|
|
188
200
|
if (isClosedPolygon) {
|
|
189
201
|
path.push('Z');
|
|
190
202
|
}
|
|
191
|
-
paths.push(path
|
|
203
|
+
paths.push(...path);
|
|
192
204
|
}
|
|
193
205
|
});
|
|
194
206
|
return {
|
|
195
|
-
path:
|
|
207
|
+
path: this.roundPathValues(paths),
|
|
196
208
|
isClosedPolygon,
|
|
197
209
|
};
|
|
198
210
|
}
|
|
211
|
+
static roundPathValues(pathItems) {
|
|
212
|
+
return pathItems.map(item => {
|
|
213
|
+
if (typeof item === 'number') {
|
|
214
|
+
return (+item.toFixed(7)).toString();
|
|
215
|
+
}
|
|
216
|
+
return item;
|
|
217
|
+
}).join(" ");
|
|
218
|
+
}
|
|
199
219
|
static angle(dx, dy) {
|
|
200
220
|
const line = new Flatten.Segment(new Flatten.Point(0, 0), new Flatten.Point(dx, dy));
|
|
201
221
|
return line.slope * 180 / Math.PI;
|