/// <summary> /// Read .FUNC statements. /// </summary> /// <param name="subCircuitDefinition">A subcircuit definition.</param> /// <param name="subCircuitContext">A subcircuit reading context.</param> private void ReadFuncControl(SubCircuit subCircuitDefinition, ICircuitContext subCircuitContext) { foreach (Statement statement in subCircuitDefinition.Statements.Where(s => s is Control && ((Control)s).Name.ToLower() == "func")) { subCircuitContext.StatementsReader.Read(statement, subCircuitContext); } }
/// <summary> /// Reads .SUBCKT statements. /// </summary> /// <param name="subCircuitDefinition">A subcircuit definition.</param> /// <param name="subCircuitContext">A subcircuit reading context.</param> private void ReadSubcircuits(SubCircuit subCircuitDefinition, ICircuitContext subCircuitContext) { foreach (Statement statement in subCircuitDefinition.Statements.Where(s => s is SubCircuit)) { subCircuitContext.StatementsReader.Read((SubCircuit)statement, subCircuitContext); } }
public override SpiceSharp.Components.Component Generate(string componentIdentifier, string originalName, string type, ParameterCollection parameters, ICircuitContext context) { SubCircuit subCircuitDefinition = FindSubcircuitDefinition(parameters, context); CircuitContext subCircuitContext = CreateSubcircuitContext(componentIdentifier, originalName, subCircuitDefinition, parameters, context); var ifPreprocessor = new IfPreprocessor(); ifPreprocessor.CaseSettings = subCircuitContext.CaseSensitivity; ifPreprocessor.Validation = new SpiceParserValidationResult() { Reading = context.Result.Validation }; ifPreprocessor.EvaluationContext = subCircuitContext.Evaluator.GetEvaluationContext(); subCircuitDefinition.Statements = ifPreprocessor.Process(subCircuitDefinition.Statements); ReadParamControl(subCircuitDefinition, subCircuitContext); ReadFuncControl(subCircuitDefinition, subCircuitContext); ReadSubcircuits(subCircuitDefinition, subCircuitContext); CreateSubcircuitModels(subCircuitDefinition, subCircuitContext); // TODO: Share models someday between instances of subcircuits CreateSubcircuitComponents(subCircuitDefinition, subCircuitContext); context.Children.Add(subCircuitContext); // null is intentional return(null); }
/// <summary> /// Creates models for subcircuit. /// </summary> /// <param name="subCircuitDefinition">A subcircuit definition.</param> /// <param name="subCircuitContext">A subcircuit reading context.</param> private void CreateSubcircuitModels(SubCircuit subCircuitDefinition, ICircuitContext subCircuitContext) { foreach (Statement statement in subCircuitDefinition.Statements.Where(s => s is Model)) { subCircuitContext.StatementsReader.Read(statement, subCircuitContext); } }
/// <summary> /// Creates components for subcircuit. /// </summary> /// <param name="subCircuitDefinition">A subcircuit definition.</param> /// <param name="subCircuitContext">A subcircuit reading context.</param> private void CreateSubcircuitComponents(SubCircuit subCircuitDefinition, ICircuitContext subCircuitContext) { foreach (Statement statement in subCircuitDefinition.Statements.Where(s => s is Component)) { subCircuitContext.StatementsReader.Read((Component)statement, subCircuitContext); var lastEntity = subCircuitContext.Result.Circuit.Last(); if (lastEntity.ParameterSets.TryGet(out BaseParameters bp)) { bp.Instance = subCircuitContext.InstanceData; } } }
/// <summary> /// Returns new instance of <see cref="SubCircuit"/> /// from the values of children nodes of <see cref="Symbols.Subckt"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="SubCircuit"/>. /// </returns> private SpiceObject CreateSubCircuit(ParseTreeNodeEvaluationValues values) { if (values.Count < 3) { throw new ParseTreeEvaluationException("Error during translating parse tree to Spice Object Model"); } var subCkt = new SubCircuit(values.GetLexem(2), new Statements(), new ParameterCollection(), new SpiceLineInfo(values)); var allParameters = values.GetSpiceObject <ParameterCollection>(3); // Parse nodes and parameters bool mode = true; // true = nodes, false = parameters foreach (var parameter in allParameters) { if (mode) { // After this, only parameters will follow if (parameter is SingleParameter s && s.Image.ToLower() == "params:") { mode = false; } // Parameters have started, so we will keep reading parameters else if (parameter is AssignmentParameter a) { mode = false; subCkt.DefaultParameters.Add(a); } // Still reading nodes else if (parameter is SingleParameter s2) { if (s2 is WordParameter || s2 is IdentifierParameter || s2 is PrefixParameter || s2 is SuffixParameter || int.TryParse(s2.Image, out _)) { subCkt.Pins.Add(s2); } } }
/// <summary> /// Creates subcircuit context. /// </summary> /// <param name="subcircuitFullName">Subcircuit full name.</param> /// <param name="subcircuitName">Subcircuit name.</param> /// <param name="subCircuitDefinition">Subcircuit definition.</param> /// <param name="parameters">Parameters and pins for subcircuit.</param> /// <param name="context">Parent reading context.</param> /// <returns> /// A new instance of reading context. /// </returns> private CircuitContext CreateSubcircuitContext(string subcircuitFullName, string subcircuitName, SubCircuit subCircuitDefinition, ParameterCollection parameters, ICircuitContext context) { int parameterParameters = 0; // setting evaluator var subCktParameters = new List <AssignmentParameter>(); while (true) { if (parameters[parameters.Count - parameterParameters - 1].Image.ToLower() == "params:") { parameterParameters++; } if (!(parameters[parameters.Count - parameterParameters - 1] is AssignmentParameter a)) { break; }
/// <summary> /// Initializes a new instance of the <see cref="SubcircuitNodeNameGenerator"/> class. /// </summary> /// <param name="subcircuitFullName">The fullname of subcircuit.</param> /// <param name="subCircuitName">The name of subcircuit.</param> /// <param name="currentSubCircuit">The current subcircuit.</param> /// <param name="pinInstanceNames">The names of pins.</param> /// <param name="globals">Global pin names.</param> /// <param name="isNodeNameCaseSensitive">Is node name case sensitive.</param> public SubcircuitNodeNameGenerator(string subcircuitFullName, string subCircuitName, SubCircuit currentSubCircuit, List <string> pinInstanceNames, IEnumerable <string> globals, bool isNodeNameCaseSensitive) { RootName = subCircuitName ?? throw new ArgumentNullException(nameof(subCircuitName)); FullName = subcircuitFullName ?? throw new ArgumentNullException(nameof(subcircuitFullName)); SubCircuit = currentSubCircuit ?? throw new ArgumentNullException(nameof(currentSubCircuit)); PinInstanceNames = pinInstanceNames ?? throw new ArgumentNullException(nameof(pinInstanceNames)); if (globals == null) { throw new ArgumentNullException(nameof(globals)); } _pinMap = new Dictionary <string, string>(StringComparerProvider.Get(isNodeNameCaseSensitive)); if (SubCircuit.Pins.Count != PinInstanceNames.Count) { throw new SpiceSharpParserException($"Subcircuit: {subcircuitFullName} has wrong number of nodes"); } for (var i = 0; i < SubCircuit.Pins.Count; i++) { var pinIdentifier = SubCircuit.Pins[i].Image; var pinInstanceIdentifier = PinInstanceNames[i]; _pinMap[pinIdentifier] = pinInstanceIdentifier; } IsNodeNameCaseSensitive = isNodeNameCaseSensitive; InitGlobals(globals); }