circuitscript 0.1.29 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/cjs/BaseVisitor.js +185 -22
  2. package/dist/cjs/RefdesAnnotationVisitor.js +27 -10
  3. package/dist/cjs/antlr/CircuitScriptLexer.js +241 -236
  4. package/dist/cjs/antlr/CircuitScriptParser.js +1197 -901
  5. package/dist/cjs/builtinMethods.js +6 -2
  6. package/dist/cjs/draw_symbols.js +38 -34
  7. package/dist/cjs/environment.js +28 -4
  8. package/dist/cjs/execute.js +195 -125
  9. package/dist/cjs/globals.js +6 -1
  10. package/dist/cjs/graph.js +14 -12
  11. package/dist/cjs/helpers.js +90 -17
  12. package/dist/cjs/layout.js +50 -25
  13. package/dist/cjs/main.js +16 -14
  14. package/dist/cjs/objects/ClassComponent.js +199 -30
  15. package/dist/cjs/objects/ExecutionScope.js +9 -0
  16. package/dist/cjs/objects/types.js +25 -2
  17. package/dist/cjs/parser.js +6 -2
  18. package/dist/cjs/regenerate-tests.js +3 -3
  19. package/dist/cjs/render.js +5 -3
  20. package/dist/cjs/rules-check/no-connect-on-connected-pin.js +9 -8
  21. package/dist/cjs/rules-check/rules.js +7 -2
  22. package/dist/cjs/rules-check/unconnected-pins.js +10 -8
  23. package/dist/cjs/utils.js +2 -1
  24. package/dist/cjs/validate/SymbolTable.js +7 -1
  25. package/dist/cjs/validate/SymbolValidatorVisitor.js +54 -17
  26. package/dist/cjs/visitor.js +299 -238
  27. package/dist/esm/BaseVisitor.js +187 -24
  28. package/dist/esm/RefdesAnnotationVisitor.js +27 -10
  29. package/dist/esm/antlr/CircuitScriptLexer.js +241 -236
  30. package/dist/esm/antlr/CircuitScriptParser.js +1196 -899
  31. package/dist/esm/antlr/CircuitScriptVisitor.js +4 -1
  32. package/dist/esm/builtinMethods.js +7 -3
  33. package/dist/esm/draw_symbols.js +38 -34
  34. package/dist/esm/environment.js +25 -1
  35. package/dist/esm/execute.js +197 -127
  36. package/dist/esm/globals.js +4 -0
  37. package/dist/esm/graph.js +14 -12
  38. package/dist/esm/helpers.js +91 -18
  39. package/dist/esm/layout.js +51 -26
  40. package/dist/esm/main.js +16 -14
  41. package/dist/esm/objects/ClassComponent.js +201 -30
  42. package/dist/esm/objects/ExecutionScope.js +9 -0
  43. package/dist/esm/objects/types.js +33 -1
  44. package/dist/esm/parser.js +6 -2
  45. package/dist/esm/regenerate-tests.js +3 -3
  46. package/dist/esm/render.js +5 -3
  47. package/dist/esm/rules-check/no-connect-on-connected-pin.js +9 -8
  48. package/dist/esm/rules-check/rules.js +7 -2
  49. package/dist/esm/rules-check/unconnected-pins.js +10 -8
  50. package/dist/esm/utils.js +2 -1
  51. package/dist/esm/validate/SymbolTable.js +5 -0
  52. package/dist/esm/validate/SymbolValidatorVisitor.js +53 -16
  53. package/dist/esm/visitor.js +201 -137
  54. package/dist/types/BaseVisitor.d.ts +27 -10
  55. package/dist/types/RefdesAnnotationVisitor.d.ts +2 -0
  56. package/dist/types/antlr/CircuitScriptLexer.d.ts +43 -42
  57. package/dist/types/antlr/CircuitScriptParser.d.ts +102 -58
  58. package/dist/types/antlr/CircuitScriptVisitor.d.ts +8 -2
  59. package/dist/types/environment.d.ts +8 -1
  60. package/dist/types/execute.d.ts +6 -3
  61. package/dist/types/globals.d.ts +4 -0
  62. package/dist/types/graph.d.ts +2 -2
  63. package/dist/types/helpers.d.ts +2 -1
  64. package/dist/types/layout.d.ts +5 -4
  65. package/dist/types/objects/ClassComponent.d.ts +34 -9
  66. package/dist/types/objects/ExecutionScope.d.ts +3 -1
  67. package/dist/types/objects/types.d.ts +40 -3
  68. package/dist/types/validate/SymbolTable.d.ts +1 -0
  69. package/dist/types/validate/SymbolValidatorVisitor.d.ts +6 -6
  70. package/dist/types/visitor.d.ts +10 -2
  71. package/package.json +4 -1
