예제 #1
0
        /// <summary>
        /// Returns all output signals for a process or connection
        /// </summary>
        /// <param name="state">The state object</param>
        /// <returns>The output signals</returns>
        public IEnumerable <Instance.Signal> OutputSignals(ValidationState state, Instance.Process process)
        {
            return(process.MappedParameters
                   .Where(x => x.MappedItem is Instance.Bus)
                   .SelectMany(x => {
                var isOut = x.MatchedParameter.Direction == AST.ParameterDirection.Out;
                var parentBus = x.MappedItem as Instance.Bus;

                return parentBus
                .Instances
                .OfType <Instance.Signal>()
                .Where(y =>
                       y.Source.Direction == SignalDirection.Normal
                                ? isOut
                                : !isOut
                       );
            })
                   .Concat(
                       process.Instances
                       .OfType <Instance.Bus>()
                       .SelectMany(x => x.Instances.OfType <Instance.Signal>())
                       .Where(x =>
                              state.ItemDirection[process].ContainsKey(x)
                              &&
                              state.ItemDirection[process][x] == ItemUsageDirection.Write
                              )
                       )
                   .Distinct());
        }
예제 #2
0
        /// <summary>
        /// Creates all sub-instances for a process
        /// </summary>
        /// <param name="state">The state to use</param>
        /// <param name="parent">The parent process</param>
        private void CreateAndRegisterInstance(Validation.ValidationState state, Instance.Process parent)
        {
            var scope = state.CurrentScope;

            CreateAndRegisterInstancesForDeclarations(state, parent.ProcessDefinition.Declarations, parent.Instances);

            // TODO: The scope should work within the statement tree. We can have nested statements....
            foreach (var loop in parent.Statements.All().OfType <AST.ForStatement>())
            {
                var l = new Instance.ForLoop(loop.Current);
                using (var sc = state.StartScope(l, loop.Current)) {
                    var varinst = new Instance.Variable(loop.Current.Variable);
                    sc.TryAddSymbol(loop.Current.Variable.Name.Name, varinst, loop.Current.Variable.SourceToken);
                }
                parent.Instances.Add(l);
            }

            // Find all function invocations so we can map parameters
            foreach (var func in parent.Statements.All().OfType <AST.FunctionStatement>())
            {
                var fdef = state.FindSymbol(func.Current.Name, scope);
                if (fdef == null)
                {
                    throw new ParserException($"No function named {func.Current.Name.AsString} found", func.Current);
                }
                if (!(fdef is AST.FunctionDefinition ffdef))
                {
                    throw new ParserException($"Expected a function for {func.Current.Name.AsString}, but found {fdef.GetType()}", func.Current);
                }

                var f = new Instance.FunctionInvocation(ffdef, func.Current);
                using (var sc = state.StartScope(f))
                    CreateAndRegisterInstancesForDeclarations(state, ffdef.Declarations, f.Instances);

                parent.Instances.Add(f);
            }
        }
예제 #3
0
        /// <summary>
        /// Creates and registers all network declaration instances
        /// </summary>
        /// <param name="state">The state to use</param>
        /// <param name="networkDecls">The network declarations to instantiate</param>
        /// <param name="parentCollection"></param>
        private void CreateAndRegisterInstances(Validation.ValidationState state, IEnumerable <NetworkDeclaration> networkDecls, IList <Instance.IInstance> parentCollection)
        {
            var scope = state.CurrentScope;

            foreach (var decl in networkDecls)
            {
                if (decl is AST.BusDeclaration bus)
                {
                    var b = new Instance.Bus(bus);
                    scope.TryAddSymbol(b.Name, b, bus.Name);
                    using (state.StartScope(b))
                        CreateAndRegisterInstance(state, b);
                    parentCollection.Add(b);
                }
                else if (decl is AST.ConstantDeclaration cdecl)
                {
                    var cref = new Instance.ConstantReference(cdecl);
                    scope.TryAddSymbol(cref.Name, cref, cdecl.Name);
                    parentCollection.Add(cref);
                    continue;
                }
                else if (decl is AST.GeneratorDeclaration genDecl)
                {
                    var startSymbol  = state.ResolveToInteger(genDecl.SourceExpression, scope);
                    var finishSymbol = state.ResolveToInteger(genDecl.TargetExpression, scope);

                    // TODO: Need to fix array support for this to work correctly?
                    for (var i = startSymbol; i < finishSymbol; i++)
                    {
                        CreateAndRegisterInstances(state, genDecl.Networks, parentCollection);
                    }
                }
                else if (decl is AST.InstanceDeclaration instDecl)
                {
                    var sym = state.FindSymbol(instDecl.SourceItem, scope);
                    if (sym != null && sym is AST.Network netw)
                    {
                        // Recursively create network
                        // TODO: Guard against infinite recursion
                        parentCollection.Add(CreateAndRegisterInstance(state, instDecl, netw));
                    }
                    else if (sym != null && sym is AST.Process proc)
                    {
                        var p = new Instance.Process(instDecl, proc, Instance.ProcessType.Normal);
                        if (instDecl.Name.Name != null)
                        {
                            scope.TryAddSymbol(instDecl.Name.Name.Name, p, instDecl.Name.Name);
                        }

                        using (state.StartScope(p, instDecl))
                            CreateAndRegisterInstance(state, p);
                        parentCollection.Add(p);
                    }
                    else
                    {
                        if (sym == null)
                        {
                            throw new ParserException($"No item found with the name {instDecl.SourceItem}", decl);
                        }
                        else
                        {
                            throw new ParserException($"The item {instDecl.SourceItem} is not a process, but a {sym.GetType().Name}", decl);
                        }
                    }
                }
                else if (decl is AST.ConnectDeclaration connDecl)
                {
                    foreach (var connEntry in connDecl.Entries)
                    {
                        var p = IdentityHelper.CreateConnectProcess(state, scope, connEntry);
                        using (state.StartScope(p, connEntry))
                            CreateAndRegisterInstance(state, p);
                        parentCollection.Add(p);
                    }
                }
                else
                {
                    throw new ParserException($"Attempted to create an instance of type: {decl.GetType()}", decl);
                }
            }
        }