예제 #1
0
파일: RppNew.cs 프로젝트: dubik/csharprpp
        public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic)
        {
            // TODO should be unified with RppFuncCall and rethink how types for closures are figureout.
            // we should use constraints and type inference only, not this kind of hacks when we check target
            // closure signature and use types from there

            // Skip closures because they may have missing types
            _arguments = NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => !(node is RppClosure), diagnostic);

            Type.Resolve(scope);

            RType targetType = Type.Value;

            if (NeedToInferGenericArguments(targetType))
            {
                RType inferredTargetType;
                Constructor = FindGenericConstructor(targetType, out inferredTargetType);
                Type = new ResolvableType(inferredTargetType);
            }
            else
            {
                Constructor = FindConstructor(targetType);
            }

            _arguments = RppFuncCall.ReplaceUndefinedClosureTypesIfNeeded(_arguments, Constructor.Parameters, new List<RType>());
            NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => node is RppClosure, diagnostic);

            return this;
        }
예제 #2
0
 public static IList<RType> TypesAsList(RppMethodInfo methodInfo)
 {
     List<RType> list = new List<RType>();
     methodInfo.GenericParameters.Select(gp => gp.Type).ForEach(list.Add);
     methodInfo.Parameters?.Select(p => p.Type).ForEach(list.Add);
     list.Add(methodInfo.ReturnType);
     return list;
 }
예제 #3
0
파일: FuncTest.cs 프로젝트: dubik/csharprpp
        public void QueryOneToOneOverload()
        {
            var args = new List<RType> {IntTy};
            var func1 = new RppMethodInfo("create", null, RMethodAttributes.None, UnitTy, new[] {new RppParameterInfo("x", IntTy)});
            var results = OverloadQuery.Find(args, new List<RppMethodInfo> {func1}).ToList();
            Assert.AreEqual(1, results.Count());
            Assert.AreEqual(func1, results.First());

            var func2 = new RppMethodInfo("create", null, RMethodAttributes.None, UnitTy, new RppParameterInfo[] {});
            results = OverloadQuery.Find(Enumerable.Empty<RType>(), new List<RppMethodInfo> {func2}).ToList();
            Assert.AreEqual(1, results.Count());
            Assert.AreEqual(func2, results.First());
        }
예제 #4
0
        public static void DefineNativeTypeFor(TypeBuilder typeBuilder, RppMethodInfo rppMethod)
        {
            MethodAttributes attr = GetMethodAttributes(rppMethod.Attributes, constructor: false);
            MethodBuilder method = typeBuilder.DefineMethod(rppMethod.Name, attr, CallingConventions.Standard);

            if (rppMethod.HasGenericParameters())
            {
                var genericParameters = rppMethod.GenericParameters;
                CreateNativeGenericParameters(genericParameters, genericParameterNames => method.DefineGenericParameters(genericParameterNames));
            }

            DefineReturnType(method, rppMethod.ReturnType);
            DefineParameters(method, rppMethod.Parameters);

            if (rppMethod.Attributes.HasFlag(RMethodAttributes.Synthesized))
            {
                method.SetCustomAttribute(CreateCompilerGeneratedAttribute());
            }

            rppMethod.Native = method;
        }
예제 #5
0
        public static void DefineNativeTypeForConstructor(TypeBuilder typeBuilder, RppMethodInfo rppConstructor)
        {
            MethodAttributes attr = GetMethodAttributes(rppConstructor.Attributes, constructor: true);
            Type[] parametersTypes = ParametersTypes(rppConstructor.Parameters);
            ConstructorBuilder constructor = typeBuilder.DefineConstructor(attr, CallingConventions.Standard, parametersTypes);
            DefineParams(constructor, rppConstructor.Parameters);
            AssignConstructorParamIndex(rppConstructor.Parameters);

            rppConstructor.Native = constructor;
        }
예제 #6
0
        public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic)
        {
            _type.Resolve(scope);

            _patterns = NodeUtils.Analyze(scope, _patterns, diagnostic).ToArray();

            TypeSymbol companionObjectSymbol = scope.LookupObject(_type.Name.Name);
            if (companionObjectSymbol != null)
            {
                RppMethodInfo unapplyMethod = FindUnapply(companionObjectSymbol.Type);
                if (unapplyMethod == null)
                {
                    throw new Exception("Can't find unapply method or amount of parameters is wrong");
                }
                _unapplyMethod = unapplyMethod;
            }
            else
            {
                throw new Exception("Can't find companion object!");
            }

            return this;
        }
