Ejemplo n.º 1
0
        /// <summary>
        /// Creates a fake process that is used to create the connection
        /// </summary>
        /// <param name="state">The validation state to use</param>
        /// <param name="scope">The active scope</param>
        /// <param name="connEntry">The connection entry to create the process for</param>
        /// <returns>A fake process instance</returns>
        public static Instance.Process CreateConnectProcess(Validation.ValidationState state, Validation.ScopeState scope, AST.ConnectEntry connEntry)
        {
            var lhs = state.FindSymbol(connEntry.Source, scope) ?? throw new ParserException($"Could not resolve symbol {connEntry.Source.SourceToken}", connEntry.Source);
            var rhs = state.FindSymbol(connEntry.Target, scope) ?? throw new ParserException($"Could not resolve symbol {connEntry.Target.SourceToken}", connEntry.Target);

            if (lhs is Instance.Signal lhs_signal && rhs is Instance.Signal rhs_signal)
            {
                return(IdentityHelper.CreateIdentityProcess(
                           state,
                           scope,
                           connEntry.SourceToken,
                           // Extract the bus name locally
                           new Name(connEntry.Source.SourceToken, connEntry.Source.Identifier.SkipLast(1).ToArray(), null).AsExpression(),
                           new Name(connEntry.Target.SourceToken, connEntry.Target.Identifier.SkipLast(1).ToArray(), null).AsExpression(),
                           // Assign just the named entry
                           new[] { lhs_signal.Source },
                           // Ensure we use the same type to avoid silent type-casting
                           new[] {
                    new BusSignalDeclaration(connEntry.Target.SourceToken,
                                             rhs_signal.Source.Name,
                                             lhs_signal.Source.Type,
                                             null,
                                             AST.SignalDirection.Normal
                                             )
                },
                           Instance.ProcessType.Connect
                           ));
            }
Ejemplo n.º 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);
            }
        }
Ejemplo n.º 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);
                }
            }
        }