Пример #1
0
        public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types)
        {
            if (Type == null)
            {
                var annotation = AsAnnotationType(system, env, types);
                if (annotation != null)
                {
                    return(annotation);
                }
            }
            var   args = Args.Select(arg => system.Infer(env, ToFormal(system, env, types, arg), types)).ToList();
            var   expr = (Node)Spec;
            var   self = system.Infer(env, expr, types);
            IType @out;

            if (Type != null)
            {
                var ctor = !(Type is IType) ? system.Const(env, (string)Type) : (IType)Type;
                @out = system.Infer(env, Apply(Var(ctor.Id, ctor), args.Select(arg => Const(arg)).ToArray(), IsAnnotation), types);
            }
            else
            {
                @out = system.NewGeneric();
                args.Add(@out);
                system.Unify(system.NewType(TypeSystem.Function, args.ToArray()), self);
            }
            return(@out);
        }
Пример #2
0
        public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types)
        {
            var scope = env.Local(system);
            var known = new List <IType>(types);
            var args  = new List <IType>();

            foreach (var arg in Args)
            {
                IType type;
                Var   var;
                if (!(arg is Define))
                {
                    var = (Var)arg;
                    if (var.Type != null)
                    {
                        type = !(var.Type is IType) ? system.Const(scope, (string)var.Type) : (IType)var.Type;
                    }
                    else
                    {
                        type = system.NewGeneric();
                        known.Add(type);
                    }
                    scope[var.Id] = type;
                }
                else
                {
                    var spec = ((Define)arg).Body;
                    var  = (Var)((Define)arg).Spec;
                    type = system.NewGeneric();
                    system.Unify(type, system.Infer(scope, spec, known));
                    scope[var.Id] = type;
                    known.Add(type);
                }
                args.Add(type);
                if (!type.Value.IsConstructor)
                {
                    type.Value.Bind(var.Id);
                }
            }
            args.Add(system.Infer(scope, Body is Let ? Body.Args[Body.Args.Length - 1] : Body, known));
            if (Type != null)
            {
                system.Unify(args[args.Count - 1], !(Type is IType) ? system.Const(scope, (string)Type) : (IType)Type);
            }
            return(system.NewType(TypeSystem.Function, args.ToArray()));
        }
Пример #3
0
        public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types)
        {
            var known = new List <IType>(types);
            var type  = system.NewGeneric();
            var var   = (Var)Spec;
            var scope = Body.IsAnnotation ? env.Local(system) : env;

            env[var.Id] = type;
            known.Add(type);
            system.Unify(type, system.Infer(scope, Body, known));
            return(env[var.Id] = !type.Value.IsConstructor ? type.Value.Bind(var.Id) : type.Value);
        }
Пример #4
0
        private Node ToFormal(ITypeSystem system, IEnvironment env, IList <IType> types, Node arg)
        {
            Func <Var, IType> typed =
                var =>
                IsAnnotation && !env.ContainsKey(var.Id) ? env[var.Id] = system.NewGeneric() : env[var.Id];
            var formal =
                IsAnnotation ?
                (
                    arg is Apply ?
                    Define((Var)arg.Args[0], Const(system.Infer(env, (Node)arg.Spec, types)))
                    :
                    arg is Var ? Define((Var)arg, Const(typed((Var)arg))) : arg
                )
                :
                arg is Var?Define((Var)arg, Const(typed((Var)arg))) : arg;

            return(formal);
        }