/// <summary> /// Creates instances for all signals of a bus /// </summary> /// <param name="state">The state to use</param> /// <param name="parent">The bus to create the signal instances for</param> private void CreateAndRegisterInstance(Validation.ValidationState state, Instance.Bus parent) { var scope = state.CurrentScope; foreach (var signal in parent.Source.Signals) { var s = new Instance.Signal(parent, signal); scope.TryAddSymbol(s.Name, s, signal.Name); parent.Instances.Add(s); } }
/// <summary> /// Creates all sub-instances from declarations /// </summary> /// <param name="state">The state to use</param> /// <param name="declarations">The declarations to process</param> /// <param name="parentInstances">The collection of instances to append to</param> private void CreateAndRegisterInstancesForDeclarations(Validation.ValidationState state, IEnumerable <AST.Declaration> declarations, List <Instance.IInstance> parentInstances) { var scope = state.CurrentScope; // Add all variables and locally defined busses foreach (var decl in declarations) { if (decl is EnumDeclaration en) { var e = new Instance.EnumTypeReference(en); scope.TryAddSymbol(e.Name, e, en.Name); using (state.StartScope(e)) CreateAndRegisterInstance(state, e); parentInstances.Add(e); } else if (decl is FunctionDefinition fdef) { scope.TryAddSymbol(fdef.Name.Name, decl, fdef.Name); } else if (decl is ConstantDeclaration cdecl) { var c = new Instance.ConstantReference(cdecl); scope.TryAddSymbol(c.Name, c, cdecl.Name); parentInstances.Add(c); } else if (decl is VariableDeclaration variable) { var v = new Instance.Variable(variable); scope.TryAddSymbol(v.Name, v, variable.Name); parentInstances.Add(v); } else if (decl is BusDeclaration bus) { var b = new Instance.Bus(bus); scope.TryAddSymbol(b.Name, b, bus.Name); using (state.StartScope(b)) CreateAndRegisterInstance(state, b); parentInstances.Add(b); } else { throw new ParserException($"Unable to process {decl.GetType()} inside a process", decl); } } }
/// <summary> /// Constructs a new signal instance /// </summary> /// <param name="source">The signal used as the source</param> public Signal(Instance.Bus parent, AST.BusSignalDeclaration source) { ParentBus = parent ?? throw new ArgumentNullException(nameof(parent)); Source = source ?? throw new ArgumentNullException(nameof(source)); }
/// <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); } } }