circuitscript 0.0.22 → 0.0.24

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.
Files changed (164) hide show
  1. package/dist/cjs/antlr/CircuitScriptLexer.js +288 -0
  2. package/dist/cjs/antlr/CircuitScriptParser.js +4905 -0
  3. package/dist/cjs/antlr/CircuitScriptVisitor.js +6 -0
  4. package/{src/draw_symbols.ts → dist/cjs/draw_symbols.js} +303 -614
  5. package/dist/cjs/execute.js +780 -0
  6. package/{src/export.ts → dist/cjs/export.js} +34 -56
  7. package/dist/cjs/fonts.js +4 -0
  8. package/dist/cjs/geometry.js +430 -0
  9. package/dist/cjs/globals.js +60 -0
  10. package/dist/cjs/helpers.js +99 -0
  11. package/dist/cjs/index.js +29 -0
  12. package/{src/layout.ts → dist/cjs/layout.js} +413 -1002
  13. package/dist/cjs/lexer.js +114 -0
  14. package/dist/cjs/logger.js +17 -0
  15. package/dist/cjs/main.js +87 -0
  16. package/dist/cjs/objects/ClassComponent.js +142 -0
  17. package/dist/cjs/objects/ExecutionScope.js +134 -0
  18. package/dist/cjs/objects/Frame.js +22 -0
  19. package/{src/objects/Net.ts → dist/cjs/objects/Net.js} +9 -24
  20. package/dist/cjs/objects/ParamDefinition.js +42 -0
  21. package/dist/cjs/objects/PinDefinition.js +31 -0
  22. package/dist/cjs/objects/PinTypes.js +11 -0
  23. package/dist/cjs/objects/Wire.js +9 -0
  24. package/dist/cjs/objects/types.js +9 -0
  25. package/dist/cjs/parser.js +299 -0
  26. package/dist/cjs/regenerate-tests.js +23 -0
  27. package/dist/cjs/render.js +155 -0
  28. package/{src/server.ts → dist/cjs/server.js} +15 -21
  29. package/dist/cjs/sizing.js +105 -0
  30. package/{src/utils.ts → dist/cjs/utils.js} +25 -35
  31. package/{src/visitor.ts → dist/cjs/visitor.js} +392 -948
  32. package/{build/src/antlr/CircuitScriptLexer.js → dist/esm/antlr/CircuitScriptLexer.mjs} +90 -91
  33. package/{build/src/antlr/CircuitScriptParser.js → dist/esm/antlr/CircuitScriptParser.mjs} +138 -136
  34. package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +11 -11
  35. package/{build/src/execute.js → dist/esm/execute.mjs} +9 -8
  36. package/{build/src/export.js → dist/esm/export.mjs} +2 -2
  37. package/{build/src/geometry.js → dist/esm/geometry.mjs} +3 -7
  38. package/{build/src/helpers.js → dist/esm/helpers.mjs} +27 -7
  39. package/dist/esm/index.mjs +13 -0
  40. package/{build/src/layout.js → dist/esm/layout.mjs} +11 -11
  41. package/{build/src/lexer.js → dist/esm/lexer.mjs} +2 -2
  42. package/{build/src/main.js → dist/esm/main.mjs} +5 -5
  43. package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +3 -3
  44. package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
  45. package/dist/esm/parser.mjs +269 -0
  46. package/{build/src/regenerate-tests.js → dist/esm/regenerate-tests.mjs} +1 -1
  47. package/{build/src/render.js → dist/esm/render.mjs} +7 -24
  48. package/{build/src/sizing.js → dist/esm/sizing.mjs} +22 -8
  49. package/{build/src/visitor.js → dist/esm/visitor.mjs} +10 -29
  50. package/{build/src → dist/types}/antlr/CircuitScriptLexer.d.ts +23 -23
  51. package/{build/src → dist/types}/antlr/CircuitScriptParser.d.ts +24 -23
  52. package/{build/src → dist/types}/draw_symbols.d.ts +2 -2
  53. package/{build/src → dist/types}/execute.d.ts +2 -2
  54. package/{build/src → dist/types}/geometry.d.ts +1 -1
  55. package/dist/types/helpers.d.ts +9 -0
  56. package/dist/types/index.d.ts +13 -0
  57. package/{build/src → dist/types}/layout.d.ts +10 -10
  58. package/{build/src → dist/types}/objects/ClassComponent.d.ts +2 -2
  59. package/{build/src → dist/types}/objects/PinDefinition.d.ts +1 -1
  60. package/dist/types/parser.d.ts +38 -0
  61. package/{build/src → dist/types}/render.d.ts +1 -1
  62. package/{build/src → dist/types}/sizing.d.ts +3 -1
  63. package/{build/src → dist/types}/visitor.d.ts +5 -3
  64. package/package.json +30 -12
  65. package/.editorconfig +0 -15
  66. package/.eslintignore +0 -1
  67. package/.eslintrc.json +0 -27
  68. package/.gitlab-ci.yml +0 -81
  69. package/.prettierignore +0 -8
  70. package/.prettierrc +0 -16
  71. package/__tests__/expectedResults.ts +0 -657
  72. package/__tests__/helpers.ts +0 -82
  73. package/__tests__/parseScripts.ts +0 -593
  74. package/__tests__/renderData/script1.cst +0 -58
  75. package/__tests__/renderData/script1.cst.svg +0 -1
  76. package/__tests__/renderData/script2.cst +0 -16
  77. package/__tests__/renderData/script2.cst.svg +0 -1
  78. package/__tests__/renderData/script3.cst +0 -30
  79. package/__tests__/renderData/script3.cst.svg +0 -1
  80. package/__tests__/renderData/script4.cst +0 -54
  81. package/__tests__/renderData/script4.cst.svg +0 -1
  82. package/__tests__/renderData/script5.cst +0 -23
  83. package/__tests__/renderData/script5.cst.svg +0 -1
  84. package/__tests__/renderData/script6.cst +0 -28
  85. package/__tests__/renderData/script6.cst.svg +0 -1
  86. package/__tests__/renderData/script7.cst +0 -26
  87. package/__tests__/renderData/script7.cst.svg +0 -1
  88. package/__tests__/renderData/script8.cst +0 -37
  89. package/__tests__/renderData/script8.cst.svg +0 -1
  90. package/__tests__/testCLI.ts +0 -68
  91. package/__tests__/testMathOps.ts +0 -36
  92. package/__tests__/testMergeWires.ts +0 -141
  93. package/__tests__/testParse.ts +0 -263
  94. package/__tests__/testRender.ts +0 -38
  95. package/build/src/helpers.d.ts +0 -1
  96. package/build/src/parser.js +0 -69
  97. package/documentation.md +0 -238
  98. package/examples/example_arduino_uno.cst +0 -1146
  99. package/examples/example_garden_pump.cst +0 -567
  100. package/examples/lib.cst +0 -185
  101. package/fonts/Inter-Bold.ttf +0 -0
  102. package/fonts/Inter-Regular.ttf +0 -0
  103. package/fonts/OpenSans-Regular.ttf +0 -0
  104. package/fonts/Roboto-Regular.ttf +0 -0
  105. package/jest.config.js +0 -23
  106. package/libs/lib.cst +0 -185
  107. package/refresh.html +0 -42
  108. package/server.cjs +0 -50
  109. package/src/antlr/CircuitScript.g4 +0 -209
  110. package/src/antlr/CircuitScriptLexer.ts +0 -317
  111. package/src/antlr/CircuitScriptParser.ts +0 -4979
  112. package/src/antlr/CircuitScriptVisitor.ts +0 -420
  113. package/src/execute.ts +0 -1227
  114. package/src/fonts.ts +0 -1
  115. package/src/geometry.ts +0 -638
  116. package/src/globals.ts +0 -67
  117. package/src/helpers.ts +0 -114
  118. package/src/lexer.ts +0 -151
  119. package/src/logger.ts +0 -17
  120. package/src/main.ts +0 -105
  121. package/src/objects/ClassComponent.ts +0 -223
  122. package/src/objects/ExecutionScope.ts +0 -201
  123. package/src/objects/Frame.ts +0 -20
  124. package/src/objects/ParamDefinition.ts +0 -49
  125. package/src/objects/PinDefinition.ts +0 -49
  126. package/src/objects/PinTypes.ts +0 -7
  127. package/src/objects/Wire.ts +0 -19
  128. package/src/objects/types.ts +0 -66
  129. package/src/parser.ts +0 -106
  130. package/src/regenerate-tests.ts +0 -25
  131. package/src/render.ts +0 -260
  132. package/src/sizing.ts +0 -96
  133. package/tsconfig.json +0 -27
  134. package/tsconfig.release.json +0 -8
  135. /package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +0 -0
  136. /package/{build/src/fonts.js → dist/esm/fonts.mjs} +0 -0
  137. /package/{build/src/globals.js → dist/esm/globals.mjs} +0 -0
  138. /package/{build/src/logger.js → dist/esm/logger.mjs} +0 -0
  139. /package/{build/src/objects/ExecutionScope.js → dist/esm/objects/ExecutionScope.mjs} +0 -0
  140. /package/{build/src/objects/Frame.js → dist/esm/objects/Frame.mjs} +0 -0
  141. /package/{build/src/objects/Net.js → dist/esm/objects/Net.mjs} +0 -0
  142. /package/{build/src/objects/ParamDefinition.js → dist/esm/objects/ParamDefinition.mjs} +0 -0
  143. /package/{build/src/objects/PinTypes.js → dist/esm/objects/PinTypes.mjs} +0 -0
  144. /package/{build/src/objects/Wire.js → dist/esm/objects/Wire.mjs} +0 -0
  145. /package/{build/src/objects/types.js → dist/esm/objects/types.mjs} +0 -0
  146. /package/{build/src/server.js → dist/esm/server.mjs} +0 -0
  147. /package/{build/src/utils.js → dist/esm/utils.mjs} +0 -0
  148. /package/{build/src → dist/types}/antlr/CircuitScriptVisitor.d.ts +0 -0
  149. /package/{build/src → dist/types}/export.d.ts +0 -0
  150. /package/{build/src → dist/types}/fonts.d.ts +0 -0
  151. /package/{build/src → dist/types}/globals.d.ts +0 -0
  152. /package/{build/src → dist/types}/lexer.d.ts +0 -0
  153. /package/{build/src → dist/types}/logger.d.ts +0 -0
  154. /package/{build/src → dist/types}/main.d.ts +0 -0
  155. /package/{build/src → dist/types}/objects/ExecutionScope.d.ts +0 -0
  156. /package/{build/src → dist/types}/objects/Frame.d.ts +0 -0
  157. /package/{build/src → dist/types}/objects/Net.d.ts +0 -0
  158. /package/{build/src → dist/types}/objects/ParamDefinition.d.ts +0 -0
  159. /package/{build/src → dist/types}/objects/PinTypes.d.ts +0 -0
  160. /package/{build/src → dist/types}/objects/Wire.d.ts +0 -0
  161. /package/{build/src → dist/types}/objects/types.d.ts +0 -0
  162. /package/{build/src → dist/types}/regenerate-tests.d.ts +0 -0
  163. /package/{build/src → dist/types}/server.d.ts +0 -0
  164. /package/{build/src → dist/types}/utils.d.ts +0 -0