예제 #7
0
파일: RType.cs 프로젝트: dubik/csharprpp
        private static RppMethodInfo Convert(MethodInfo method)
        {
            Type declaringType = method.DeclaringType;
            Debug.Assert(declaringType != null, "declaringType != null");

            RType returnType = GetOrCreateType(method.ReturnType.Name, method.ReturnType);

            var rMethodAttributes = RTypeUtils.GetRMethodAttributes(method.Attributes);
            var parameters = method.GetParameters().Select(p => new RppParameterInfo(GetOrCreateType(p.ParameterType.Name, p.ParameterType))).ToArray();
            RppMethodInfo rppConstructor = new RppMethodInfo(method.Name, GetOrCreateType(declaringType.Name, declaringType), rMethodAttributes,
                returnType, parameters)
            {
                Native = method
            };

            return rppConstructor;
        }
예제 #8
0
 private static void UpdateReturnType(RppFunc node, RppMethodInfo method)
 {
     if (!node.IsConstructor)
     {
         method.ReturnType = node.ReturnType.Value;
     }
 }
예제 #9
0
        private void CodegenForStub(RppMethodInfo function)
        {
            if (function.DeclaringType.Name == "Array")
            {
                RType elementType = function.DeclaringType.GenericArguments.First();
                switch (function.Name)
                {
                    case "ctor":
                        _body.Emit(OpCodes.Newarr, elementType.NativeType);
                        break;

                    case "length":
                        _body.Emit(OpCodes.Ldlen);
                        break;

                    case "apply":
                    {
                        if (elementType.IsGenericParameter)
                        {
                            _body.Emit(OpCodes.Ldelem, elementType.NativeType);
                        }
                        else
                        {
                            OpCode ldOpCode = ClrCodegenUtils.ArrayLoadOpCodeByType(elementType.NativeType);
                            _body.Emit(ldOpCode);
                        }
                        break;
                    }

                    case "update":
                    {
                        OpCode? ldOpCode = ClrCodegenUtils.ArrayStoreOpCodeByType(elementType.NativeType);
                        if (ldOpCode.HasValue)
                        {
                            _body.Emit(ldOpCode.Value);
                        }
                        else
                        {
                            _body.Emit(OpCodes.Stelem, elementType.NativeType);
                        }
                        break;
                    }

                    default:
                        throw new NotImplementedException("Other funcs are not implemented");
                }
            }
        }
예제 #10
0
        private static string MethodString(RppMethodInfo method)
        {
            if (method.Name == "ctor")
            {
                return method.ToString().Replace("ctor", "constructor").Replace("constrparam", "");
            }

            return method.ToString();
        }
예제 #11
0
 public static SemanticException NotEnoughArguments(IToken token, RppMethodInfo targetMethod)
 {
     string methodString = MethodString(targetMethod);
     return new SemanticException(107, FormatErrorAndPointAtToken(token, $"not enough arguments for method {methodString}"));
 }
예제 #12
0
파일: RType.cs 프로젝트: dubik/csharprpp
 public RppMethodInfo DefineConstructor(RMethodAttributes attributes, RppParameterInfo[] parameterTypes)
 {
     RppMethodInfo constructor = new RppMethodInfo("ctor", this, attributes, UnitTy, parameterTypes);
     _constructors.Add(constructor);
     return constructor;
 }
예제 #13
0
파일: RType.cs 프로젝트: dubik/csharprpp
 public RppMethodInfo DefineMethod([NotNull] string name,
     RMethodAttributes attributes,
     [CanBeNull] RType returnType,
     [NotNull] RppParameterInfo[] parameterTypes,
     [NotNull] RppGenericParameter[] genericParameters)
 {
     RppMethodInfo method = new RppMethodInfo(name, this, attributes, returnType, parameterTypes);
     if (name == "ctor")
     {
         _constructors.Add(method);
     }
     else
     {
         _methods.Add(method);
     }
     return method;
 }
