Beispiel #1
0
        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)");
                }
            }
        }
Beispiel #2
0
        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);
            }
        }