Author: marek
Date: 2007-06-06 10:06:06 -0400 (Wed, 06 Jun 2007)
New Revision: 78740

Modified:
   trunk/mcs/gmcs/cs-parser.jay
   trunk/mcs/gmcs/generic.cs
   trunk/mcs/gmcs/linq.cs
Log:
2007-06-06  Marek Safar  <[EMAIL PROTECTED]>

        * cs-parser.jay: Select, where, cast clauses are now working.
        
        * generics.cs (TypeArguments): New contructor fow known number 
of
        arguments.
        
        * linq.cs: Moved to separate namespace. Refactored select to use 
new
        shared functionality. Implemented where and explictly types from 
clause.



Modified: trunk/mcs/gmcs/cs-parser.jay
===================================================================
--- trunk/mcs/gmcs/cs-parser.jay        2007-06-06 14:05:12 UTC (rev 78739)
+++ trunk/mcs/gmcs/cs-parser.jay        2007-06-06 14:06:06 UTC (rev 78740)
@@ -5355,7 +5355,7 @@
        : from_clause query_body
          {
                lexer.QueryParsing = false;
-               $$ = new QueryExpression ((Expression)$1, (Expression)$2);
+               $$ = new Linq.QueryExpression (current_container, 
current_block, (Expression)$1, (Linq.AQueryClause)$2); 
                end_block (lexer.Location);
          }
        ;
@@ -5377,8 +5377,9 @@
                start_block (lexer.Location);
                LocatedToken lt = (LocatedToken) $3;
 
-               LocalInfo vi = current_block.AddVariable ((Expression)$2, 
lt.Value, lt.Location);
-               $$ = $5;
+               Expression type = (Expression)$2;
+               LocalInfo vi = current_block.AddVariable (type, lt.Value, 
lt.Location);
+               $$ = new Linq.Cast (type, (Expression)$5, lt.Location);
          }
        ;
 
@@ -5406,7 +5407,14 @@
 query_body
        : opt_from_let_where_clauses opt_orderby_clause SELECT expression 
opt_query_continuation
          {
-           $$ = new Select (current_container, current_block, (Expression)$4, 
GetLocation ($3));
+               Linq.AQueryClause ret = new Linq.Select ((Expression)$4, 
GetLocation ($3));
+               
+               if ($1 != null) {
+                       ((Linq.AQueryClause)$1).Next = ret;
+                       ret = (Linq.AQueryClause)$1;
+               }
+                       
+               $$ = ret;
          }
        | opt_from_let_where_clauses opt_orderby_clause group_clause 
opt_query_continuation
        ;
@@ -5433,6 +5441,9 @@
 
 where_clause
        : WHERE boolean_expression
+         {
+               $$ = new Linq.Where ((Expression)$2, GetLocation ($1));
+         }
        ;
        
 opt_orderby_clause

Modified: trunk/mcs/gmcs/generic.cs
===================================================================
--- trunk/mcs/gmcs/generic.cs   2007-06-06 14:05:12 UTC (rev 78739)
+++ trunk/mcs/gmcs/generic.cs   2007-06-06 14:06:06 UTC (rev 78740)
@@ -1135,6 +1135,12 @@
                        this.Location = loc;
                }
 
