Ejemplo n.º 1
0
        public IExpressionNode Visit(NamedIdSyntaxNode node)
        {
            if (node.IdType == NamedIdNodeType.Constant)
            {
                var varVal = (VarVal)node.IdContent;
                return(new ConstantExpressionNode(varVal.Value, varVal.Type, node.Interval));
            }

            var funVariable = _typeInferenceResults.GetFunctionalVariableOrNull(node.OrderNumber);

            if (funVariable != null)
            {
                if (funVariable is IGenericFunction genericFunction)
                {
                    var genericTypes = _typeInferenceResults.GetGenericCallArguments(node.OrderNumber);
                    if (genericTypes == null)
                    {
                        throw new ImpossibleException($"MJ79. Generic function is missed at {node.OrderNumber}:  {node.Id}`{genericFunction.Name} ");
                    }

                    var genericArgs = new FunnyType[genericTypes.Length];
                    for (int i = 0; i < genericTypes.Length; i++)
                    {
                        genericArgs[i] = _typesConverter.Convert(genericTypes[i]);
                    }

                    var function = genericFunction.CreateConcrete(genericArgs);
                    return(new FunVariableExpressionNode(function, node.Interval));
                }
                else if (funVariable is IConcreteFunction concrete)
                {
                    return(new FunVariableExpressionNode(concrete, node.Interval));
                }
            }

            var lower = node.Id;

            if (_variables.GetSourceOrNull(lower) == null)
            {
                //if it is not a variable it might be a functional-variable
                var funVars = _functions.GetOverloads(lower);
                if (funVars.Count > 0)
                {
                    var specification = node.OutputType.FunTypeSpecification;
                    if (specification == null)
                    {
                        throw ErrorFactory.FunctionNameAndVariableNameConflict(node);
                    }

                    if (funVars.Count > 1)
                    {
                        //several function with such name are appliable
                        var result = funVars.Where(f =>
                                                   f.ReturnType == specification.Output && f.ArgTypes.SequenceEqual(specification.Inputs))
                                     .ToList();
                        if (result.Count == 0)
                        {
                            throw ErrorFactory.FunctionIsNotExists(node);
                        }
                        if (result.Count > 1)
                        {
                            throw ErrorFactory.AmbiguousFunctionChoise(node);
                        }
                        if (result[0] is IConcreteFunction ff)
                        {
                            return(new FunVariableExpressionNode(ff, node.Interval));
                        }
                        else
                        {
                            throw new NotImplementedException("GenericsAreNotSupp");
                        }
                    }

                    if (funVars.Count == 1)
                    {
                        if (funVars[0] is IConcreteFunction ff)
                        {
                            return(new FunVariableExpressionNode(ff, node.Interval));
                        }
                    }
                }
            }
            var node1 = _variables.CreateVarNode(node.Id, node.Interval, node.OutputType);

            if (node1.Source.Name != node.Id)
            {
                throw ErrorFactory.InputNameWithDifferentCase(node.Id, node1.Source.Name, node.Interval);
            }
            return(node1);
        }