/// <summary> /// Find the type of a local variable /// </summary> /// <param name="name">The name of the variable</param> /// <returns></returns> private string GetVariableType(string name) { // Use regular expression to find the type Regex decl = new Regex($@"^\s*(?<type>double|int)[^;]+{name}[^;]*;", RegexOptions.Multiline); Match m = decl.Match(Definition); if (m.Success) { return(m.Groups["type"].Value); } m = decl.Match(ModelCode); if (m.Success) { return(m.Groups["type"].Value); } m = decl.Match(DeviceCode); if (m.Success) { return(m.Groups["type"].Value); } // Search the main part for the type ConverterWarnings.Add($"Could not find type of local variable {name}"); return("double"); }
/// <summary> /// Read the method in which is iterated over all device models and instances and seperate the code parts /// The results are stored in the variables /// </summary> /// <param name="method">The full method definition</param> protected void ReadMethod(string method) { // Get the model loop content Regex modelloop = new Regex(@"for\s*\(\s*;\s*(?<var>\w+)\s*\!\=\s*NULL\s*;\s*\k<var>\s*\=\s*\k<var>\s*\-\>\s*\w+\s*\)\s*{"); var m = modelloop.Match(method); if (m.Success) { string content = Code.GetMatchingBlock(method, m.Index + m.Length - 1); string model = m.Groups["var"].Value; // Get the instance loop content Regex instanceloop = new Regex(@"for\s*\(\s*(?<var>\w+)\s*\=\s*" + model + @"\s*\-\>\s*\w+\s*;\s*\k<var>\s*(\!\=\s*NULL\s*)?;\s*\k<var>\s*\=\s*\k<var>\s*\-\>\s*\w+\s*\)\s*{"); var m2 = instanceloop.Match(content); if (m2.Success) { int s = m2.Index + m2.Length - 1; int e = Code.GetMatchingParenthesis(content, s); string content2 = content.Substring(s + 1, e - s - 1); // Everything is ready to store! int ms = method.IndexOf('{'); Definition = method.Substring(ms + 1, m.Index - ms - 1); ModelCode = content.Substring(0, m2.Index - 1); ModelParameter = m.Groups["var"].Value; DeviceCode = content2; DeviceParameter = m2.Groups["var"].Value; // There is still a part after the device loop that could be used for the loop ModelCode += content.Substring(e + 1); } else { ConverterWarnings.Add("Could not find instance iterator"); int ms = method.IndexOf('{'); Definition = method.Substring(ms + 1, m.Index - ms - 1); ModelCode = content; ModelParameter = m.Groups["var"].Value; DeviceCode = ""; DeviceParameter = ""; } } else { throw new Exception("Could not find model iterator"); } // Find all the declared variables FindSharedVariables(); }
/// <summary> /// Build the list of parameters /// </summary> /// <param name="param"></param> /// <param name="ask"></param> /// <param name="declarations"></param> /// <param name="variables"></param> private void BuildParameters(Dictionary <string, ParameterExtractor.DeviceParameter> ps) { // First make a list of all possible ID's HashSet <string> ids = new HashSet <string>(); foreach (var k in param.Keys) { ids.Add(k); } foreach (var k in ask.Keys) { ids.Add(k); } List <string> attr = new List <string>(); List <string> decl = new List <string>(); // Build a declaration for each foreach (var id in ids) { // Get the declarations string param_decl = param.ContainsKey(id) ? Code.RemoveComments(param[id]).Trim() : null; string ask_decl = ask.ContainsKey(id) ? Code.RemoveComments(ask[id]).Trim() : null; if (!ps.ContainsKey(id)) { // Warning! ConverterWarnings.Add($"Could not find definition for ID '{id}'"); continue; } var info = ps[id]; string type = GetTypeByFlag(info.FlagType); string name = null; // Build the attributes attr.Clear(); foreach (var n in info.Names) { attr.Add($"SpiceName(\"{n}\")"); } attr.Add($"SpiceInfo(\"{info.Description}\")"); List <string> declaration = new List <string>(); decl.Clear(); decl.Add($"[{string.Join(", ", attr)}]"); // Create a declaration if (param_decl != null && ask_decl != null) { // Let's hope it's a Parameter<> string paramGet, paramGiven; string[] multiS, multiG; bool defSet = IsDefaultParameterSet(param_decl, out name, out paramGiven); bool defGet = IsDefaultGet(ask_decl, out paramGet); if (defSet && defGet && name == paramGet) { GivenVariable.Add(paramGiven, name); switch (type.ToLower()) { case "double": case "int": decl.Add($"public Parameter {name} {{ get; }} = new Parameter();"); break; default: decl.Add($"public Parameter<{type}> {name} {{ get; }} = new Parameter<{type}>();"); break; } } else if (IsDefaultSet(param_decl, out name) && defGet && name == paramGet) { decl.Add($"public {type} {name} {{ get; set; }}"); } else if (AnySet(ref param_decl, out multiS) && AnyGet(ask_decl, out multiG)) { decl.AddRange(new string[] { $"public {type} {id}", "{", "get", "{", fmtMethod(ask_decl), "}", "set", "{", fmtMethod(param_decl), "}", "}" }); // Find the first common one if (multiS[0] == multiG[0]) { name = multiS[0]; if (GivenVariable.ContainsValue(name)) { switch (type.ToLower()) { case "double": case "int": decl.Add($"public Parameter {name} {{ get; }} = new Parameter();"); break; default: decl.Add($"public Parameter<{type}> {name} = new Parameter<{type}>();"); break; } } else { decl.Add($"private {type} {name};"); } } } else { ConverterWarnings.Add($"Could not process ID '{id}'"); continue; } } else if (param_decl != null) { // Check for a default anyway, Spice mistakes sometimes... string given; if (IsDefaultParameterSet(param_decl, out name, out given)) { GivenVariable.Add(given, name); switch (type.ToLower()) { case "double": case "int": decl.Add($"public Parameter {name} {{ get;}} = new Parameter();"); break; default: decl.Add($"public Parameter<{type}> {name} {{ get; }} = new Parameter<{type}>();"); break; } } else if (IsDefaultSet(param_decl, out name)) { decl.Add($"public {type} {name} {{ get; set; }}"); } else { string[] names; AnySet(ref param_decl, out names); decl.AddRange(new string[] { $"public void Set{id}({type} value)", "{", fmtMethod(param_decl), "}" }); } } else if (ask_decl != null) { if (IsDefaultGet(ask_decl, out name)) { decl.Add($"public {type} {name} {{ get; private set; }}"); } else { decl.AddRange(new string[] { $"public {type} Get{id}(Circuit ckt)", "{", fmtMethod(ask_decl), "}" }); } } else { throw new Exception("Invalid declaration(?)"); } // Store if (name != null) { Variables.Add(name); Declarations.Add(name, string.Join(Environment.NewLine, decl)); } else { Methods.Add(string.Join(Environment.NewLine, decl)); } } }