Beispiel #1
0
        private Ast AssignmentExpression()
        {
            Func <Ast> declaration = () =>
            {
                if (!IsType(_tokenStream.Current))
                {
                    return(null);
                }

                Ast             decl       = Declaration();
                AssignmentToken assignment = _tokenStream.Take <AssignmentToken>();
                Ast             expr       = Expression();

                return(new BinaryExpression(decl, assignment, expr));
            };

            Func <Ast> reAssignment = () =>
            {
                if (!_tokenStream.IsMatch <IdentifierToken>())
                {
                    return(null);
                }

                Variable        var        = new Variable(_tokenStream.Take <IdentifierToken>());
                AssignmentToken assignment = _tokenStream.Take <AssignmentToken>();
                Ast             expr       = Expression();

                return(new BinaryExpression(var, assignment, expr));
            };

            return
                (_tokenStream.Capture(declaration) ??
                 _tokenStream.Capture(reAssignment) ??
                 _tokenStream.Capture(LogicalOrExpression));
        }
 public override SemanticPayload Visit(AssignmentToken token, SemanticPayload payload)
 {
     return(Visit(token.Item2, payload)
            .Combine(new SemanticPayload {
         Contour = new Contour <None>(token.Item1, None.New())
     }));
 }
Beispiel #3
0
        /// <summary>
        /// Read the parameter
        /// </summary>
        /// <param name="st"></param>
        /// <param name="netlist"></param>
        /// <returns></returns>
        public override bool Read(string type, Statement st, Netlist netlist)
        {
            // Read all assignments
            for (int i = 0; i < st.Parameters.Count; i++)
            {
                switch (st.Parameters[i].kind)
                {
                case ASSIGNMENT:
                    AssignmentToken at = st.Parameters[i] as AssignmentToken;
                    switch (at.Name.kind)
                    {
                    case WORD:
                        netlist.Path.Parameters.Add(new CircuitIdentifier(at.Name.image), netlist.ParseDouble(at.Value));
                        break;

                    default:
                        throw new ParseException(at.Name, "Parameter expected");
                    }
                    break;

                default:
                    throw new ParseException(st.Parameters[i], "Assignment expected");
                }
            }

            Generated = null;
            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Generate a capacitor
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="parameters">Parameters</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        protected ICircuitObject GenerateCap(CircuitIdentifier name, List <Token> parameters, Netlist netlist)
        {
            Capacitor cap = new Capacitor(name);

            cap.ReadNodes(netlist.Path, parameters);

            // Search for a parameter IC, which is common for both types of capacitors
            for (int i = 3; i < parameters.Count; i++)
            {
                if (parameters[i].kind == ASSIGNMENT)
                {
                    AssignmentToken at = parameters[i] as AssignmentToken;
                    if (at.Name.image.ToLower() == "ic")
                    {
                        double ic = netlist.ParseDouble(at.Value);
                        cap.CAPinitCond.Set(ic);
                        parameters.RemoveAt(i);
                        break;
                    }
                }
            }

            // The rest is just dependent on the number of parameters
            if (parameters.Count == 3)
            {
                cap.CAPcapac.Set(netlist.ParseDouble(parameters[2]));
            }
            else
            {
                cap.SetModel(netlist.FindModel <CapacitorModel>(parameters[2]));
                switch (parameters[2].kind)
                {
                case WORD:
                case IDENTIFIER:
                    cap.SetModel(netlist.Path.FindModel <CapacitorModel>(netlist.Circuit.Objects, new CircuitIdentifier(parameters[2].image)));
                    break;

                default:
                    throw new ParseException(parameters[2], "Model name expected");
                }
                netlist.ReadParameters(cap, parameters, 2);
                if (!cap.CAPlength.Given)
                {
                    throw new ParseException(parameters[1], "L needs to be specified", false);
                }
            }

            return(cap);
        }
 protected T Visit(IToken token, T state = default)
 {
     return(token switch
     {
         AddToken addToken => Visit(addToken, state),
         SubtractToken subtractToken => Visit(subtractToken, state),
         MultiplyToken multiplyToken => Visit(multiplyToken, state),
         DivideToken divideToken => Visit(divideToken, state),
         NegateToken negateToken => Visit(negateToken, state),
         NumberToken numberToken => Visit(numberToken, state),
         FactorialToken factorialToken => Visit(factorialToken, state),
         PowerToken powerToken => Visit(powerToken, state),
         VariableToken variableToken => Visit(variableToken, state),
         AssignmentToken assignmentToken => Visit(assignmentToken, state),
         _ => throw new ArgumentOutOfRangeException(nameof(token))
     });
Beispiel #6
0
        /// <summary>
        /// Read
        /// </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)
        {
            // Only assignments are possible
            for (int i = 0; i < st.Parameters.Count; i++)
            {
                switch (st.Parameters[i].kind)
                {
                case ASSIGNMENT:
                    AssignmentToken at = st.Parameters[i] as AssignmentToken;
                    switch (at.Name.kind)
                    {
                    case BRACKET:
                        BracketToken bt = at.Name as BracketToken;
                        if (bt.Name.image.ToLower() == "v" && bt.Parameters.Length == 1 && ReaderExtension.IsNode(bt.Parameters[0]))
                        {
                            netlist.Circuit.Nodes.Nodeset.Add(new CircuitIdentifier(bt.Parameters[0].image), netlist.ParseDouble(at.Value));
                        }
                        else
                        {
                            throw new ParseException(st.Parameters[i], "Invalid format, v(<node>)=<ic> expected");
                        }
                        break;

                    default:
                        if (ReaderExtension.IsNode(at.Name))
                        {
                            netlist.Circuit.Nodes.Nodeset.Add(new CircuitIdentifier(at.Name.image), netlist.ParseDouble(at.Value));
                        }
                        else
                        {
                            throw new ParseException(st.Parameters[i], "Invalid format, <node>=<ic> expected");
                        }
                        break;
                    }
                    break;
                }
            }
            return(true);
        }
Beispiel #7
0
        /// <summary>
        /// Read named parameters for a Parameterized object
        /// </summary>
        /// <param name="obj">The parameterized object</param>
        /// <param name="parameters">The parameters</param>
        /// <param name="start">The starting index</param>
        public static void ReadParameters(this Netlist netlist, IParameterized obj, List <Token> parameters, int start = 0)
        {
            for (int i = start; i < parameters.Count; i++)
            {
                if (parameters[i].kind == TokenConstants.ASSIGNMENT)
                {
                    AssignmentToken at = parameters[i] as AssignmentToken;
                    string          pname;
                    if (at.Name.kind == WORD)
                    {
                        pname = at.Name.image.ToLower();
                    }
                    else
                    {
                        throw new ParseException(parameters[i], "Invalid assignment");
                    }
                    switch (at.Value.kind)
                    {
                    case VALUE:
                        obj.Set(pname, netlist.Readers.ParseDouble(at.Value.image.ToLower()));
                        break;

                    case EXPRESSION:
                        obj.Set(pname, netlist.Readers.ParseDouble(at.Value.image.Substring(1, at.Value.image.Length - 2).ToLower()));
                        break;

                    case WORD:
                    case STRING:
                        obj.Set(pname, netlist.ParseString(at.Value));
                        break;

                    default:
                        throw new ParseException(parameters[i], "Invalid assignment");
                    }
                }
            }
        }
 public virtual T Visit(AssignmentToken token, T state = default)
 {
     return(Visit(token.Item2, state ?? new T()));
 }
Beispiel #9
0
        /// <summary>
        /// Read
        /// </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)
        {
            // Read all options
            for (int i = 0; i < st.Parameters.Count; i++)
            {
                switch (st.Parameters[i].kind)
                {
                case ASSIGNMENT:
                    AssignmentToken at  = st.Parameters[i] as AssignmentToken;
                    string          key = at.Name.image.ToLower();
                    switch (key)
                    {
                    case "abstol": SimulationConfiguration.Default.AbsTol = netlist.ParseDouble(at.Value); break;

                    case "reltol": SimulationConfiguration.Default.RelTol = netlist.ParseDouble(at.Value); break;

                    case "gmin": SimulationConfiguration.Default.Gmin = netlist.ParseDouble(at.Value); break;

                    case "itl1": SimulationConfiguration.Default.DcMaxIterations = (int)Math.Round(netlist.ParseDouble(at.Value)); break;

                    case "itl2": SimulationConfiguration.Default.SweepMaxIterations = (int)Math.Round(netlist.ParseDouble(at.Value)); break;

                    case "itl4": SimulationConfiguration.Default.TranMaxIterations = (int)Math.Round(netlist.ParseDouble(at.Value)); break;

                    case "temp": netlist.Circuit.State.Temperature = netlist.ParseDouble(at.Value) + Circuit.CONSTCtoK; break;

                    case "tnom": netlist.Circuit.State.NominalTemperature = netlist.ParseDouble(at.Value) + Circuit.CONSTCtoK; break;

                    case "method":
                        switch (at.Value.image.ToLower())
                        {
                        case "trap":
                        case "trapezoidal":
                            SimulationConfiguration.Default.Method = new IntegrationMethods.Trapezoidal();
                            break;
                        }
                        break;

                    default:
                        throw new ParseException(st.Parameters[i], "Unrecognized option");
                    }
                    break;

                case WORD:
                    key = st.Parameters[i].image.ToLower();
                    switch (key)
                    {
                    case "keepopinfo": SimulationConfiguration.Default.KeepOpInfo = true; break;

                    default:
                        throw new ParseException(st.Parameters[i], "Unrecognized option");
                    }
                    break;

                default:
                    throw new ParseException(st.Parameters[i], "Unrecognized option");
                }
            }

            return(true);
        }
Beispiel #10
0
        /// <summary>
        /// Generate a diode
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="parameters">Parameters</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        protected override ICircuitObject Generate(string type, CircuitIdentifier name, List <Token> parameters, Netlist netlist)
        {
            Diode dio = new Diode(name);

            dio.ReadNodes(netlist.Path, parameters);

            if (parameters.Count < 3)
            {
                throw new ParseException(parameters[1], "Model expected", false);
            }
            dio.SetModel(netlist.FindModel <DiodeModel>(parameters[2]));

            // Read the rest of the parameters
            for (int i = 3; i < parameters.Count; i++)
            {
                switch (parameters[i].kind)
                {
                case WORD:
                    switch (parameters[i].image.ToLower())
                    {
                    case "on":
                        dio.DIOoff = false;
                        break;

                    case "off":
                        dio.DIOoff = true;
                        break;

                    default:
                        throw new ParseException(parameters[i], "ON or OFF expected");
                    }
                    break;

                case ASSIGNMENT:
                    AssignmentToken at = parameters[i] as AssignmentToken;
                    if (at.Name.image.ToLower() == "ic")
                    {
                        dio.DIOinitCond = netlist.ParseDouble(at.Value);
                    }
                    else
                    {
                        throw new ParseException(parameters[i], "IC expected");
                    }
                    break;

                case VALUE:
                case EXPRESSION:
                    if (!dio.DIOarea.Given)
                    {
                        dio.DIOarea.Set(netlist.ParseDouble(parameters[i]));
                    }
                    else if (!dio.DIOtemp.Given)
                    {
                        dio.DIO_TEMP = netlist.ParseDouble(parameters[i]);
                    }
                    else
                    {
                        throw new ParseException(parameters[i], "Invalid parameter");
                    }
                    break;

                default:
                    throw new ParseException(parameters[i], "Unrecognized parameter");
                }
            }

            return(dio);
        }
 public override CodeGenPayload Visit(AssignmentToken token, CodeGenPayload state = default)
 {
     return(state?.Combine(new CodeGenPayload {
         Contour = new Contour <CodeGenPayload>(token.Item1, Visit(token.Item2, state))
     }));
 }
        /// <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);
        }
Beispiel #13
0
        /// <summary>
        /// Read a transistor model
        /// </summary>
        /// <param name="type">Type</param>
        /// <param name="st">Statement</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        public override bool Read(string type, Statement st, Netlist netlist)
        {
            // Errors
            switch (st.Parameters.Count)
            {
            case 0: throw new ParseException(st.Name, "Model name and type expected", false);
            }

            // The model depends on the model level, find the model statement
            int level = 0; string version = null;
            int lindex = -1, vindex = -1;

            for (int i = 0; i < st.Parameters.Count; i++)
            {
                if (st.Parameters[i].kind == ASSIGNMENT)
                {
                    AssignmentToken at = st.Parameters[i] as AssignmentToken;
                    if (at.Name.image.ToLower() == "level")
                    {
                        lindex = i;
                        level  = (int)Math.Round(netlist.ParseDouble(at.Value));
                    }
                    if (at.Name.image.ToLower() == "version")
                    {
                        vindex  = i;
                        version = at.Value.image.ToLower();
                    }
                    if (vindex >= 0 && lindex >= 0)
                    {
                        break;
                    }
                }
            }
            if (lindex >= 0)
            {
                st.Parameters.RemoveAt(lindex);
            }
            if (vindex >= 0)
            {
                st.Parameters.RemoveAt(vindex < lindex ? vindex : vindex - 1);
            }

            // Generate the model
            ICircuitObject model = null;

            if (Levels.ContainsKey(level))
            {
                model = Levels[level].Invoke(new CircuitIdentifier(st.Name.image), type, version);
            }
            else
            {
                throw new ParseException(st.Name, $"Unknown mosfet model level {level}");
            }

            // Read all the parameters
            netlist.ReadParameters((IParameterized)model, st.Parameters);

            // Output
            netlist.Circuit.Objects.Add(model);
            Generated = model;
            return(true);
        }
Beispiel #14
0
        /// <summary>
        /// Read
        /// </summary>
        /// <param name="type">Type</param>
        /// <param name="st">Statement</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        public override bool Read(string type, Statement st, Netlist netlist)
        {
            // Initialize
            List <CircuitIdentifier> instancepins = new List <CircuitIdentifier>();
            Dictionary <CircuitIdentifier, Token> instanceparameters = new Dictionary <CircuitIdentifier, Token>();
            CircuitIdentifier definition = null;

            // Get the name
            CircuitIdentifier name;

            if (netlist.Path.InstancePath != null)
            {
                name = netlist.Path.InstancePath.Grow(st.Name.image);
            }
            else
            {
                name = new CircuitIdentifier(st.Name.image);
            }

            // Format: <NAME> <NODES>* <SUBCKT> <PAR1>=<VAL1> ...
            // Or: <NAME> <NODES>* <SUBCKT> params: <PAR1>=<VAL1> ...
            bool mode = true; // true = nodes, false = parameters

            for (int i = 0; i < st.Parameters.Count; i++)
            {
                // Reading nodes
                if (mode)
                {
                    if (ReaderExtension.IsNode(st.Parameters[i]))
                    {
                        instancepins.Add(definition = new CircuitIdentifier(st.Parameters[i].image));
                    }
                    else
                    {
                        instancepins.RemoveAt(instancepins.Count - 1);
                        mode = false;
                    }
                }

                // Reading parameters
                // Don't use ELSE! We still need to read the last parameter
                if (!mode)
                {
                    if (st.Parameters[i].kind == ASSIGNMENT)
                    {
                        AssignmentToken at = st.Parameters[i] as AssignmentToken;
                        switch (at.Name.kind)
                        {
                        case WORD:
                        case IDENTIFIER:
                            instanceparameters.Add(new CircuitIdentifier(at.Name.image), at.Value);
                            break;

                        default:
                            throw new ParseException(at.Name, "Parameter name expected");
                        }
                    }
                }
            }

            // If there are only node-like tokens, then the last one is the definition by default
            if (mode)
            {
                instancepins.RemoveAt(instancepins.Count - 1);
            }

            // Modify the instancepins to be local or use the nodemap
            for (int i = 0; i < instancepins.Count; i++)
            {
                if (netlist.Path.NodeMap.TryGetValue(instancepins[i], out CircuitIdentifier node))
                {
                    instancepins[i] = node;
                }
                else if (netlist.Path.InstancePath != null)
                {
                    instancepins[i] = netlist.Path.InstancePath.Grow(instancepins[i].Name);
                }
            }

            // Find the subcircuit definition
            if (netlist.Path.DefinitionPath != null)
            {
                definition = netlist.Path.DefinitionPath.Grow(definition);
            }
            SubcircuitDefinition subcktdef = netlist.Path.FindDefinition(netlist.Definitions, definition) ??
                                             throw new ParseException(st.Parameters[st.Parameters.Count - 1], "Cannot find subcircuit definition");
            Subcircuit subckt = new Subcircuit(subcktdef, name, instancepins, instanceparameters);

            SubcircuitPath orig = netlist.Path;

            netlist.Path = new SubcircuitPath(netlist, orig, subckt);

            // Read all control statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Control))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Read all model statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Model))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Read all component statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Component))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Restore
            netlist.Path = orig;
            Generated    = subckt;
            return(true);
        }