public void Main(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, ComponentStartMode startMode) { // TODO: Add your interpreter code // Get RootFolder IMgaFolder rootFolder = project.RootFolder; // To use the domain-specific API: // Create another project with the same name as the paradigm name // Copy the paradigm .mga file to the directory containing the new project // In the new project, install the GME DSMLGenerator NuGet package (search for DSMLGenerator) // Add a Reference in this project to the other project // Add "using [ParadigmName] = ISIS.GME.Dsml.[ParadigmName].Classes.Interfaces;" to the top of this file // if (currentobj.Meta.Name == "KindName") // [ParadigmName].[KindName] dsCurrentObj = ISIS.GME.Dsml.[ParadigmName].Classes.[KindName].Cast(currentobj); if (currentobj.Meta.Name == "Component") { VF.Component dsCurrentObj = VFClasses.Component.Cast(currentobj); // List of components for which we need dictionaries var components = new List <string>(); // constants and function references list var parameters = new List <Parameter>(); // functions var functions = new List <Function>(); // Build the list of all constants and functions BuildLists("", dsCurrentObj, components, parameters, functions); using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"output.py")) { file.WriteLine("import json"); file.WriteLine(""); file.WriteLine("parameters = dict()"); file.WriteLine(""); file.WriteLine("def add(x, *args):"); file.WriteLine(" for arg in args:"); file.WriteLine(" x = x + arg"); file.WriteLine(" return x"); file.WriteLine(""); file.WriteLine("def mult(x, *args):"); file.WriteLine(" for arg in args:"); file.WriteLine(" x = x * arg"); file.WriteLine(" return x"); file.WriteLine(""); file.WriteLine("def max (x, *args):"); file.WriteLine(" for arg in args:"); file.WriteLine(" if arg > x:"); file.WriteLine(" x = arg"); file.WriteLine(" return x"); file.WriteLine(""); file.WriteLine("simpleResults = list()"); file.WriteLine("complexResults = list()"); file.WriteLine("pythonResults = list()"); file.WriteLine(""); foreach (var c in components) { file.WriteLine("parameters[\"" + c.Replace(".", "\"][\"") + "\"] = dict()"); } var knownElements = new List <System.Guid>(); var newKnownElements = new List <System.Guid>(); var values = new Dictionary <System.Guid, string>(); int simpleResultsCount = 0; int complexResultsCount = 0; int pythonResultsCount = 0; int passIndex = 0; int lastCount = -1; int count = 0; while (count > lastCount) { file.WriteLine("\n#----------------- Pass " + passIndex++ + " ------------------"); lastCount = count; foreach (var p in parameters.Where(p => !knownElements.Contains(p.guid))) { if (p.constant) { newKnownElements.Add(p.guid); values.Add(p.guid, "parameters[\"" + p.name.Replace(".", "\"][\"") + "\"]"); file.WriteLine("parameters[\"" + p.name.Replace(".", "\"][\"") + "\"] = " + p.value); count++; } else if (knownElements.Contains(p.dependencies.First())) { newKnownElements.Add(p.guid); values.Add(p.guid, values[p.dependencies.First()]); file.WriteLine("parameters[\"" + p.name.Replace(".", "\"][\"") + "\"] = " + values[p.dependencies.First()]); count++; } } file.WriteLine(""); foreach (var f in functions.Where(f => !knownElements.Contains(f.guid))) { var unsatisfiedDeps = f.dependencies.Where(d => !knownElements.Contains(d)); if (!unsatisfiedDeps.Any()) { if (f.type == Function.FunctionType.SIMPLE) { var expressionString = Function.simpleFunctionTransform[f.simpleType] + "(" + String.Join(",", f.dependencies.Select(x => values[x]).ToList()) + ")"; file.WriteLine("simpleResults.append(" + expressionString + ")"); var valueString = "simpleResults[" + simpleResultsCount++ + "]"; newKnownElements.Add(f.guid); values.Add(f.guid, valueString); count++; } else if (f.type == Function.FunctionType.COMPLEX) { // Replace the META variables with their respective Python variables var templateStringIndex = 0; var output = new StringBuilder(f.expression); foreach (var d in f.dependencies) { output.Replace("$" + templateStringIndex++, values[d]); } var expressionString = "(" + output.ToString() + ")"; file.WriteLine("complexResults.append(" + expressionString + ")"); var valueString = "complexResults[" + complexResultsCount++ + "]"; newKnownElements.Add(f.guid); values.Add(f.guid, valueString); count++; } else if (f.type == Function.FunctionType.PYTHON) { var functionName = Path.GetFileNameWithoutExtension(f.python_filename); file.WriteLine("\nimport " + functionName); file.WriteLine("pythonResults.append(" + functionName + "." + functionName + "("); file.Write(" " + String.Join(",\n ", f.dependencies.Select(x => values[x]).ToList())); file.WriteLine("))\n"); int outputIndex = 0; foreach (var output in f.outputs) { var valueString = "pythonResults[" + pythonResultsCount + "][" + outputIndex++ + "]"; newKnownElements.Add(output); values.Add(output, valueString); count++; } newKnownElements.Add(f.guid); pythonResultsCount++; } } } knownElements.AddRange(newKnownElements); newKnownElements = new List <Guid>(); } file.WriteLine("#------ Done! (No new values found.) -------"); file.WriteLine(""); file.WriteLine("print json.dumps(parameters, indent=2, sort_keys=True)"); file.WriteLine(""); file.WriteLine("with open('output.json', 'w') as f_out:"); file.WriteLine(" json.dump(parameters, f_out, indent=2, sort_keys=True)"); } } }
void BuildLists(string parents, VF.Component component, List <string> components, List <Parameter> parameters, List <Function> functions) { components.Add(parents + component.Name); parents = parents + component.Name + "."; foreach (var p in component.Children.ParameterCollection) { if (!p.SrcConnections.ValueFlowCollection.Any()) // No incoming ValueFlow connections { // Value should already be assigned var value = p.Attributes.Value; if (value == null || value == "") // Looks like it wasn't assigned, after all { value = "0"; } else if (value.Contains('/')) // To support single fraction inputs { value = "float(" + value.Replace("/", ")/"); } parameters.Add(new Parameter(parents + p.Name, p.Guid, value)); } else { var dep = p.SrcConnections.ValueFlowCollection.First().SrcEnd.Guid; parameters.Add(new Parameter(parents + p.Name, p.Guid, dep)); } } foreach (var f in component.Children.SimpleFormulaCollection) { var deps = new List <System.Guid>(); foreach (var flow in f.SrcConnections.ValueFlowCollection) { deps.Add(flow.SrcEnd.Guid); } functions.Add(new Function(parents + f.Name, f.Guid, deps, Function.FunctionType.SIMPLE, f.Attributes.Method.ToString())); } foreach (var f in component.Children.ComplexFormulaCollection) { // Translate the MuParser expression to a python expression AntlrInputStream input = new AntlrInputStream(f.Attributes.Expression.ToString()); MuParserLexer lexer = new MuParserLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); MuParserParser parser = new MuParserParser(tokens); IParseTree tree = parser.expr(); MuParserToPythonVisitor visitor = new MuParserToPythonVisitor(); var pythonExpression = visitor.Visit(tree); // Get all unique ID's referenced in complexFormula ParseTreeWalker walker = new ParseTreeWalker(); IDListener listener = new IDListener(); walker.Walk(listener, tree); var ids = listener.GetIDs().OrderByDescending(id => id.Length); // Get mapping from IDs to Guids var guids = new Dictionary <string, System.Guid>(); foreach (var flow in f.SrcConnections.ValueFlowCollection) { if (flow.Attributes.Name == null || flow.Attributes.Name == "") { guids[flow.SrcEnd.Name] = flow.SrcEnd.Guid; } else { guids[flow.Attributes.Name] = flow.SrcEnd.Guid; } } // Save ordered Guid list of dependencies var deps = ids.Select(id => guids[id]).ToList(); // Substitute template strings into pythonExpression to create templateExpression var template = new StringBuilder(pythonExpression); var i = 0; foreach (var id in ids) { template.Replace(id, "$" + i++); } var templateExpression = template.ToString(); functions.Add(new Function(parents + f.Name, f.Guid, deps, Function.FunctionType.COMPLEX, templateExpression)); } foreach (var f in component.Children.PythonCollection) { var filename = System.IO.Path.GetFileName(f.Attributes.Filename); System.IO.File.Copy(f.Attributes.Filename, filename, true); string pythonBody = System.IO.File.ReadAllText(filename); // Sort Dependencies and Outputs based on order in function. var deps = new List <System.Guid>(); var outputs = new List <System.Guid>(); List <string> pyArgs = new Regex(System.IO.Path.GetFileNameWithoutExtension(filename) + @"\((.*)\)").Match(pythonBody).Groups[1].Captures[0].ToString().Split(',').Select(p => p.Trim()).ToList(); List <string> pyReturnVals = new Regex(@"return\s+\[(.*)\]").Match(pythonBody).Groups[1].Captures[0].ToString().Split(',').Select(p => p.Trim()).ToList(); foreach (var arg in pyArgs) { if (f.Children.InputCollection.Select(x => x.Name).Contains(arg)) { var input = f.Children.InputCollection.First(x => x.Name == arg); var dep = input.SrcConnections.ValueFlowCollection.First().SrcEnd.Guid; deps.Add(dep); } } foreach (var returnVal in pyReturnVals) { if (f.Children.OutputCollection.Select(x => x.Name).Contains(returnVal)) { var output = f.Children.OutputCollection.First(x => x.Name == returnVal); outputs.Add(output.Guid); } } functions.Add(new Function(parents + f.Name, f.Guid, deps, Function.FunctionType.PYTHON, f.Attributes.Filename, outputs)); } foreach (VF.Component c in component.Children.ComponentCollection) { BuildLists(parents, c, components, parameters, functions); } }