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