/// <summary> /// Parse from a <see cref="Stream"/> /// </summary> /// <param name="stream">The stream</param> public void Parse(Stream stream) { if (Netlist == null) { throw new ParseException("No netlist specified"); } SpiceSharpParser parser = new SpiceSharpParser(stream); // The order of reading StatementType[] order = new StatementType[] { StatementType.Subcircuit, StatementType.Control, StatementType.Model, StatementType.Component }; // Parse the netlist and read the statements StatementsToken main = parser.ParseNetlist(Netlist); for (int i = 0; i < order.Length; i++) { foreach (var s in main.Statements(order[i])) { Netlist.Readers.Read(s, Netlist); } } }
/// <summary> /// Constructor /// </summary> /// <param name="name">Name of the subcircuit definition</param> /// <param name="body">The statements</param> public SubcircuitDefinition(CircuitIdentifier name, StatementsToken body) { Name = name ?? throw new ParseException("Invalid subcircuit identifier"); Body = body ?? throw new ParseException("Invalid subcircuit body"); }
/// <summary> /// Read subcircuit definitions /// </summary> /// <param name="name">Name</param> /// <param name="parameters">Parameters</param> /// <param name="netlist">Netlist</param> /// <returns></returns> public override bool Read(string type, Statement st, Netlist netlist) { if (st.Parameters.Count < 2) { throw new ParseException(st.Name, "Subcircuit name expected", false); } // Create the identifier of the subcircuit definition CircuitIdentifier name = new CircuitIdentifier(st.Parameters[0].image); if (netlist.Path.DefinitionPath != null) { name = netlist.Path.DefinitionPath.Grow(name); } // Extract the subcircuit definition statements StatementsToken body = (StatementsToken)st.Parameters[st.Parameters.Count - 1]; SubcircuitDefinition definition = new SubcircuitDefinition(name, body); // Parse nodes and parameters bool mode = true; // true = nodes, false = parameters for (int i = 1; i < st.Parameters.Count - 1; i++) { if (mode) { // After this, only parameters will follow if (st.Parameters[i].image.ToLower() == "params:") { mode = false; } // Parameters have started, so we will keep reading parameters else if (st.Parameters[i].kind == ASSIGNMENT) { mode = false; AssignmentToken at = st.Parameters[i] as AssignmentToken; definition.Defaults.Add(new CircuitIdentifier(at.Name.image), at.Value); } // Still reading nodes else if (ReaderExtension.IsNode(st.Parameters[i])) { definition.Pins.Add(new CircuitIdentifier(st.Parameters[i].image)); } } else if (st.Parameters[i].kind == ASSIGNMENT) { AssignmentToken at = st.Parameters[i] as AssignmentToken; definition.Defaults.Add(new CircuitIdentifier(at.Name.image), at.Value); } } // Create a new subcircuit path SubcircuitPath orig = netlist.Path; netlist.Path = new SubcircuitPath(orig, definition); foreach (var s in definition.Body.Statements(StatementType.Subcircuit)) { netlist.Readers.Read(s, netlist); } // Restore netlist.Path = orig; // Return values netlist.Definitions.Add(definition.Name, definition); Generated = definition; return(true); }