Esempio n. 1
0
        /// <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);
                }
            }
        }
Esempio 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);
            }
        }