예제 #14
0
파일: RType.cs 프로젝트: dubik/csharprpp
        private static RppMethodInfo Convert(ConstructorInfo constructor)
        {
            Type declaringType = constructor.DeclaringType;
            Debug.Assert(declaringType != null, "declaringType != null");

            var rMethodAttributes = RTypeUtils.GetRMethodAttributes(constructor.Attributes);
            var parameters = constructor.GetParameters().Select(p => new RppParameterInfo(GetOrCreateType(p.ParameterType.Name, p.ParameterType))).ToArray();
            RppMethodInfo rppConstructor = new RppMethodInfo("ctor", GetOrCreateType(declaringType.Name, declaringType), rMethodAttributes,
                UnitTy, parameters)
            {
                Native = constructor
            };
            return rppConstructor;
        }
예제 #15
0
 public static IEnumerable<RppGenericParameter> CreateGenericParameters(IEnumerable<string> genericParameterName, RType declaringType,
     RppMethodInfo declaringMethod = null)
 {
     int genericArgumentPosition = 0;
     foreach (var genericParamName in genericParameterName)
     {
         RppGenericParameter genericParameter = CreateGenericParameter(genericParamName, genericArgumentPosition++, declaringType, declaringMethod);
         yield return genericParameter;
     }
 }
예제 #16
0
 private static RppGenericParameter CreateGenericParameter(string name, int genericArgumentPosition, RType declaringType, RppMethodInfo declaringMethod)
 {
     RppGenericParameter genericParameter = new RppGenericParameter(name);
     RType type = new RType(name, RTypeAttributes.None, null, declaringType)
     {
         IsGenericParameter = true,
         GenericParameterPosition = genericArgumentPosition,
         GenericParameterDeclaringMethod = declaringMethod
     };
     genericParameter.Type = type;
     genericParameter.Position = genericArgumentPosition;
     return genericParameter;
 }
예제 #17
0
        private IEnumerable<RType> InferTypes(RppMethodInfo candidate, IEnumerable<IRppExpr> args)
        {
            var argTypes = args.Select(a => a.Type.Value).ToList();

            List<RType> targetTypes =
                candidate.GenericParameters.Select(gp => gp.Type)
                    .Concat(candidate.Parameters.Select(p => p.Type))
                    .Concat(candidate.ReturnType).ToList();

            List<RType> sourceTypes = GetGenericArgumentsOrUndefinedTypes(_typeArgs, candidate.GenericParameters.Length)
                .Concat(argTypes).Concat(RppTypeSystem.Undefined).ToList();

            IEnumerable<RType> inferredTypes = TypeInference.InferTypes(sourceTypes, targetTypes).ToList();
            if (inferredTypes.Any(t => RppTypeSystem.Undefined.Equals(t)))
            {
                return null;
            }

            return inferredTypes.Take(candidate.GenericParameters.Length);
        }
예제 #18
0
 public ResolveResults(RppMethodInfo resolvedFunc)
 {
     Method = resolvedFunc;
 }
예제 #19
0
 public ResolveResults(RppMethodInfo resolvedFunc, IEnumerable<RType> typeArguments, bool isInsideClosure)
 {
     Method = resolvedFunc;
     TypeArguments = typeArguments;
     _isInsideClosure = isInsideClosure;
 }
예제 #20
0
 private static void UpdateParameters(RppFunc node, RppMethodInfo method)
 {
     IRppParam[] funcParams = node.Params;
     if (funcParams.Length != 0)
     {
         RppParameterInfo[] funcParamsTypes = funcParams.Select(p => new RppParameterInfo(p.Name, ResolveType(p))).ToArray();
         method.Parameters = funcParamsTypes;
     }
 }
예제 #21
0
 public ClosureResolveResults(RppMember expr, RppMethodInfo resolvedFunc)
     : base(resolvedFunc)
 {
     _expr = expr;
 }
예제 #22
0
 private RppMethodInfo InflateMethod(RppMethodInfo method)
 {
     return new RppInflatedMethodInfo(method, _genericArguments, this);
 }
예제 #23
0
파일: RType.cs 프로젝트: dubik/csharprpp
 private EmptyTypeDefinition()
 {
     TypeParameters = new RppTypeParameterInfo[0];
     Constructors = new RppMethodInfo[0];
     Fields = new RppFieldInfo[0];
     Methods = new RppMethodInfo[0];
 }