Ejemplo n.º 1
0
        /// <summary>
        /// Parses a process and builds an AST component for it
        /// </summary>
        /// <param name="network">The top-level network.</param>
        /// <param name="process">The process to build the AST for.</param>
        protected virtual Process Parse(NetworkState network, ProcessMetadata process, Simulation simulation)
        {
            var st = process.Instance.GetType();

            var inputbusses  = process.Instance.InputBusses.Union(process.Instance.ClockedInputBusses).ToArray();
            var outputbusses = process.Instance.OutputBusses.Distinct().ToArray();

            var res = new ProcessState()
            {
                Name           = NameWithoutPrefix(network, st.FullName, st),
                SourceType     = st,
                CecilType      = LoadType(st),
                SourceInstance = process,
                InstanceName   = process.InstanceName,
                Parent         = network,
                IsSimulation   = process.Instance is SimulationProcess,
                IsClocked      = st.GetCustomAttribute <ClockedProcessAttribute>() != null,
                Decompile      =
                    (
                        typeof(SimpleProcess).IsAssignableFrom(st)
                        ||
                        typeof(StateProcess).IsAssignableFrom(st)
                    )
                    &&
                    !st.HasAttribute <SuppressOutputAttribute>()
                    &&
                    !st.HasAttribute <SuppressBodyAttribute>()
            };

            var proctype = res.CecilType.Resolve();

            if (res.CecilType is Mono.Cecil.GenericInstanceType)
            {
                var gp    = res.CecilType as Mono.Cecil.GenericInstanceType;
                var names = gp.GenericArguments.ToArray();
                var ga    = proctype.GenericParameters.ToArray();

                foreach (var g in ga)
                {
                    res.GenericMap[g.Name]   = g;
                    res.GenericTypes[g.Name] = names[g.Position];
                }
            }

            res.InputBusses    = inputbusses.Select(x => Parse(network, res, x, simulation)).ToArray();
            res.OutputBusses   = outputbusses.Select(x => Parse(network, res, x, simulation)).ToArray();
            res.InternalBusses = process.Instance.InternalBusses.Select(x => Parse(network, res, x, simulation)).ToArray();
            foreach (var ib in res.InternalBusses)
            {
                ib.IsInternal = true;
            }

            // Set up the local names by finding the field that holds the instance reference
            foreach (var b in res.InputBusses.Union(res.OutputBusses).Union(res.InternalBusses))
            {
                var f = st
                        .GetFields(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic)
                        .FirstOrDefault(x => x.GetValue(process.Instance) == b.SourceInstance);
                if (f != null)
                {
                    res.LocalBusNames[b] = f.Name;
                }
            }

            if (res.Decompile)
            {
                // Register all variables
                foreach (var f in proctype.Fields)
                {
                    var ft = res.ResolveGenericType(f.FieldType);

                    if (ft.IsBusType())
                    {
                        RegisterBusReference(network, res, f);
                    }
                    else
                    {
                        RegisterVariable(network, res, f);
                    }
                }
            }

            foreach (var f in process.Initialization)
            {
                if (f.Value == null)
                {
                    continue;
                }

                Variable v;
                if (res.Variables.TryGetValue(f.Key, out v))
                {
                    SetDataElementDefaultValue(network, res, v, f.Value, false);
                }
            }

            res.SharedSignals        = res.Signals.Values.ToArray();
            res.SharedVariables      = res.Variables.Values.ToArray();
            res.InternalDataElements = new DataElement[0];
            return(res);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses a a field reference and returns the associated variable
        /// </summary>
        /// <returns>The constant element.</returns>
        /// <param name="network">The top-level network.</param>
        /// <param name="proc">The process where the method is located.</param>
        /// <param name="field">The field to parse.</param>
        protected virtual DataElement RegisterVariable(NetworkState network, ProcessState proc, FieldDefinition field)
        {
            DataElement res;

            var    ceciltype    = proc.ResolveGenericType(field.FieldType);
            object defaultvalue = null;

            proc.SourceInstance.Initialization.TryGetValue(field.Name, out defaultvalue);
            defaultvalue = field.Constant ?? defaultvalue;


            if (field.IsLiteral)
            {
                var c = new Constant()
                {
                    CecilType    = ceciltype,
                    DefaultValue = defaultvalue,
                    Name         = field.Name,
                    Source       = field,
                    Parent       = proc
                };
                res = c;
                network.ConstantLookup.Add(field, c);
            }
            else if (field.IsStatic && field.IsInitOnly)
            {
                var c = new Constant()
                {
                    CecilType    = ceciltype,
                    DefaultValue = defaultvalue,
                    Name         = field.Name,
                    Source       = field,
                    Parent       = proc
                };
                res = c;
                network.ConstantLookup[field] = c;
            }
            else if (field.IsStatic)
            {
                //Don't care
                res = null;
            }
            else if (field.GetAttribute <Signal>() == null)
            {
                var c = new Variable()
                {
                    CecilType    = ceciltype,
                    DefaultValue = defaultvalue,
                    Name         = field.Name,
                    Source       = field,
                    Type         = null,
                    Parent       = proc
                };
                res = c;
                proc.Variables.Add(field.Name, c);
            }
            else
            {
                var c = new Signal()
                {
                    CecilType    = ceciltype,
                    DefaultValue = defaultvalue,
                    Name         = field.Name,
                    Source       = field,
                    Type         = null,
                    Parent       = proc
                };
                res = c;
                proc.Signals.Add(field.Name, c);
            }

            return(res);
        }