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); }
private IType AsAnnotationType(ITypeSystem system, IEnvironment env, IList <IType> types) { IType ctor; if ( (Spec is Node) && (((ctor = ((Node)Spec).Type as IType)) != null) && (!IsFunction(ctor) || IsAnnotation) ) { Args.Select ( (arg, i) => arg is Var ? system.Infer(env, Define((Var)arg, Const(ctor[i])), types) : null ). ToArray(); var type = system.NewType(ctor, Args.Select(arg => system.Infer(env, ToFormal(system, env, types, arg), types)).ToArray()); return(type); } else { return(null); } }
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())); }
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); }
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); }
public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types) { env = env.Local(system); return(Args.Select(define => system.Infer(env, define, types)).Concat(new[] { system.Infer(env, Body, types) }).Last()); }