コード例 #1
0
        public BindingContext BuildContext(BindingContext callingContext,
                                           IUnboundDecl parameterType, IBoundDecl argType,
                                           ref IEnumerable <IBoundDecl> typeArgs, out bool canInferArgs)
        {
            // try to infer the args if not passed in
            IList <IBoundDecl> inferredTypeArgs = TypeArgInferrer.Infer(TypeParameters,
                                                                        parameterType, argType);

            canInferArgs = inferredTypeArgs != null;

            if (canInferArgs)
            {
                typeArgs = inferredTypeArgs;
            }

            if (typeArgs.IsEmpty())
            {
                typeArgs = null;
            }

            // include the open namespaces of the calling context. this was the instantiated
            // generic has access to everything that the instantiation call site has access
            // to
            var searchSpace = new NameSearchSpace(BaseType.SearchSpace, callingContext.SearchSpace);

            return(new BindingContext(callingContext.Compiler, searchSpace, TypeParameters, typeArgs));
        }
コード例 #2
0
        /// <summary>
        /// Infers the types of the given collection of named type arguments from the given collection
        /// of parameters.
        /// </summary>
        /// <param name="typeArgNames">The names of the type parameters.</param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static IList <IBoundDecl> Infer(IEnumerable <string> typeParameters,
                                               IUnboundDecl parameterType,
                                               IBoundDecl argType)
        {
            var inferrer = new TypeArgInferrer(typeParameters);

            inferrer.mParamTypes.Push(parameterType);
            bool dummy = argType.Accept(inferrer);

            inferrer.mParamTypes.Pop();

            // if the inference failed (like from a type collision) then fail
            if (inferrer.mFailed)
            {
                return(null);
            }

            // if any type argument is left unfilled then fail
            if (inferrer.mTypeArguments.Contains(null))
            {
                return(null);
            }

            return(inferrer.mTypeArguments);
        }
コード例 #3
0
ファイル: Decl.cs プロジェクト: stjordanis/magpie-csharp
        /// <summary>
        /// Creates a new unbound declaration.
        /// </summary>
        public Decl(IUnboundDecl unbound)
        {
            if (unbound == null)
            {
                throw new ArgumentNullException("unbound");
            }

            Unbound = unbound;
        }
コード例 #4
0
        public UnionCase(string name, IUnboundDecl valueType, int index)
        {
            if (valueType == null)
            {
                throw new ArgumentNullException("valueType");
            }

            Name      = name;
            ValueType = new Decl(valueType);
            Index     = index;
        }
コード例 #5
0
        // <-- LPAREN ParamDecl? ARROW TypeDecl? RPAREN
        private FuncType FnArgsDecl(List <string> paramNames)
        {
            Consume(TokenType.LeftParen);

            var arg = CurrentIs(TokenType.RightArrow) ? Decl.Unit : ParamDecl(paramNames);

            var position = Consume(TokenType.RightArrow).Position;

            IUnboundDecl returnType = CurrentIs(TokenType.RightParen) ? Decl.Unit : TypeDecl();

            Consume(TokenType.RightParen);

            return(new FuncType(position, arg, returnType));
        }
コード例 #6
0
        public static T Match <T>(this IUnboundDecl decl,
                                  Func <AtomicDecl, T> atomicCallback,
                                  Func <FuncType, T> funcCallback,
                                  Func <RecordType, T> recordCallback,
                                  Func <TupleType, T> tupleCallback,
                                  Func <NamedType, T> namedCallback)
        {
            if (decl == null)
            {
                throw new ArgumentNullException("decl");
            }

            var atomic = decl as AtomicDecl;

            if (atomic != null)
            {
                return(atomicCallback(atomic));
            }

            var func = decl as FuncType;

            if (func != null)
            {
                return(funcCallback(func));
            }

            var record = decl as RecordType;

            if (record != null)
            {
                return(recordCallback(record));
            }

            var tuple = decl as TupleType;

            if (tuple != null)
            {
                return(tupleCallback(tuple));
            }

            var named = decl as NamedType;

            if (named != null)
            {
                return(namedCallback(named));
            }

            throw new ArgumentException("Unknown declaration type.");
        }
コード例 #7
0
        public FuncType(Position position, IUnboundDecl parameter, IUnboundDecl returnType)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException("parameter");
            }
            if (returnType == null)
            {
                throw new ArgumentNullException("returnType");
            }

            Position = position;

            Parameter = new Decl(parameter);
            Return    = new Decl(returnType);
        }