+               public TypeArguments (Location loc, params Expression[] types)
+               {
+                       this.Location = loc;
+                       this.args = new ArrayList (types);
+               }
+               
                public TypeArguments (int dimension, Location loc)
                {
                        this.dimension = dimension;

Modified: trunk/mcs/gmcs/linq.cs
===================================================================
--- trunk/mcs/gmcs/linq.cs      2007-06-06 14:05:12 UTC (rev 78739)
+++ trunk/mcs/gmcs/linq.cs      2007-06-06 14:06:06 UTC (rev 78740)
@@ -12,82 +12,176 @@
 using System.Reflection;
 using System.Collections;
 
-namespace Mono.CSharp
+namespace Mono.CSharp.Linq
 {
+       // NOTES:
+       // Expression should be IExpression to save some memory and make a few 
things
+       // easier to read
+       //
+       //
+
        public class QueryExpression : Expression
        {
-               Expression query_body;
-               Expression from;
+               public readonly Block Block;
+               public readonly TypeContainer Host;
 
-               public QueryExpression (Expression from, Expression queryBody)
+               AQueryClause query;
+               public Expression From;
+
+               public QueryExpression (TypeContainer host, Block block, 
Expression from, AQueryClause query)
                {
-                       this.from = from;
-                       this.query_body = queryBody;
+                       this.Host = host;
+                       this.Block = block;
+                       this.From = from;
+                       this.query = query;
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       from = from.Resolve (ec);
-                       ((Select)query_body).From = from;
-                       query_body = query_body.Resolve (ec);
+                       LocalInfo li = null;
+                       foreach (LocalInfo li_temp in Block.Variables.Values)
+                       {
+                               li = li_temp;
+                               break;
+                       }
 
-                       return query_body;
+                       Expression e = query.BuildQueryClause (ec, this, From, 
li);
+                       return e.Resolve (ec);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       throw new NotImplementedException ();
+                       throw new NotSupportedException ();
                }
        }
 
-       public class Select : Expression
+       public abstract class ALinqExpression : Expression
        {
-               Expression expr;
-               public Expression From;
+               // Dictionary of method name -> MethodGroupExpr
+               static Hashtable methods = new Hashtable ();
+               static Type enumerable_class;
 
-               TypeContainer host;
-               Block block;
+               protected abstract string MethodName { get; }
 
-               public Select (TypeContainer host, Block block, Expression 
expr, Location loc)
+               protected MethodGroupExpr MethodGroup {
+                       get {
+                               MethodGroupExpr method_group = 
(MethodGroupExpr)methods [MethodName];
+                               if (method_group != null)
+                                       return method_group;
+
+                               if (enumerable_class == null)
+                                       enumerable_class = 
TypeManager.CoreLookupType ("System.Linq", "Enumerable");
+
+                               MemberList ml = TypeManager.FindMembers 
(enumerable_class,
+                                       MemberTypes.Method, BindingFlags.Static 
| BindingFlags.Public,
+                                       Type.FilterName, MethodName);
+
+                               // TODO: implement correct selection
+                               MethodInfo[] mi = new MethodInfo[] { 
(MethodInfo)ml[0] };
+
+                               method_group = new MethodGroupExpr (mi, loc);
+                               methods.Add (MethodName, method_group);
+                               return method_group;
+                       }
+               }
+       }
+
+       public abstract class AQueryClause : ALinqExpression
+       {
+               public AQueryClause Next;
+               protected Expression expr;
+
+               protected AQueryClause (Expression expr, Location loc)
                {
-                       this.host = host;
-                       this.block = block;
-
                        this.expr = expr;
                        this.loc = loc;
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       MethodInfo[] mi = new MethodInfo[] { 
TypeManager.enumerable_select };
-                       MethodGroupExpr select_mg = new MethodGroupExpr (mi, 
loc);
+                       return expr.DoResolve (ec);
+               }
 
-                       // TODO:
-                       LocalInfo li = null;
-                       foreach (LocalInfo li_temp in block.Variables.Values) {
-                               li = li_temp;
-                               break;
-                       }
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
 
-                       // TODO: eplicit li.Type means .Cast between 
IEnumerable and IEnumerable<T>
-                       Parameters p = new Parameters (new Parameter (li.Type, 
li.Name, Parameter.Modifier.NONE, null, loc));
-                       AnonymousMethodExpression ame = new 
AnonymousMethodExpression (null, null, host, p, block, loc);
-                       ame.Block = new ToplevelBlock (p, loc);
+               public Expression BuildQueryClause (EmitContext ec, 
QueryExpression top, Expression from, LocalInfo li)
+               {
+                       Parameters parameters = new Parameters (new Parameter 
(li.Type, li.Name, Parameter.Modifier.NONE, null, loc));
+                       AnonymousMethodExpression ame = new 
AnonymousMethodExpression (
+                               null, null, top.Host,
+                               parameters,
+                               top.Block, loc);
+                       ame.Block = new ToplevelBlock (parameters, loc);
                        ame.Block.AddStatement (new Return (expr, loc));
 
                        ArrayList args = new ArrayList (2);
-                       args.Add (new Argument (From));
+                       args.Add (new Argument (from));
                        args.Add (new Argument (ame));
 
-                       Expression select = new Invocation (select_mg, args);
-                       select = select.Resolve (ec);
-                       return select;
+                       expr = new Invocation (MethodGroup, args);
+                       if (Next != null)
+                               return Next.BuildQueryClause (ec, top, this, 
li);
+
+                       return expr;
                }
+       }
 
+       public class Cast : ALinqExpression
+       {
+               readonly Expression expr;
+               readonly Expression cast_type;
+
+               public Cast (Expression type, Expression expr, Location loc)
+               {
+                       this.cast_type = type;
+                       this.expr = expr;
+                       this.loc = loc;
+               }
+
+               protected override string MethodName {
+                       get { return "Cast"; }
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       TypeArguments type_arguments = new TypeArguments (loc, 
cast_type);
+                       Expression cast = MethodGroup.ResolveGeneric (ec, 
type_arguments);
+
+                       ArrayList args = new ArrayList (1);
+                       args.Add (new Argument (expr));
+                       return new Invocation (cast, args).DoResolve (ec);
+               }
+
                public override void Emit (EmitContext ec)
                {
-                       throw new NotImplementedException ();
+                       throw new NotSupportedException ();
                }
        }
+
+       public class Select : AQueryClause
+       {
+               public Select (Expression expr, Location loc)
+                       : base (expr, loc)
+               {
+               }
+
+               protected override string MethodName {
+                       get { return "Select"; }
+               }
+       }
+
+       public class Where : AQueryClause
+       {
+               public Where (Expression expr, Location loc)
+                       : base (expr, loc)
+               {
+               }
+
+               protected override string MethodName {
+                       get { return "Where"; }
+               }
+       }
 }
-

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to