package/src/execute.ts DELETED
@@ -1,1227 +0,0 @@
1
- import { BlockTypes, ComponentTypes, GlobalNames, NoNetText, ParamKeys, ReferenceTypes } from './globals.js';
2
- import { ClassComponent } from './objects/ClassComponent.js';
3
- import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.js';
4
- import { Net } from './objects/Net.js';
5
- import { ParamDefinition } from './objects/ParamDefinition.js';
6
- import { PinDefinition, PortSide } from './objects/PinDefinition.js';
7
- import { CFunction, CFunctionResult, CallableParameter, ComponentPin, ReferenceType } from './objects/types.js';
8
- import { Wire, WireSegment } from './objects/Wire.js';
9
- import { Logger } from './logger.js';
10
- import { Frame } from './objects/Frame.js';
11
-
12
- export class ExecutionContext {
13
- // Contains the current running state of the circuit web
14
-
15
- name: string; // Local name of the execution context.
16
-
17
- // Namespace of current execution context, used for
18
- // building the specific name of instances
19
- namespace: string;
20
-
21
- // Namespace for building nets, split away from instance namespace so
22
- // that the net names generated are cleaner.
23
- netNamespace: string;
24
-
25
- executionLevel: number;
26
-
27
- scope: ExecutionScope;
28
-
29
- tmpPointId = 0; // Counter for points created within the context
30
-
31
- resolveNet: (name: string, netNamespace:string) => ({
32
- found: boolean, net?: Net
33
- }) = null;
34
-
35
- // If true, then do no evaluate further expressions.
36
- // Used for function state control
37
- stopFurtherExpressions = false;
38
-
39
- // Return result of the context
40
- returnValue = null;
41
-
42
- // If true, then do not print any messages
43
- silent = false;
44
-
45
- logger: Logger;
46
-
47
- __functionCache = {};
48
-
49
-
50
- constructor(
51
- name: string,
52
- namespace: string,
53
- netNamespace: string,
54
- executionLevel = 0,
55
- indentLevel = 0,
56
- silent = false,
57
- logger: Logger
58
- ) {
59
- this.name = name;
60
- this.namespace = namespace;
61
- this.netNamespace = netNamespace;
62
-
63
- this.executionLevel = executionLevel;
64
- this.logger = logger;
65
-
66
- this.scope = ExecutionScope.create();
67
- this.scope.indentLevel = indentLevel;
68
-
69
- this.setupRoot();
70
-
71
- this.silent = silent;
72
-
73
- this.print(
74
- 'create new execution context',
75
- this.namespace,
76
- this.name,
77
- this.scope.indentLevel,
78
- );
79
- }
80
-
81
- print(...params: any[]): void {
82
- const indentOutput = ''.padStart(this.scope.indentLevel * 4, ' ');
83
- const indentLevelText = this.scope.indentLevel
84
- .toString()
85
- .padStart(3, ' ');
86
-
87
- const args = ['[' + indentLevelText + ']', indentOutput, ...params];
88
-
89
- this.logger.add(args.join(' '));
90
-
91
- if (this.silent) {
92
- return;
93
- }
94
- console.log.apply(null, args);
95
- }
96
-
97
- private setupRoot(): void {
98
- // Setup the root node in the scope
99
- const componentRoot = ClassComponent.simple(
100
- GlobalNames.__root,
101
- 1,
102
- '__root',
103
- );
104
- componentRoot.typeProp = ComponentTypes.net;
105
-
106
- this.scope.instances.set(GlobalNames.__root, componentRoot);
107
-
108
- this.scope.currentComponent = componentRoot;
109
- this.scope.currentPin = componentRoot.getDefaultPin();
110
-
111
- this.scope.componentRoot = componentRoot;
112
- }
113
-
114
-
115
- instanceExists(instanceName: string): boolean {
116
- return this.scope.instances.has(instanceName);
117
- }
118
-
119
- getComponent(instanceName: string): ClassComponent {
120
- return this.scope.instances.get(instanceName);
121
- }
122
-
123
- getUniqueInstanceName(className: string): string {
124
- let extraPrefix = '';
125
-
126
- switch (className) {
127
- case GlobalNames.DefaultResistor:
128
- extraPrefix = 'R_';
129
- break;
130
- case GlobalNames.DefaultCapacitor:
131
- extraPrefix = 'C_';
132
- break;
133
- case GlobalNames.DefaultInductor:
134
- extraPrefix = 'L_';
135
- break;
136
- }
137
-
138
- const tmpName = extraPrefix + 'COMP_' + this.scope.unnamedCounter;
139
- this.scope.unnamedCounter += 1;
140
-
141
- return tmpName;
142
- }
143
-
144
- getUniqueNetName(): string {
145
- const tmpName = 'NET_' + this.scope.netCounter;
146
- this.scope.netCounter++;
147
- return tmpName;
148
- }
149
-
150
- getCurrentPoint(): ComponentPin {
151
- return [this.scope.currentComponent, this.scope.currentPin];
152
- }
153
-
154
- private linkComponentPinNet(
155
- component1: ClassComponent,
156
- component1Pin: number,
157
- component2: ClassComponent,
158
- component2Pin: number,
159
- ): Net {
160
- const net1_exists = this.scope.hasNet(component1, component1Pin);
161
- const net2_exists = this.scope.hasNet(component2, component2Pin);
162
-
163
- const net1 = net1_exists
164
- ? this.scope.getNet(component1, component1Pin)
165
- : null;
166
- const net2 = net2_exists
167
- ? this.scope.getNet(component2, component2Pin)
168
- : null;
169
-
170
- this.print('link nets', component1, component1Pin, net1,
171
- 'to', component2, component2Pin, net2);
172
-
173
- let returnNet: Net;
174
-
175
- if (net1 === null && net2 === null) {
176
- // Both nets do not exist yet, so create a new one
177
- // that both will use.
178
- const tmpNet = new Net(this.netNamespace, this.getUniqueNetName());
179
-
180
- this.scope.setNet(component1, component1Pin, tmpNet);
181
- this.scope.setNet(component2, component2Pin, tmpNet);
182
-
183
- returnNet = tmpNet;
184
-
185
- } else if (net1 === null && net2 !== null) {
186
- // If net1 does not exist, but net2 exists
187
- this.scope.setNet(component1, component1Pin, net2);
188
- returnNet = net2;
189
-
190
- } else if (net1 !== null && net2 === null) {
191
- // If net1 exists, but net2 does not exist
192
- this.scope.setNet(component2, component2Pin, net1);
193
- returnNet = net1;
194
-
195
- } else {
196
- if (net1 !== net2) {
197
- returnNet = this.mergeNets(net1, net2);
198
- } else {
199
- // Otherwise, both nets are the same.
200
- return net1;
201
- }
202
- }
203
-
204
- return returnNet;
205
- }
206
-
207
- private mergeNets(net1: Net, net2: Net): Net {
208
- // By default merge net2 into net1, net2 will no longer be used.
209
- if (net1 === net2) {
210
- return;
211
- }
212
-
213
- let tmpNet: Net;
214
-
215
- // Check priority to ensure that net1 always
216
- // has the higher priority. Swap both nets
217
- // if this is not the case.
218
- if (net2.priority > net1.priority) {
219
- tmpNet = net1;
220
- net1 = net2;
221
- net2 = tmpNet;
222
- }
223
-
224
- // Get all (component, pin) pairs that are linked to net2
225
- // and change them to net1
226
- const scopeNets = this.scope.getNets();
227
- scopeNets.forEach(([component, pin, net]) => {
228
- if (Net.isSame(net, net2)) {
229
- this.scope.setNet(component, pin, net1);
230
- }
231
- });
232
-
233
- return net1;
234
- }
235
-
236
- createComponent(
237
- instanceName: string,
238
- pins: PinDefinition[],
239
- params: ParamDefinition[],
240
- props: {
241
- arrange?: Map<string, number[]>,
242
- display?: string,
243
- type?: string,
244
- width?: number
245
- }
246
- ): ClassComponent {
247
-
248
- const numPins = pins.length;
249
- const component = new ClassComponent(
250
- instanceName,
251
- numPins,
252
- GlobalNames.symbol,
253
- );
254
- pins.forEach((pin) => {
255
- component.pins.set(pin.id, pin);
256
- });
257
-
258
- const paramsMap = new Map<string, any>();
259
-
260
- params.forEach((param) => {
261
- component.parameters.set(param.paramName, param.paramValue);
262
- paramsMap.set(param.paramName, param.paramValue);
263
- });
264
-
265
- if (paramsMap.has(ParamKeys.__is_net)) {
266
- const netName = paramsMap.get(ParamKeys.net_name);
267
- const priority = paramsMap.get(ParamKeys.priority);
268
-
269
- // Check if the net exists
270
- const result = this.resolveNet(netName, this.netNamespace);
271
- let tmpNet: Net;
272
-
273
- if (result.found) {
274
- tmpNet = result.net;
275
- this.print('net found', tmpNet.namespace, tmpNet.name);
276
-
277
- } else {
278
- tmpNet = new Net(this.netNamespace, netName, priority);
279
- this.print('net not found, added net instance',
280
- tmpNet.namespace, tmpNet.name);
281
- }
282
-
283
- // Assume net is on 1 pin for now
284
- this.scope.setNet(component, 1, tmpNet);
285
- this.print('set net', netName, 'component', component);
286
- }
287
-
288
- const {arrange = null} = props;
289
-
290
- component.arrangeProps = arrange;
291
- component.displayProp = props.display ?? null;
292
- component.widthProp = props.width ?? null;
293
- component.typeProp = props.type ?? null;
294
-
295
- // Determine the side for each pin and update the
296
- // pin definition
297
- const portSides = getPortSide(component.pins, arrange);
298
- portSides.forEach(({ pinId, side, position }) => {
299
- if (component.pins.has(pinId)){
300
- const tmpPin = component.pins.get(pinId);
301
- tmpPin.side = side;
302
- tmpPin.position = position;
303
- }
304
- });
305
-
306
- this.scope.instances.set(instanceName, component);
307
-
308
- const pinsOutput = pins.map((pin) => {
309
- return pin.id + ':' + pin.name;
310
- });
311
-
312
- this.print(
313
- 'add symbol',
314
- instanceName,
315
- '[' + pinsOutput.join(', ') + ']',
316
- );
317
-
318
- return component;
319
- }
320
-
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
-
332
- this.print(
333
- (extra !== '' ? (extra + ' ') : '') + 'point: ' +
334
- this.scope.currentComponent.instanceName +
335
- ' ' +
336
- this.scope.currentPin + ' ' + netName
337
- );
338
- }
339
-
340
- addComponentExisting(component: ClassComponent, pin: number): ComponentPin {
341
- const startPin = pin;
342
- const nextPin = component.getNextPinAfter(startPin);
343
-
344
- // Add to sequence
345
- this.toComponent(component, startPin, {addSequence: true});
346
-
347
- this.print('move to next pin: ' + nextPin);
348
- this.atComponent(component, nextPin, {
349
- addSequence: true
350
- });
351
-
352
- this.printPoint();
353
-
354
- return this.getCurrentPoint();
355
- }
356
-
357
- toComponent(
358
- component: ClassComponent,
359
- pinId: number | null,
360
- options?: {
361
- addSequence?: boolean,
362
- cloneNetComponent?: boolean,
363
- }): ComponentPin {
364
- this.print('to component');
365
-
366
- const { addSequence = false, cloneNetComponent = false } = options ?? {};
367
-
368
- if (cloneNetComponent && this.isNetOnlyComponent(component)) {
369
- component = this.cloneComponent(component);
370
- }
371
-
372
- if (!(component instanceof ClassComponent)){
373
- throw "Not a valid component!";
374
- }
375
-
376
- if (pinId === null) {
377
- pinId = component.getDefaultPin();
378
- } else {
379
-
380
- if (component.hasPin(pinId)) {
381
- pinId = component.getPin(pinId);
382
- } else {
383
- console.trace();
384
- throw (
385
- 'Invalid pin number ' +
386
- pinId +
387
- ' in ' +
388
- component.instanceName
389
- );
390
- }
391
- }
392
-
393
- if (
394
- this.scope.hasNet(
395
- this.scope.currentComponent,
396
- this.scope.currentPin,
397
- )
398
- ) {
399
- this.print(
400
- 'net: ',
401
- this.scope
402
- .getNet(this.scope.currentComponent, this.scope.currentPin)
403
- .toString(),
404
- );
405
- }
406
-
407
- const linkedNet = this.linkComponentPinNet(
408
- this.scope.currentComponent,
409
- this.scope.currentPin,
410
- component,
411
- pinId,
412
- );
413
-
414
- this.scope.currentComponent = component;
415
- this.scope.currentPin = pinId;
416
-
417
- this.scope.clearActive();
418
-
419
- if (addSequence) {
420
- if (this.scope.sequence.length > 0) {
421
-
422
- // Prevent component pin from being connected to multiple
423
- // wires at the same time. This happens if the user tries
424
- // to add the same (non-net) component at multiple places.
425
- if (component.pinWires.has(pinId) && component.typeProp !== ComponentTypes.point) {
426
- // throw "Component pin already connected to wire"
427
- }
428
-
429
- // Check if the previous entry is a wire
430
- const [entryType, , segments]: [SequenceAction, number, WireSegment[]] =
431
- this.scope.sequence[this.scope.sequence.length - 1];
432
-
433
- if (entryType === SequenceAction.Wire && isWireSegmentsEndAuto(segments)) {
434
- segments[segments.length - 1].until = [
435
- component, pinId
436
- ];
437
- }
438
-
439
- component.pinWires.set(pinId, segments);
440
- }
441
-
442
- this.scope.sequence.push([SequenceAction.To, component,
443
- pinId, linkedNet]);
444
- }
445
-
446
- this.printPoint();
447
-
448
- return this.getCurrentPoint();
449
- }
450
-
451
- atComponent(
452
- component: ClassComponent,
453
- pinId: number | null,
454
- options?: {
455
- addSequence?: boolean,
456
- cloneNetComponent?: boolean,
457
- }): ComponentPin {
458
- this.print('at component');
459
-
460
- const { addSequence = false, cloneNetComponent = false } = options ?? {};
461
-
462
- if (cloneNetComponent && this.isNetOnlyComponent(component)) {
463
- component = this.cloneComponent(component);
464
- }
465
-
466
- this.scope.currentComponent = component;
467
-
468
- let usePinId: number;
469
- if (pinId === null) {
470
- usePinId = component.getDefaultPin();
471
- } else {
472
- if (component.hasPin(pinId)) {
473
- usePinId = component.getPin(pinId);
474
- } else {
475
- throw 'Invalid pin number ' + pinId + ' in ' + component;
476
- }
477
- }
478
-
479
- if (usePinId) {
480
- this.scope.currentPin = usePinId;
481
- }
482
-
483
- // Insertion point is currently at a component pin, so clear
484
- // any wire/frame selected.
485
- this.scope.clearActive();
486
-
487
- if (addSequence) {
488
- this.scope.sequence.push([SequenceAction.At,
489
- component, usePinId]);
490
- }
491
-
492
- this.printPoint();
493
-
494
- return this.getCurrentPoint();
495
- }
496
-
497
- private isNetOnlyComponent(component: ClassComponent): boolean {
498
- return isNetComponent(component) && !isLabelComponent(component);
499
- }
500
-
501
- private cloneComponent(component: ClassComponent): ClassComponent {
502
- // This creates a clone from a given net component, assume only
503
- // has 1 pin
504
-
505
- let clonedComponent: ClassComponent = null;
506
-
507
- // If is a net component and not a label component, then
508
- // create a new copy of the same net component.
509
- if (!this.scope.copyIDs.has(component.instanceName)) {
510
- this.scope.copyIDs.set(component.instanceName, 0);
511
- }
512
-
513
- const idNum = this.scope.copyIDs.get(component.instanceName);
514
- clonedComponent = component.clone();
515
- clonedComponent._copyID = idNum;
516
- clonedComponent._copyFrom = component;
517
-
518
- // Set linkIDs to the next value to use
519
- this.scope.copyIDs.set(component.instanceName, idNum + 1);
520
-
521
- const cloneInstanceName = component.instanceName + ':' + idNum;
522
-
523
- // Add the cloned component
524
- this.scope.instances.set(cloneInstanceName,
525
- clonedComponent);
526
- clonedComponent.instanceName = cloneInstanceName;
527
-
528
- // Link pin of cloned component onto the same net
529
- this.linkComponentPinNet(
530
- component, 1,
531
- clonedComponent, 1
532
- );
533
-
534
- this.print('created clone of net component:', cloneInstanceName);
535
-
536
- return clonedComponent;
537
- }
538
-
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>(),
558
- current_index: null,
559
- type: blockType,
560
- });
561
-
562
- this.print('enter blocks');
563
- }
564
-
565
- exitBlocks(): void {
566
- const stackRef = this.scope.blockStack.get(
567
- this.scope.indentLevel,
568
- );
569
-
570
- const { type: blockType } = stackRef;
571
-
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;
576
-
577
- this.scope.currentComponent = component;
578
- this.scope.currentPin = pin;
579
- this.scope.currentWireId = wireId;
580
-
581
- if (wireId !== -1) {
582
- this.scope.sequence.push([
583
- SequenceAction.WireJump, wireId, 1
584
- ]);
585
- }
586
- } else if (blockType === BlockTypes.Point) {
587
- const { entered_at: [component, pin,] } =
588
- stackRef;
589
-
590
- // Preblock location should be a created point without any wires
591
- this.atComponent(component, pin, { addSequence: true });
592
- }
593
-
594
- this.print('exit blocks');
595
- }
596
-
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
-
602
- const { type: blockType } = stackRef;
603
-
604
- // Setup the state for the inner block at the given index
605
- stackRef['inner_blocks'].set(blockIndex, {
606
- last_net: null,
607
- ignore_last_net: false,
608
- });
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
-
623
- this.scope.indentLevel += 1;
624
- }
625
-
626
- exitBlock(blockIndex: number): void {
627
- const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1);
628
- const { type: blockType } = stackRef;
629
-
630
- // Save the last net reference
631
- const blockIndexRef = stackRef['inner_blocks'].get(blockIndex);
632
- blockIndexRef['last_net'] = [
633
- this.scope.currentComponent,
634
- this.scope.currentPin,
635
- this.scope.currentWireId
636
- ];
637
-
638
- stackRef['block_index'] = null;
639
- this.scope.indentLevel -= 1;
640
-
641
- this.print('exit inner block <<<');
642
-
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
- }
697
-
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');
702
-
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];
707
-
708
- if (component.instanceName.startsWith('_point.')) {
709
- return entered_at;
710
- }
711
- }
712
-
713
- this.print('did not find block point');
714
-
715
- return null;
716
- }
717
-
718
- breakBranch(): void {
719
- this.print('break branch');
720
- // Mark that the branch stack at the current indent level
721
- // should be ignored
722
-
723
- const branchesInfo = this.scope.blockStack.get(
724
- this.scope.indentLevel - 1,
725
- );
726
- const branchIndex = branchesInfo['block_index'];
727
-
728
- const branchIndexRef = branchesInfo['inner_blocks'].get(branchIndex);
729
- branchIndexRef['ignore_last_net'] = true;
730
- }
731
-
732
- createFunction(functionName: string, __runFunc: CFunction): void {
733
- this.scope.functions.set(functionName, __runFunc);
734
- this.__functionCache[functionName] = __runFunc;
735
- this.print(`defined new function '${functionName}'`);
736
- }
737
-
738
- hasFunction(functionName: string): boolean {
739
- return this.scope.functions.has(functionName);
740
- }
741
-
742
- getFunction(functionName: string): CFunction {
743
- return this.scope.functions.get(functionName);
744
- }
745
-
746
- resolveVariable(executionStack: ExecutionContext[], idName: string):
747
- ReferenceType {
748
- // this.print('resolve variable', idName);
749
- const reversed = [...executionStack].reverse();
750
-
751
- for (let i = 0; i < reversed.length; i++) {
752
- const context = reversed[i];
753
- if (context.hasFunction(idName)) {
754
- return {
755
- found: true,
756
- value: context.getFunction(idName),
757
- type: ReferenceTypes.function,
758
- name: idName,
759
- }
760
-
761
- } else if (context.scope.variables.has(idName)) {
762
- return {
763
- found: true,
764
- value: context.scope.variables.get(idName),
765
- type: ReferenceTypes.variable,
766
- name: idName,
767
- };
768
-
769
- } else if (context.scope.instances.has(idName)) {
770
- return {
771
- found: true,
772
- value: context.scope.instances.get(idName),
773
- type: ReferenceTypes.instance,
774
- name: idName,
775
- }
776
- }
777
- }
778
-
779
- return {
780
- found: false,
781
- name: idName,
782
- }
783
- }
784
-
785
- callFunction(
786
- functionName: string,
787
- functionParams: CallableParameter[],
788
- executionStack: ExecutionContext[],
789
- netNamespace: string,
790
- ): CFunctionResult {
791
- let __runFunc: CFunction | null = null;
792
-
793
- // Function is not cached yet, so look for it
794
- if (this.__functionCache[functionName] === undefined){
795
- if (this.hasFunction(functionName)) {
796
- __runFunc = this.getFunction(functionName);
797
- }
798
-
799
- // If the function does not exist in the current execution context,
800
- // then try to search in the upper execution context
801
- if (__runFunc === null) {
802
- this.print(`searching for function ${functionName} in upper context`)
803
-
804
- const tmpResolveResult =
805
- this.resolveVariable(executionStack, functionName);
806
-
807
- if (tmpResolveResult.found) {
808
- __runFunc = tmpResolveResult.value;
809
- } else {
810
- throw `Invalid function ${functionName}`;
811
- }
812
- }
813
- this.print('save function to cache:', functionName);
814
- this.__functionCache[functionName] = __runFunc;
815
-
816
- } else {
817
- this.print('found function in cache:', functionName);
818
- __runFunc = this.__functionCache[functionName];
819
- }
820
-
821
- if (__runFunc !== null) {
822
- this.print(`call function '${functionName}'`);
823
-
824
- const functionResult = __runFunc(
825
- functionParams,
826
- { netNamespace });
827
-
828
- this.print(`done call function '${functionName}'`);
829
-
830
- return functionResult;
831
- } else {
832
- throw `Invalid function '${functionName}'`;
833
- }
834
- }
835
-
836
- mergeScope(childScope: ExecutionScope, namespace: string): void {
837
- this.print('-- merging scope to parent --');
838
-
839
- // Save these position first, because this needs to be restored
840
- // after the merge operation
841
- const currentComponent = this.scope.currentComponent;
842
- const currentPin = this.scope.currentPin;
843
- const currentWireId = this.scope.currentWireId;
844
-
845
- // move all instances into the parent scope first, with a namespace extension
846
- const tmpInstances = childScope.instances;
847
- const tmpNets = childScope.getNets();
848
-
849
- for (const [instanceName, component] of tmpInstances) {
850
- // Rename instance names with the addition of the namespace
851
- const newInstanceName = `${namespace}.${instanceName}`;
852
- component.instanceName = newInstanceName;
853
-
854
- // Do not add root and gnd components of child scope to the
855
- // parent scope
856
- if (component === childScope.componentGnd ||
857
- component === childScope.componentRoot){
858
- continue;
859
- }
860
-
861
- if (!this.scope.instances.has(newInstanceName)) {
862
- this.scope.instances.set(newInstanceName, component);
863
- } else {
864
- throw "Invalid instance name to merge into parent scope!";
865
- }
866
- }
867
-
868
- // Merge all nets into parent scope
869
- tmpNets.forEach(([component, pin, net]) => {
870
- this.scope.setNet(component, pin, net);
871
- });
872
-
873
- // If true, then then __root component of the child_scope will
874
- // be connected to the current component/pin of the parent
875
- const linkRootComponent = true;
876
-
877
- const tmpRoot = childScope.componentRoot;
878
-
879
- if (linkRootComponent) {
880
- // Join the child_scope's __root net to the current component / pin
881
-
882
- // Get the net of the root scope first
883
- const netConnectedToRoot = childScope.getNet(tmpRoot, 1);
884
-
885
- if (netConnectedToRoot !== null){
886
- // Only if the child scope root component is connected
887
- // to a net, then merge them together.
888
- let currentNet = this.scope.getNet(
889
- currentComponent, currentPin
890
- );
891
-
892
- if (currentNet === null){
893
- // Current net does not exist yet, so create it
894
- const tmpNet = new Net(this.netNamespace,
895
- this.getUniqueNetName());
896
-
897
- this.scope.setNet(
898
- currentComponent, currentPin, netConnectedToRoot);
899
- currentNet = tmpNet
900
- }
901
-
902
- netConnectedToRoot.priority = currentNet.priority - 1;
903
-
904
- // Connect current component to the root component, since the
905
- // net priority of the current component and pin is higher,
906
- // then the root component's net will be merged in.
907
- this.toComponent(tmpRoot, 1);
908
- }
909
- }
910
-
911
- // Merge the sequences together, need to renumber the wire ids.
912
- const wireIdOffset = this.scope.wires.length;
913
-
914
- // Need to renumber the frame ids too.
915
- const frameIdOffset = this.scope.frames.length;
916
-
917
- let incrementGndLinkId = 0;
918
-
919
- childScope.sequence.forEach(sequenceAction => {
920
- const [action] = sequenceAction;
921
-
922
- if (action === SequenceAction.Wire) {
923
- // Need to have new IDs for wires
924
- const [, innerWireId, segments] = sequenceAction;
925
-
926
- this.scope.sequence.push(
927
- [SequenceAction.Wire, wireIdOffset + innerWireId, segments]
928
- );
929
-
930
- this.scope.wires.push(new Wire(segments));
931
-
932
- } else if (action === SequenceAction.WireJump) {
933
- // Wire IDs in wire jumps need to be updated.
934
- const jumpWireId = wireIdOffset + sequenceAction[1];
935
- this.scope.sequence.push(
936
- [SequenceAction.WireJump, jumpWireId, 1]
937
- );
938
- } else if (action === SequenceAction.At || action === SequenceAction.To) {
939
- const tmpComponent: ClassComponent = sequenceAction[1];
940
-
941
- // Check if the component is a gnd component
942
- if (isNetComponent(tmpComponent) && tmpComponent.parameters.get(ParamKeys.net_name) === 'gnd') {
943
- // Is a gnd net
944
- tmpComponent._copyID = gndCopyIdOffset + incrementGndLinkId;
945
- incrementGndLinkId += 1;
946
-
947
- } else if (tmpComponent === tmpRoot) {
948
- // If this sequence action contains the root component,
949
- // then replace it with a corresponding sequence action.
950
- // If current wire id is set, then use a wire jump sequence
951
- // action, otherwise use at/to action.
952
-
953
- if (currentWireId !== -1){
954
- sequenceAction = [SequenceAction.WireJump, currentWireId];
955
-
956
- } else {
957
- // If is the root component, then replace it by the current
958
- // component and pin
959
- sequenceAction = [action, currentComponent, currentPin];
960
- }
961
- }
962
- this.scope.sequence.push(sequenceAction);
963
-
964
- } else if (action === SequenceAction.Frame){
965
- const frame: Frame = sequenceAction[1];
966
- const frameAction: string = sequenceAction[2];
967
- if (frameAction === FrameAction.Enter){
968
- frame.frameId += frameIdOffset;
969
- this.scope.frames.push(frame);
970
- }
971
-
972
- this.scope.sequence.push(sequenceAction);
973
- }
974
- });
975
-
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;
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
-
994
- this.print('-- nets --');
995
-
996
- // dump the list of nets in the current scope
997
- const currentNets = this.scope.getNets();
998
-
999
- currentNets.reduce((accum, [,,net]) => {
1000
- if (accum.indexOf(net) === -1){
1001
- accum.push(net);
1002
- this.print(`${net.namespace}${net.name} ${net.priority}`);
1003
- }
1004
- return accum;
1005
- }, []);
1006
-
1007
- this.print('-- done merging scope --');
1008
- }
1009
-
1010
- addWire(segments: [string, number?][]): void {
1011
-
1012
- if (this.scope.currentComponent === null) {
1013
- throw "No current component";
1014
- }
1015
-
1016
- const tmp = segments.map(item => {
1017
- const [direction, value=null] = item;
1018
- return {
1019
- direction,
1020
- value
1021
- } as WireSegment
1022
- });
1023
-
1024
- // This ID is used to identify/jump to wires later
1025
- const wireId = this.scope.wires.length;
1026
-
1027
- this.scope.wires.push(new Wire(tmp));
1028
-
1029
- const output = [];
1030
- segments.forEach(item => {
1031
- output.push(item.join(","));
1032
- });
1033
-
1034
- this.print('add wire: ', output.join("|"));
1035
-
1036
- this.scope.setActive(ActiveObject.Wire, wireId);
1037
- this.scope.sequence.push([SequenceAction.Wire, wireId, tmp]);
1038
-
1039
- // if (this.scope.currentComponent.pinWires.has(this.scope.currentPin)) {
1040
- // throw "Component pin already connected to wire"
1041
- // }
1042
-
1043
- this.scope.currentComponent.pinWires.set(
1044
- this.scope.currentPin, tmp
1045
- )
1046
- }
1047
-
1048
- addPoint(pointId: string, userDefined = true): ComponentPin {
1049
- if (this.scope.instances.has(pointId)) {
1050
- this.print('Warning: ' + pointId + ' is being redefined');
1051
- }
1052
-
1053
- const useName = userDefined ? 'point.' + pointId : pointId;
1054
- const componentPoint = ClassComponent.simple(useName, 1, "point");
1055
- componentPoint.displayProp = "point";
1056
- componentPoint.typeProp = ComponentTypes.point;
1057
-
1058
- this.scope.instances.set(pointId, componentPoint);
1059
- this.toComponent(componentPoint, 1, { addSequence: true });
1060
-
1061
- return this.getCurrentPoint();
1062
- }
1063
-
1064
- setProperty(nameWithProp: string, value: any): void {
1065
- this.print('set property', nameWithProp, 'value', value);
1066
-
1067
- let idName: string;
1068
- let paramName: string;
1069
-
1070
- let useActive = false;
1071
-
1072
- if (nameWithProp.startsWith('..')){
1073
- useActive = true;
1074
- paramName = nameWithProp.substring(2);
1075
- } else {
1076
- const parts = nameWithProp.split(".");
1077
- idName = parts[0];
1078
- paramName = parts[1];
1079
- }
1080
-
1081
- if (useActive && this.scope.currentFrameId !== -1) {
1082
- // If there is some frame selected, then update frame params
1083
- this.scope.frames[this.scope.currentFrameId - 1]
1084
- .parameters.set(paramName, value);
1085
- } else {
1086
- idName = this.scope.currentComponent.instanceName;
1087
-
1088
- // Check if instance exists
1089
- if (this.scope.instances.has(idName)) {
1090
- const component = this.scope.instances.get(idName);
1091
- component.parameters.set(paramName, value);
1092
-
1093
- } else if (this.scope.variables.has(idName)) {
1094
- throw "Not implemented yet!";
1095
- } else {
1096
- throw "Unknown identifier: " + idName;
1097
- }
1098
- }
1099
- }
1100
-
1101
- setCurrentComponentStyle(styles: { [key: string]: number | string }): void {
1102
- // Add onto to the current component styles
1103
- for (const key in styles) {
1104
- this.scope.currentComponent.styles[key] = styles[key];
1105
- }
1106
- }
1107
-
1108
- enterFrame(): number {
1109
- // Frame 0 is the 'base' frame
1110
- const frameId = this.scope.frames.length + 1;
1111
- const frameObject = new Frame(frameId);
1112
- this.scope.frames.push(frameObject);
1113
-
1114
- this.scope.sequence.push([SequenceAction.Frame,
1115
- frameObject, FrameAction.Enter]);
1116
-
1117
- this.scope.currentFrameId = frameId;
1118
- this.scope.setActive(ActiveObject.Frame, frameId);
1119
-
1120
- // TODO: allow frame properties to be set in double dot expressions
1121
- // TODO: also allow frames to be assigned in variables for reuse?
1122
-
1123
- return frameId;
1124
- }
1125
-
1126
- exitFrame(frameId: number): void {
1127
- const frame = this.scope.frames[frameId-1];
1128
- this.scope.sequence.push([SequenceAction.Frame,
1129
- frame, FrameAction.Exit]);
1130
- }
1131
- }
1132
-
1133
- function isWireSegmentsEndAuto(segments:WireSegment[]): boolean {
1134
- if (segments.length > 0){
1135
- if (segments[segments.length -1].value === null){
1136
- return true;
1137
- }
1138
- }
1139
-
1140
- return false;
1141
- }
1142
-
1143
- export function isNetComponent(component: ClassComponent): boolean {
1144
- // Returns true if the component is a net component
1145
- return component.parameters.has(ParamKeys.__is_net);
1146
- }
1147
-
1148
- export function isLabelComponent(component: ClassComponent): boolean {
1149
- return component.parameters.has(ParamKeys.__is_label);
1150
- }
1151
-
1152
- export function getPortSide(pins: Map<number, PinDefinition>, arrangeProps: null | Map<string, number[]>): PortSideItem[] {
1153
- // Takes the arrangeProps and determines how to arrange pins in the symbol.
1154
-
1155
- const result = [];
1156
-
1157
- if (arrangeProps === null) {
1158
-
1159
- let counter = 0;
1160
- for (const [pinId] of pins) {
1161
- result.push({
1162
- pinId,
1163
- side: counter % 2 === 0 ? PortSide.WEST : PortSide.EAST,
1164
- order: counter,
1165
- position: Math.floor(counter/2),
1166
- });
1167
- counter++;
1168
- }
1169
-
1170
- } else {
1171
- let counter = pins.size;
1172
- const existingPinIds = Array.from(pins.keys());
1173
-
1174
- for (const [key, items] of arrangeProps) {
1175
- let useItems;
1176
- if (!Array.isArray(items)){
1177
- useItems = [items];
1178
- } else {
1179
- // Do no mutate original array
1180
- useItems = [...items];
1181
- }
1182
-
1183
- let useSide = PortSide.WEST;
1184
- if (key === 'left') {
1185
- useSide = PortSide.WEST;
1186
- } else if (key === 'right') {
1187
- useSide = PortSide.EAST;
1188
- } else if (key === 'top') {
1189
- useSide = PortSide.NORTH;
1190
- } else if (key === 'bottom') {
1191
- useSide = PortSide.SOUTH;
1192
- }
1193
-
1194
- let position = 0;
1195
-
1196
- useItems.forEach(item => {
1197
- if (typeof item === 'object'){
1198
- if (item.blank){
1199
- position += item.blank;
1200
- }
1201
- }
1202
-
1203
- // Only use the pin if it exists!
1204
- if (existingPinIds.indexOf(item) !== -1) {
1205
- result.push({
1206
- pinId: item,
1207
- side: useSide,
1208
- position,
1209
- order: counter
1210
- });
1211
- counter--;
1212
- position += 1;
1213
- }
1214
- });
1215
- }
1216
- }
1217
-
1218
- return result;
1219
- }
1220
-
1221
- type PortSideItem = {
1222
- pinId: number,
1223
- side: string,
1224
- order: number,
1225
- position: number,
1226
- };
1227
-