コード例 #8
0
        public static IUnboundDecl Clone(this IUnboundDecl decl)
        {
            return(decl.Match <IUnboundDecl>(
                       // atomic types are immutable, so we can reuse it
                       atomic => atomic,
                       func => func.CloneFunc(),
                       record => {
                var fields = new Dictionary <string, IUnboundDecl>();
                foreach (var field in record.Fields)
                {
                    fields.Add(field.Key, field.Value.Clone());
                }

                return new RecordType(fields);
            },
                       tuple => new TupleType(tuple.Fields.Select(field => field.Clone())),
                       // named types are immutable, so we can reuse it
                       named => named));
        }
コード例 #9
0
        public static IUnboundDecl[] Expand(this IUnboundDecl decl)
        {
            // the unit type expands to no values
            if (ReferenceEquals(decl, Decl.Unit))
            {
                return(new IUnboundDecl[0]);
            }

            // a tuple expands to its fields
            TupleType tuple = decl as TupleType;

            if (tuple != null)
            {
                return(tuple.Fields.ToArray());
            }

            // everything else expands to just itself
            return(new IUnboundDecl[] { decl });
        }
コード例 #10
0
        // <-- (NAME (TypeDecl)? LINE)*
        private List <UnionCase> UnionCases()
        {
            var cases = new List <UnionCase>();

            while (CurrentIs(TokenType.Name))
            {
                var name = Consume(TokenType.Name).StringValue;

                IUnboundDecl type = Decl.Unit;
                if (!CurrentIs(TokenType.Line))
                {
                    type = TypeDecl();
                }
                Consume(TokenType.Line);

                cases.Add(new UnionCase(name, type, cases.Count));
            }

            return(cases);
        }
コード例 #11
0
ファイル: TypeBinder.cs プロジェクト: adityavs/magpie-csharp
        public static IBoundDecl Bind(BindingContext context, IUnboundDecl unbound)
        {
            return(unbound.Match <IBoundDecl>(
                       // atomics are already bound
                       atomic => atomic,
                       func => {
                Bind(context, func);
                return func;
            },
                       record => {
                var fields = new Dictionary <string, IBoundDecl>();

                foreach (var field in record.Fields)
                {
                    fields.Add(field.Key, Bind(context, field.Value));
                }

                return new BoundRecordType(fields);
            },
                       tuple => new BoundTupleType(tuple.Fields.Select(field => Bind(context, field))),
                       named => BindNamed(context, named)));
        }
コード例 #12
0
ファイル: Struct.cs プロジェクト: stjordanis/magpie-csharp
 public Field(string name, IUnboundDecl type)
     : this(name, type, 0)
 {
 }
コード例 #13
0
ファイル: Decl.cs プロジェクト: rwaldron/magpie
        /// <summary>
        /// Binds this declaration to the given binder.
        /// </summary>
        public void Bind(Func<IUnboundDecl, IBoundDecl> binder)
        {
            if (binder == null) throw new ArgumentNullException("binder");
            if (IsBound) throw new InvalidOperationException("Cannot bind a Decl that is already bound.");

            Bound = binder(Unbound);

            // discard the unbound one now. makes sure we're clear on what state we expect
            // the declaration to be in.
            Unbound = null;
        }
コード例 #14
0
ファイル: Decl.cs プロジェクト: rwaldron/magpie
        /// <summary>
        /// Creates a new unbound declaration.
        /// </summary>
        public Decl(IUnboundDecl unbound)
        {
            if (unbound == null) throw new ArgumentNullException("unbound");

            Unbound = unbound;
        }
コード例 #15
0
 public FuncRefExpr(Position position, NameExpr name, IUnboundDecl paramType)
 {
     Position  = position;
     Name      = name;
     ParamType = paramType;
 }
コード例 #16
0
ファイル: Struct.cs プロジェクト: stjordanis/magpie-csharp
 public Field(string name, IUnboundDecl type, byte index)
     : this(name, index)
 {
     Type = new Decl(type);
 }
コード例 #17
0
 /// <summary>
 /// Instantiates a new instance of a zero-length array.
 /// </summary>
 /// <param name="position">Where the expression occurs in the source file.</param>
 /// <param name="elementType">The element type. This must be explicitly passed in since
 /// it cannot be inferred from an element.</param>
 public ArrayExpr(Position position, IUnboundDecl elementType)
 {
     Position     = position;
     mElementType = elementType;
 }
コード例 #18
0
ファイル: Struct.cs プロジェクト: stjordanis/magpie-csharp
 public void Define(string name, IUnboundDecl type)
 {
     Fields.Add(new Field(name, type, (byte)Fields.Count));
 }
コード例 #19
0
ファイル: NamedType.cs プロジェクト: stjordanis/magpie-csharp
 public NamedType(string name)
 {
     Position  = Position.None;
     Name      = name;
     mTypeArgs = new IUnboundDecl[0];
 }