@@ -1,10 +1,10 @@
1
1
  import { BlockTypes, ComponentTypes, Delimiter1, GlobalNames, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide } from './globals.js';
2
- import { ClassComponent, ModuleComponent } from './objects/ClassComponent.js';
2
+ import { ClassComponent, ComponentUnit, ModuleComponent } from './objects/ClassComponent.js';
3
3
  import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.js';
4
4
  import { Net } from './objects/Net.js';
5
5
  import { numeric, NumericValue } from './objects/ParamDefinition.js';
6
6
  import { PinId, PortSide } from './objects/PinDefinition.js';
7
- import { AnyReference, CFunctionEntry, DeclaredReference, Direction, NetTypes } from './objects/types.js';
7
+ import { AnyReference, CFunctionEntry, DeclaredReference, Direction, ImportFunctionHandling, NetTypes } from './objects/types.js';
8
8
  import { Wire } from './objects/Wire.js';
9
9
  import { Frame } from './objects/Frame.js';
10
10
  import { CalculatePinPositions } from './layout.js';
@@ -39,7 +39,7 @@ export class ExecutionContext {
39
39
  this.scope.scopeLevel = scopeLevel;
40
40
  this.setupRoot();
41
41
  this.silent = silent;
42
- this.log('create new execution context', this.namespace, this.name, this.scope.scopeLevel);
42
+ this.log(`create new execution context, namespace: ${this.namespace}, name: ${this.name}, level: ${this.scope.scopeLevel}`);
43
43
  this.parentContext = parent;
44
44
  this.warnings = warnings;
45
45
  }
