示例#1
0
        /// <summary>
        /// Registers an item for usage in a particular direction
        /// </summary>
        /// <param name="scope">The scope to use</param>
        /// <param name="item">The item to register</param>
        /// <param name="direction">The direction to register</param>
        /// <param name="sourceExpr">The source expression used for error messages</param>
        public void RegisterItemUsageDirection(Instance.IParameterizedInstance scope, object item, ItemUsageDirection direction, AST.ParsedItem sourceExpr)
        {
            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            if (!ItemDirection.TryGetValue(scope, out var usagescope))
            {
                ItemDirection[scope] = usagescope = new Dictionary <object, ItemUsageDirection>();
            }

            if (item is Instance.Signal signalInstance)
            {
                // Get list of parameters with direction from instantiation
                var directionParam = scope
                                     .MappedParameters
                                     .Zip(
                    Enumerable.Range(0, scope.MappedParameters.Count),
                    (x, i) => new
                {
                    Direction = scope.SourceParameters[i].Direction,
                    Bus       = x.MappedItem
                }
                    )
                                     .Where(x => x.Bus == signalInstance.ParentBus)
                                     .FirstOrDefault();

                // Local bus is bi-directional and does not need checking
                if (directionParam != null)
                {
                    var definedDirection = directionParam.Direction;

                    // Flip the signal if it has inverse direction
                    if (signalInstance.Source.Direction == SignalDirection.Inverse)
                    {
                        definedDirection =
                            definedDirection == ParameterDirection.In
                            ? ParameterDirection.Out
                            : ParameterDirection.In;
                    }

                    if (definedDirection == ParameterDirection.Out && direction != ItemUsageDirection.Write)
                    {
                        throw new ParserException($"Can only write to output signal: {signalInstance.Name}", sourceExpr);
                    }
                    if (definedDirection == ParameterDirection.In && direction != ItemUsageDirection.Read)
                    {
                        throw new ParserException($"Can only read from input signal: {signalInstance.Name}", sourceExpr);
                    }
                }
            }

            if (!usagescope.TryGetValue(item, out var d))
            {
                usagescope[item] = direction;
            }
            else if (d != direction)
            {
                usagescope[item] = ItemUsageDirection.Both;
            }
        }
示例#2
0
 /// <summary>
 /// Tries to add a new symbol to the table and throws an exception pointing to the offending location
 /// </summary>
 /// <param name="name">The name of the item to add</param>
 /// <param name="item">The item to add</param>
 /// <param name="token">The token used in the error message</param>
 public void TryAddSymbol(string name, object item, AST.ParsedItem token)
 {
     TryAddSymbol(name, item, token.SourceToken);
 }