@@ -65,7 +65,7 @@ export class ExecutionContext {
65
65
  setupRoot() {
66
66
  const componentRoot = ClassComponent.simple(GlobalNames.__root, 1);
67
67
  componentRoot.typeProp = ComponentTypes.net;
68
- componentRoot.displayProp = this.getPointSymbol();
68
+ componentRoot.addDefaultUnit(this.getPointSymbol());
69
69
  this.scope.instances.set(GlobalNames.__root, componentRoot);
70
70
  this.scope.setCurrent(componentRoot);
71
71
  this.scope.componentRoot = componentRoot;
@@ -131,49 +131,13 @@ export class ExecutionContext {
131
131
  }
132
132
  createComponent(instanceName, pins, params, props, isModule = false) {
133
133
  const className = isModule ? ModuleComponent : ClassComponent;
134
+ pins = this.extractPinsFromUnits(props.units);
134
135
  const component = new className(instanceName, pins.length);
135
136
  pins.forEach((pin) => {
136
137
  component.pins.set(pin.id, pin);
137
138
  });
138
- component.displayProp = props.display ?? null;
139
- component.widthProp = props.width ?? null;
140
- component.heightProp = props.height ?? null;
141
139
  component.typeProp = props.type ?? null;
142
140
  component.copyProp = props.copy ?? false;
143
- let useAngle = null;
144
- if (props.angle) {
145
- useAngle = props.angle.toNumber() % 360;
146
- if (useAngle < 0) {
147
- useAngle += 360;
148
- }
149
- }
150
- if (props.display === null && props.arrange === null) {
151
- const tmpArrangeLeft = [];
152
- const tmpArrangeRight = [];
153
- pins.forEach((pin, index) => {
154
- const useArray = (index % 2 === 0) ? tmpArrangeLeft : tmpArrangeRight;
155
- useArray.push(pin.id);
156
- });
157
- const arrangeProp = new Map([
158
- [SymbolPinSide.Left, tmpArrangeLeft],
159
- [SymbolPinSide.Right, tmpArrangeRight]
160
- ]);
161
- props.arrange = arrangeProp;
162
- }
163
- if (props.arrange !== null) {
164
- component.arrangeProps = this.removeArrangePropDuplicates(props.arrange);
165
- const arrangePropPins = this.getArrangePropPins(component.arrangeProps);
166
- pins.forEach(pin => {
167
- if (arrangePropPins.find(id => id.equals(pin.id)) === undefined) {
168
- this.logWarning(`Pin ${pin.id} is not specified in arrange property`);
169
- }
170
- });
171
- }
172
- else {
173
- component.arrangeProps = null;
174
- }
175
- component.angleProp = useAngle ?? 0;
176
- component.followWireOrientationProp = props.followWireOrientation;
177
141
  const paramsMap = new Map();
178
142
  params.forEach((param) => {
179
143
  component.parameters.set(param.paramName, param.paramValue);
@@ -200,27 +164,91 @@ export class ExecutionContext {
200
164
  this.scope.setNet(component, defaultPin, tmpNet);
201
165
  this.log('set net', netName, 'component', component, defaultPin);
202
166
  }
203
- const { pins: pinSides, maxPositions } = getPortSide(component.pins, component.arrangeProps);
204
- component.pinsMaxPositions = maxPositions;
205
- const pinIdKeys = Array.from(component.pins.keys());
206
- pinSides.forEach(({ pinId, side, position }) => {
207
- const matchedPinId = pinIdKeys.find(id => id.equals(pinId));
208
- if (matchedPinId) {
209
- const tmpPin = component.pins.get(matchedPinId);
210
- tmpPin.side = side;
211
- tmpPin.position = position;
212
- }
213
- else {
214
- throw 'Not found!';
215
- }
216
- });
217
167
  this.scope.instances.set(instanceName, component);
218
168
  const pinsOutput = pins.map((pin) => {
219
169
  return pin.id + ':' + pin.name;
220
170
  });
221
171
  this.log('add symbol', instanceName, '[' + pinsOutput.join(', ') + ']');
172
+ component.units = this.generateComponentUnits(props.units, component);
173
+ component.refreshPinUnitMap();
222
174
  return component;
223
175
  }
176
+ extractPinsFromUnits(units) {
177
+ const pins = [];
178
+ units.forEach(([, definition]) => {
179
+ pins.push(...definition.pins);
180
+ });
181
+ return pins;
182
+ }
183
+ generateComponentUnits(units, parent) {
184
+ return units.map(([key, unitDef]) => {
185
+ unitDef = { ...unitDef };
186
+ let useAngle = null;
187
+ const { pins } = unitDef;
188
+ const pinsMap = new Map();
189
+ pins.forEach(pin => {
190
+ pinsMap.set(pin.id, pin);
191
+ });
192
+ if (unitDef.angle) {
193
+ useAngle = unitDef.angle.toNumber() % 360;
194
+ if (useAngle < 0) {
195
+ useAngle += 360;
196
+ }
197
+ }
198
+ if (unitDef.display === null && unitDef.arrange === null) {
199
+ const tmpArrangeLeft = [];
200
+ const tmpArrangeRight = [];
201
+ pins.forEach((pin, index) => {
202
+ const useArray = (index % 2 === 0) ? tmpArrangeLeft : tmpArrangeRight;
203
+ useArray.push(pin.id);
204
+ });
205
+ const arrangeProp = new Map([
206
+ [SymbolPinSide.Left, tmpArrangeLeft],
207
+ [SymbolPinSide.Right, tmpArrangeRight]
208
+ ]);
209
+ unitDef.arrange = arrangeProp;
210
+ }
211
+ if (unitDef.arrange !== null) {
212
+ unitDef.arrange = this.removeArrangePropDuplicates(unitDef.arrange);
213
+ const arrangePropPins = this.getArrangePropPins(unitDef.arrange);
214
+ pins.forEach(pin => {
215
+ if (arrangePropPins.find(id => id.equals(pin.id)) === undefined) {
216
+ this.logWarning(`Pin ${pin.id} is not specified in arrange property`);
217
+ }
218
+ });
219
+ }
220
+ else {
221
+ unitDef.arrange = null;
222
+ }
223
+ unitDef.angle = useAngle ?? 0;
224
+ const { pins: pinSides, maxPositions } = getPortSide(pinsMap, unitDef.arrange);
225
+ const pinIdKeys = Array.from(pinsMap.keys());
226
+ pinSides.forEach(({ pinId, side, position }) => {
227
+ const matchedPinId = pinIdKeys.find(id => id.equals(pinId));
228
+ if (matchedPinId) {
229
+ const tmpPin = pinsMap.get(matchedPinId);
230
+ tmpPin.side = side;
231
+ tmpPin.position = position;
232
+ }
233
+ else {
234
+ throw 'Not found!';
235
+ }
236
+ });
237
+ const componentUnit = new ComponentUnit(key, parent);
238
+ componentUnit.widthProp = unitDef.width;
239
+ componentUnit.heightProp = unitDef.height;
240
+ componentUnit.angleProp = unitDef.angle;
241
+ componentUnit.followWireOrientationProp = unitDef.followWireOrientation;
242
+ componentUnit.pins = pinsMap;
243
+ componentUnit.pinsFlat = pins;
244
+ componentUnit.numPins = unitDef.pins.length;
245
+ componentUnit.pinsMaxPositions = maxPositions;
246
+ componentUnit.displayProp = unitDef.display;
247
+ componentUnit.arrangeProps = unitDef.arrange;
248
+ componentUnit.suffix = unitDef.suffix ?? null;
249
+ return componentUnit;
250
+ });
251
+ }
224
252
  removeArrangePropDuplicates(arrangeProp) {
225
253
  const sides = [
226
254
  SymbolPinSide.Left,
@@ -591,10 +619,11 @@ export class ExecutionContext {
591
619
  getBreakContext() {
592
620
  return this.scope.breakStack[this.scope.breakStack.length - 1];
593
621
  }
594
- createFunction(functionName, __runFunc, source, uniqueId) {
595
- this.scope.functions.set(functionName, new CFunctionEntry(functionName, __runFunc, source, uniqueId));
596
- this.__functionCache.set(functionName, __runFunc);
597
- this.log(`defined new function '${functionName}'`);
622
+ createFunction(namespace, functionName, __runFunc, source, uniqueId) {
623
+ const functionPath = `${namespace}${functionName}`;
624
+ this.scope.functions.set(functionPath, new CFunctionEntry(namespace, functionName, __runFunc, source, uniqueId));
625
+ this.__functionCache.set(functionPath, __runFunc);
626
+ this.log(`defined new function: ${functionPath}`);
598
627
  }
599
628
  hasFunction(functionName) {
600
629
  return this.scope.functions.has(functionName);
@@ -603,32 +632,63 @@ export class ExecutionContext {
603
632
  return this.scope.functions.get(functionName);
604
633
  }
605
634
  resolveVariable(executionStack, idName, trailers = []) {
635
+ this.log('resolve variable name:', idName, 'trailers:', trailers);
606
636
  const reversed = [...executionStack].reverse();
607
637
  for (let i = 0; i < reversed.length; i++) {
608
638
  const context = reversed[i];
609
- if (context.hasFunction(idName)) {
639
+ const functionPath = `${context.namespace}${idName}`;
640
+ if (context.hasFunction(functionPath)) {
610
641
  return new DeclaredReference({
611
642
  found: true,
612
- value: context.getFunction(idName),
643
+ value: context.getFunction(functionPath),
613
644
  type: ReferenceTypes.function,
614
645
  name: idName,
615
646
  });
616
647
  }
617
648
  else {
649
+ const modules = Array.from(context.scope.modules.values());
650
+ for (let j = 0; j < modules.length; j++) {
651
+ const module = modules[j];
652
+ if (module.importHandlingFlag === ImportFunctionHandling.AllMergeIntoNamespace ||
653
+ (module.importHandlingFlag === ImportFunctionHandling.SpecificMergeIntoNamespace
654
+ && module.specifiedImports.indexOf(idName) !== -1)) {
655
+ const moduleContext = module.context;
656
+ const functionPath = `${moduleContext.namespace}${idName}`;
657
+ if (module.context.hasFunction(functionPath)) {
658
+ return new DeclaredReference({
659
+ found: true,
660
+ rootValue: module,
661
+ value: module.context.getFunction(functionPath),
662
+ type: ReferenceTypes.function,
663
+ name: idName,
664
+ trailerIndex: 1,
665
+ trailers: [idName],
666
+ });
667
+ }
668
+ }
669
+ }
670
+ let isModule = false;
671
+ if (context.scope.modules.has(idName)) {
672
+ const module = context.scope.modules.get(idName);
673
+ if (module.importHandlingFlag === ImportFunctionHandling.AllWithNamespace) {
674
+ isModule = true;
675
+ }
676
+ }
618
677
  let isVariable = context.scope.variables.has(idName);
619
678
  let isComponentInstance = context.scope.instances.has(idName);
620
- if (isVariable || isComponentInstance) {
621
- const scopeList = isVariable ? context.scope.variables
622
- : context.scope.instances;
679
+ if (isModule || isVariable || isComponentInstance) {
680
+ const scopeList = isModule ? context.scope.modules :
681
+ (isVariable ? context.scope.variables : context.scope.instances);
623
682
  const useValue = scopeList.get(idName);
624
683
  if (!isComponentInstance && (useValue instanceof ClassComponent)) {
625
684
  isComponentInstance = true;
626
685
  isVariable = false;
627
686
  }
628
- const tmpReference = this.resolveTrailers(isVariable ? ReferenceTypes.variable : ReferenceTypes.instance, useValue, trailers);
687
+ const referenceType = isModule ? ReferenceTypes.module :
688
+ (isVariable ? ReferenceTypes.variable : ReferenceTypes.instance);
689
+ const tmpReference = this.resolveTrailers(referenceType, useValue, trailers);
629
690
  return new DeclaredReference({
630
- type: isVariable ? ReferenceTypes.variable
631
- : ReferenceTypes.instance,
691
+ type: referenceType,
632
692
  found: (tmpReference.value !== undefined),
633
693
  rootValue: tmpReference.rootValue,
634
694
  value: tmpReference.value,
@@ -649,65 +709,63 @@ export class ExecutionContext {
649
709
  if (trailers.length > 0) {
650
710
  rootValue = useValue;
651
711
  const trailersPath = trailers.join(".");
652
- if (type === ReferenceTypes.variable) {
653
- useValue = rootValue;
654
- trailers.forEach(trailerPath => {
655
- useValue = useValue[trailerPath];
656
- });
657
- }
658
- else if (type === ReferenceTypes.instance) {
659
- const tmpComponent = rootValue;
660
- if (tmpComponent.typeProp === ComponentTypes.net) {
661
- const usedNet = this.scope.getNet(tmpComponent, new PinId(1));
662
- if (usedNet) {
663
- const trailerValue = trailers.join(".");
664
- useValue = usedNet.params.get(trailerValue) ?? null;
712
+ switch (type) {
713
+ case ReferenceTypes.variable:
714
+ useValue = rootValue;
715
+ trailers.forEach(trailerPath => {
716
+ useValue = useValue[trailerPath];
717
+ });
718
+ break;
719
+ case ReferenceTypes.instance: {
720
+ const tmpComponent = rootValue;
721
+ if (tmpComponent.typeProp === ComponentTypes.net) {
722
+ const usedNet = this.scope.getNet(tmpComponent, new PinId(1));
723
+ if (usedNet) {
724
+ const trailerValue = trailers.join(".");
725
+ useValue = usedNet.params.get(trailerValue) ?? null;
726
+ }
727
+ }
728
+ else {
729
+ useValue = rootValue
730
+ .parameters.get(trailersPath);
665
731
  }
732
+ break;
666
733
  }
667
- else {
668
- useValue = rootValue
669
- .parameters.get(trailersPath);
734
+ case ReferenceTypes.module: {
735
+ const funcName = trailers[0];
736
+ const module = rootValue;
737
+ const functionPath = `${module.moduleNamespace}${funcName}`;
738
+ if (module.context.hasFunction(functionPath)) {
739
+ const foundFunc = module.context.getFunction(functionPath);
740
+ return new AnyReference({
741
+ found: true,
742
+ type: ReferenceTypes.function,
743
+ rootValue,
744
+ trailers,
745
+ trailerIndex: trailers.length,
746
+ value: foundFunc,
747
+ });
748
+ }
749
+ break;
670
750
  }
671
751
  }
672
752
  }
673
753
  let found = false;
674
- if (rootValue !== undefined && useValue !== undefined) {
754
+ if (useValue !== undefined) {
675
755
  found = true;
676
756
  }
677
757
  return new AnyReference({
678
758
  found,
679
- type: type,
759
+ type,
680
760
  rootValue,
681
761
  trailers,
682
762
  trailerIndex: trailers.length,
683
763
  value: useValue,
684
764
  });
685
765
  }
686
- callFunction(functionName, functionParams, executionStack, netNamespace) {
687
- let __runFunc = null;
688
- if (!this.__functionCache.has(functionName)) {
689
- if (this.hasFunction(functionName)) {
690
- const entry = this.getFunction(functionName);
691
- __runFunc = entry.execute;
692
- }
693
- if (__runFunc === null) {
694
- this.log(`searching for function ${functionName} in upper context`);
695
- const tmpResolveResult = this.resolveVariable(executionStack, functionName);
696
- if (tmpResolveResult.found) {
697
- const entry = tmpResolveResult.value;
698
- __runFunc = entry.execute;
699
- }
700
- else {
701
- throw `Invalid function ${functionName}`;
702
- }
703
- }
704
- this.log('save function to cache:', functionName);
705
- this.__functionCache.set(functionName, __runFunc);
706
- }
707
- else {
708
- this.log('found function in cache:', functionName);
709
- __runFunc = this.__functionCache.get(functionName);
710
- }
766
+ callFunction(functionReference, functionParams, executionStack, netNamespace) {
767
+ const functionEntry = functionReference.value;
768
+ const { name: functionName, execute: __runFunc } = functionEntry;
711
769
  if (__runFunc !== null) {
712
770
  let functionCallIndex = -1;
713
771
  if (!this.scope.functionCounter.has(__runFunc)) {
@@ -725,6 +783,7 @@ export class ExecutionContext {
725
783
  return functionResult;
726
784
  }
727
785
  else {
786
+ this.log(`Invalid function: ${functionName}`);
728
787
  throw `Invalid function '${functionName}'`;
729
788
  }
730
789
  }
@@ -735,7 +794,7 @@ export class ExecutionContext {
735
794
  const tmpNets = childScope.getNets();
736
795
  const mergedInstances = [];
737
796
  for (const [instanceName, component] of tmpInstances) {
738
- const newInstanceName = `${namespace}.${instanceName}`;
797
+ const newInstanceName = namespace !== "" ? `${namespace}.${instanceName}` : instanceName;
739
798
  component.instanceName = newInstanceName;
740
799
  if (component === childScope.componentRoot) {
741
800
  continue;
@@ -855,9 +914,10 @@ export class ExecutionContext {
855
914
  this.scope.setActive(ActiveObject.Wire, wireId);
856
915
  this.scope.sequence.push([SequenceAction.Wire, wireId, tmp, newWire]);
857
916
  this.scope.currentComponent.pinWires.set(this.scope.currentPin, tmp);
858
- if (!this.scope.currentComponent.didSetWireOrientationAngle) {
917
+ const currentUnit = this.scope.currentComponent.getUnitForPin(this.scope.currentPin);
918
+ if (!currentUnit.didSetWireOrientationAngle) {
859
919
  this.applyComponentAngleFromWire(this.scope.currentComponent, this.scope.currentPin, true);
860
- this.scope.currentComponent.didSetWireOrientationAngle = true;
920
+ currentUnit.didSetWireOrientationAngle = true;
861
921
  }
862
922
  return newWire;
863
923
  }
@@ -867,7 +927,6 @@ export class ExecutionContext {
867
927
  }
868
928
  const useName = userDefined ? 'point.' + pointId : pointId;
869
929
  const componentPoint = ClassComponent.simple(useName, 1);
870
- componentPoint.displayProp = this.getPointSymbol(useName);
871
930
  componentPoint.typeProp = ComponentTypes.net;
872
931
  let usePointLinkComponent = null;
873
932
  if (this.scope.currentComponent._pointLinkComponent) {
@@ -877,6 +936,7 @@ export class ExecutionContext {
877
936
  usePointLinkComponent = this.scope.currentComponent;
878
937
  }
879
938
  componentPoint._pointLinkComponent = usePointLinkComponent;
939
+ componentPoint.addDefaultUnit(this.getPointSymbol(useName));
880
940
  this.scope.instances.set(pointId, componentPoint);
881
941
  this.toComponent(componentPoint, 1, { addSequence: true });
882
942
  return this.getCurrentPoint();
@@ -950,6 +1010,15 @@ export class ExecutionContext {
950
1010
  if (this.scope.instances.has(idName)) {
951
1011
  const component = this.scope.instances.get(idName);
952
1012
  component.setParam(paramName, value);
1013
+ const unitModifiers = [
1014
+ ParamKeys.angle,
1015
+ ParamKeys.flip,
1016
+ ParamKeys.flipX,
1017
+ ParamKeys.flipY,
1018
+ ];
1019
+ if (unitModifiers.indexOf(paramName) !== -1) {
1020
+ component.getUnit().setParam(paramName, value);
1021
+ }
953
1022
  }
954
1023
  else if (this.scope.variables.has(idName)) {
955
1024
  throw "Not implemented yet!";
@@ -960,17 +1029,18 @@ export class ExecutionContext {
960
1029
  }
961
1030
  }
962
1031
  applyComponentAngleFromWire(component, pin, opposite = false) {
1032
+ const targetUnit = component.getUnitForPin(pin);
963
1033
  if (this.componentAngleFollowsWire
964
- && component.followWireOrientationProp
965
- && component.useWireOrientationAngle
966
- && !component.didSetWireOrientationAngle
1034
+ && targetUnit.followWireOrientationProp
1035
+ && targetUnit.useWireOrientationAngle
1036
+ && !targetUnit.didSetWireOrientationAngle
967
1037
  && this.scope.currentWireId !== -1) {
968
1038
  const currentWire = this.scope.wires[this.scope.currentWireId];
969
1039
  let useSegment = currentWire.path[currentWire.path.length - 1];
970
1040
  if (opposite) {
971
1041
  useSegment = currentWire.path[0];
972
1042
  }
973
- const pinPositions = CalculatePinPositions(component);
1043
+ const pinPositions = CalculatePinPositions(targetUnit);
974
1044
  if (pinPositions.has(pin)) {
975
1045
  const connectedPinPos = pinPositions.get(pin);
976
1046
  let targetAngle = null;
@@ -1008,27 +1078,27 @@ export class ExecutionContext {
1008
1078
  if (targetAngle === null) {
1009
1079
  return;
1010
1080
  }
1011
- this.log('set component angle from wire, target angle:', targetAngle, ', component angle:', component.angleProp, 'pin angle:', connectedPinPos.angle);
1081
+ this.log('set component unit angle from wire, target angle:', targetAngle, ', component unit angle:', targetUnit.angleProp, 'pin angle:', connectedPinPos.angle);
1012
1082
  let useAngle = (targetAngle - connectedPinPos.angle.toNumber()) % 360;
1013
1083
  if (useAngle < 0) {
1014
1084
  useAngle += 360;
1015
1085
  }
1016
1086
  if (useAngle === 90) {
1017
- component.setParam(ParamKeys.angle, numeric(90));
1087
+ targetUnit.setParam(ParamKeys.angle, numeric(90));
1018
1088
  }
1019
1089
  else if (useAngle === 180) {
1020
- if (component.angleProp === 0 || component.angleProp === 180) {
1021
- component.setParam(ParamKeys.flipX, 1);
1090
+ if (targetUnit.angleProp === 0 || targetUnit.angleProp === 180) {
1091
+ targetUnit.setParam(ParamKeys.flipX, numeric(1));
1022
1092
  }
1023
- else if (component.angleProp === 90 || component.angleProp === 270) {
1024
- component.setParam(ParamKeys.flipY, 1);
1093
+ else if (targetUnit.angleProp === 90 || targetUnit.angleProp === 270) {
1094
+ targetUnit.setParam(ParamKeys.flipY, numeric(1));
1025
1095
  }
1026
1096
  }
1027
1097
  else if (useAngle === 270) {
1028
- component.setParam(ParamKeys.angle, numeric(270));
1098
+ targetUnit.setParam(ParamKeys.angle, numeric(270));
1029
1099
  }
1030
- component.wireOrientationAngle = useAngle;
1031
- component.didSetWireOrientationAngle = true;
1100
+ targetUnit.wireOrientationAngle = useAngle;
1101
+ targetUnit.didSetWireOrientationAngle = true;
1032
1102
  }
1033
1103
  }
1034
1104
  }
@@ -2,6 +2,8 @@ import { numeric } from "./objects/ParamDefinition.js";
2
2
  export const TOOL_VERSION = '0.1.5';
3
3
  export const Delimiter1 = '-';
4
4
  export const DoubleDelimiter1 = `${Delimiter1}${Delimiter1}`;
5
+ export const BaseNamespace = `${DoubleDelimiter1}.`;
6
+ export const RefdesFileSuffix = '.refdes.json';
5
7
  export var GlobalNames;
6
8
  (function (GlobalNames) {
7
9
  GlobalNames["__root"] = "--root";
@@ -93,6 +95,7 @@ export var ReferenceTypes;
93
95
  ReferenceTypes["variable"] = "variable";
94
96
  ReferenceTypes["instance"] = "instance";
95
97
  ReferenceTypes["pinType"] = "pinType";
98
+ ReferenceTypes["module"] = "module";
96
99
  ReferenceTypes["unknown"] = "unknown";
97
100
  })(ReferenceTypes || (ReferenceTypes = {}));
98
101
  export var BlockTypes;
@@ -126,3 +129,4 @@ export const RenderFlags = {
126
129
  };
127
130
  export const SymbolValidatorContext = '_sym';
128
131
  export const TrailerArrayIndex = 'index';
132
+ export const DefaultComponentUnit = '__default';
package/dist/esm/graph.js CHANGED
@@ -35,32 +35,33 @@ export class NetGraph {
35
35
  case SequenceAction.At: {
36
36
  this.print(...sequenceStep);
37
37
  const [, component, pin] = sequenceStep;
38
- const tmpInstanceName = component.instanceName;
38
+ const componentUnit = component.getUnitForPin(pin);
39
+ const tmpInstanceName = componentUnit.instanceName;
39
40
  if (action === SequenceAction.At) {
40
41
  previousNode = null;
41
42
  previousPin = null;
42
43
  }
43
44
  if (!graph.hasNode(tmpInstanceName)) {
44
45
  this.print('create instance', tmpInstanceName);
45
- const { displayProp = null } = component;
46
+ const { displayProp = null } = componentUnit;
46
47
  let tmpSymbol;
47
48
  if (displayProp instanceof SymbolDrawing) {
48
49
  tmpSymbol = new SymbolPlaceholder(displayProp);
49
50
  tmpSymbol.drawing.logger = this.logger;
50
51
  }
51
52
  else {
52
- const symbolPinDefinitions = generateLayoutPinDefinition(component);
53
+ const symbolPinDefinitions = generateLayoutPinDefinition(componentUnit);
53
54
  if (component.typeProp === ComponentTypes.module) {
54
- tmpSymbol = new SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
55
+ tmpSymbol = new SymbolCustomModule(symbolPinDefinitions, componentUnit.pinsMaxPositions);
55
56
  }
56
57
  else {
57
- tmpSymbol = new SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
58
+ tmpSymbol = new SymbolCustom(symbolPinDefinitions, componentUnit.pinsMaxPositions);
58
59
  }
59
60
  }
60
- applyComponentParamsToSymbol(component, tmpSymbol);
61
+ applyComponentParamsToSymbol(componentUnit, tmpSymbol);
61
62
  tmpSymbol.refreshDrawing();
62
63
  const { width: useWidth, height: useHeight } = tmpSymbol.size();
63
- tmpComponent = new RenderComponent(component, useWidth, useHeight);
64
+ tmpComponent = new RenderComponent(component, componentUnit.unitId, useWidth, useHeight);
64
65
  tmpComponent.symbol = tmpSymbol;
65
66
  graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, index]);
66
67
  let useFrame = frameStack[frameStack.length - 1];
@@ -88,7 +89,8 @@ export class NetGraph {
88
89
  const [prevNodeType, prevNodeItem] = graph.node(previousNode);
89
90
  if (prevNodeType === RenderItemType.Component) {
90
91
  const matchingItem = nets.find(([comp, pin]) => {
91
- return comp.instanceName === previousNode
92
+ const unit = comp.getUnitForPin(pin);
93
+ return unit.instanceName === previousNode
92
94
  && pin.equals(previousPin);
93
95
  });
94
96
  if (matchingItem !== undefined) {
@@ -321,11 +323,11 @@ function makeEdgeValue(instanceName1, instancePin1, instanceName2, instancePin2,
321
323
  export function getWireName(wireId) {
322
324
  return 'wire:' + wireId;
323
325
  }
324
- export function generateLayoutPinDefinition(component) {
325
- const pins = component.pins;
326
+ export function generateLayoutPinDefinition(componentUnit) {
327
+ const pins = componentUnit.pins;
326
328
  const symbolPinDefinitions = [];
327
329
  const existingPinIds = Array.from(pins.keys());
328
- const arrangeProps = component.arrangeProps ?? [];
330
+ const arrangeProps = componentUnit.arrangeProps ?? [];
329
331
  const addedPins = [];
330
332
  for (const [key, items] of arrangeProps) {
331
333
  let useItems;
@@ -354,7 +356,7 @@ export function generateLayoutPinDefinition(component) {
354
356
  return addedPins.find(id => id.equals(pinId)) === undefined;
355
357
  });
356
358
  if (unplacedPins.length > 0) {
357
- component._unplacedPins = unplacedPins;
359
+ componentUnit._unplacedPins = unplacedPins;
358
360
  console.warn("Warning: There are unplaced pins: " + unplacedPins);
359
361
  }
360
362
  return symbolPinDefinitions;