Author: marek
Date: 2007-09-05 13:42:50 -0400 (Wed, 05 Sep 2007)
New Revision: 85375
Modified:
trunk/mcs/gmcs/ChangeLog
trunk/mcs/gmcs/cs-parser.jay
trunk/mcs/gmcs/linq.cs
Log:
2007-09-05 Marek Safar <[EMAIL PROTECTED]>
* cs-parser.jay: Plug into let clause.
* linq.cs: Implemented let clause, parameters refactoring.
Modified: trunk/mcs/gmcs/ChangeLog
===================================================================
--- trunk/mcs/gmcs/ChangeLog 2007-09-05 17:39:49 UTC (rev 85374)
+++ trunk/mcs/gmcs/ChangeLog 2007-09-05 17:42:50 UTC (rev 85375)
@@ -1,3 +1,9 @@
+2007-09-05 Marek Safar <[EMAIL PROTECTED]>
+
+ * cs-parser.jay: Plug into let clause.
+
+ * linq.cs: Implemented let clause, parameters refactoring.
+
2007-08-31 Marek Safar <[EMAIL PROTECTED]>
* generic.cs (TypeParameter): Uses common Emit.
Modified: trunk/mcs/gmcs/cs-parser.jay
===================================================================
--- trunk/mcs/gmcs/cs-parser.jay 2007-09-05 17:39:49 UTC (rev 85374)
+++ trunk/mcs/gmcs/cs-parser.jay 2007-09-05 17:42:50 UTC (rev 85375)
@@ -5490,6 +5490,14 @@
let_clause
: LET IDENTIFIER ASSIGN expression
+ {
+ start_block (lexer.Location);
+ LocatedToken lt = (LocatedToken) $2;
+ current_block.AddVariable
(Linq.ImplicitQueryParameter.ImplicitType.Instance,
+ lt.Value, lt.Location);
+ $$ = new Linq.Let (current_block, (Expression)$4);
+ end_block (lexer.Location);
+ }
;
where_clause
Modified: trunk/mcs/gmcs/linq.cs
===================================================================
--- trunk/mcs/gmcs/linq.cs 2007-09-05 17:39:49 UTC (rev 85374)
+++ trunk/mcs/gmcs/linq.cs 2007-09-05 17:42:50 UTC (rev 85375)
@@ -90,23 +90,30 @@
throw new NotSupportedException ();
}
- public virtual Expression BuildQueryClause (EmitContext ec,
Expression from, Parameters parameters, TransparentIdentifiersScope ti)
+ public virtual Expression BuildQueryClause (EmitContext ec,
Expression from, Parameter parameter, TransparentIdentifiersScope ti)
{
ArrayList args = new ArrayList (2);
args.Add (new Argument (from));
- args.Add (new Argument (CreateSelector (ec, expr,
parameters, ti)));
+ args.Add (new Argument (CreateSelector (ec, expr,
parameter, ti)));
expr = new Invocation (MethodGroup, args);
if (next != null)
- return next.BuildQueryClause (ec, this,
parameters, ti);
+ return next.BuildQueryClause (ec, this,
parameter, ti);
return expr;
}
- protected LambdaExpression CreateSelector (EmitContext ec,
Expression expr, Parameters parameters, TransparentIdentifiersScope ti)
+ protected LambdaExpression CreateSelector (EmitContext ec,
Expression expr, Parameter parameter, TransparentIdentifiersScope ti)
{
+ return CreateSelector (ec, expr, new Parameter [] {
parameter }, ti);
+ }
+
+ protected LambdaExpression CreateSelector (EmitContext ec,
Expression expr, Parameter[] parameters, TransparentIdentifiersScope ti)
+ {
+ Parameters p = new Parameters (parameters);
+
LambdaExpression selector = new LambdaExpression (
- null, null, (TypeContainer) ec.DeclContainer,
parameters, ec.CurrentBlock, loc);
- selector.Block = new SelectorBlock (ec.CurrentBlock,
parameters, ti, loc);
+ null, null, (TypeContainer) ec.DeclContainer,
p, ec.CurrentBlock, loc);
+ selector.Block = new SelectorBlock (ec.CurrentBlock, p,
ti, loc);
selector.Block.AddStatement (new Return (expr, loc));
selector.CreateAnonymousHelpers ();
@@ -129,12 +136,12 @@
}
//
- // A query clause with identifier (range variable)
+ // A query clause with an identifier (range variable)
//
public abstract class ARangeVariableQueryClause : AQueryClause
{
public readonly Block block;
- Expression element_selector;
+ protected Expression element_selector;
protected ARangeVariableQueryClause (Block block, Expression
expr, Location loc)
: base (expr, loc)
@@ -142,8 +149,20 @@
this.block = block;
}
- public override Expression BuildQueryClause (EmitContext ec,
Expression from, Parameters parameters, TransparentIdentifiersScope ti)
+ protected virtual void AddSelectorArguments (EmitContext ec,
ArrayList args, Parameter parentParameter,
+ Parameter parameter, TransparentIdentifiersScope ti)
{
+ args.Add (new Argument (CreateSelector (ec, expr,
parentParameter, null)));
+ args.Add (new Argument (CreateSelector (ec,
element_selector,
+ new Parameter [] { parentParameter, parameter
}, ti)));
+ }
+
+ //
+ // Customization for range variables which not only creates a
lambda expression but
+ // also builds a chain of range varible pairs
+ //
+ public override Expression BuildQueryClause (EmitContext ec,
Expression from, Parameter parentParameter, TransparentIdentifiersScope ti)
+ {
ICollection values = block.Variables.Values;
if (values.Count != 1)
throw new NotImplementedException ("Count !=
1");
@@ -152,61 +171,58 @@
enumerator.MoveNext ();
LocalInfo li = (LocalInfo) enumerator.Current;
- Parameters clause_parameter;
+ Parameter parameter;
if (li.Type ==
ImplicitQueryParameter.ImplicitType.Instance) {
- clause_parameter = new Parameters (
- new ImplicitQueryParameter (li));
+ parameter = new ImplicitQueryParameter (li);
} else {
- clause_parameter = new Parameters (
- new Parameter (li.Type, li.Name,
Parameter.Modifier.NONE, null, li.Location));
+ parameter = new Parameter (li.Type, li.Name,
Parameter.Modifier.NONE, null, li.Location);
}
- if (parameters == null)
- return next.BuildQueryClause (ec, expr,
clause_parameter, ti);
+ if (parentParameter == null)
+ return next.BuildQueryClause (ec, expr,
parameter, ti);
- Parameters transparent_parameters = new Parameters (
- new Parameter[] { parameters [0],
clause_parameter [0] });
if (next != null) {
+ //
+ // Builds transparent identifiers, each
identifier includes its parent
+ // type at index 0, and new value at index 1.
This is not valid for the
+ // first one which includes two values directly.
+ //
ArrayList transp_args = new ArrayList (2);
- transp_args.Add (new AnonymousTypeParameter
(transparent_parameters [0]));
- transp_args.Add (new AnonymousTypeParameter
(transparent_parameters [1]));
+ transp_args.Add (new AnonymousTypeParameter
(parentParameter));
+ transp_args.Add (CreateAnonymousTypeVariable
(parameter));
element_selector = new AnonymousTypeDeclaration
(transp_args, (TypeContainer) ec.DeclContainer, loc);
}
ArrayList args = new ArrayList (3);
args.Add (new Argument (from));
- args.Add (new Argument (CreateSelector (ec, expr,
parameters, null)));
- args.Add (new Argument (CreateSelector (ec,
element_selector, transparent_parameters, ti)));
+ AddSelectorArguments (ec, args, parentParameter,
parameter, ti);
+
expr = new Invocation (MethodGroup, args);
if (next != null) {
- TransparentParameter tp = new
TransparentParameter (loc);
- parameters = new Parameters (tp);
-
+ //
+ // Parameter indentifiers goes to the scope
+ //
string[] identifiers;
if (ti == null) {
- identifiers = new string [] {
transparent_parameters [0].Name, transparent_parameters [1].Name };
+ identifiers = new string [] {
parentParameter.Name, parameter.Name };
} else {
- identifiers = new string [] {
transparent_parameters [1].Name };
+ identifiers = new string [] {
parameter.Name };
}
- return next.BuildQueryClause (ec, this,
parameters,
+ TransparentParameter tp = new
TransparentParameter (loc);
+ return next.BuildQueryClause (ec, this, tp,
new TransparentIdentifiersScope (ti,
tp, identifiers));
-
}
return expr;
}
- public override AQueryClause Next {
- set {
- element_selector = value.expr;
-
- // Can be optimized as SelectMany element
selector
- if (value is Select)
- return;
-
- next = value;
- }
+ //
+ // For transparent identifiers, creates an instance of variable
expression
+ //
+ protected virtual AnonymousTypeParameter
CreateAnonymousTypeVariable (Parameter parameter)
+ {
+ return new AnonymousTypeParameter (parameter);
}
}
@@ -259,19 +275,19 @@
this.element_selector = elementSelector;
}
- public override Expression BuildQueryClause (EmitContext ec,
Expression from, Parameters parameters, TransparentIdentifiersScope ti)
+ public override Expression BuildQueryClause (EmitContext ec,
Expression from, Parameter parameter, TransparentIdentifiersScope ti)
{
ArrayList args = new ArrayList (3);
args.Add (new Argument (from));
- args.Add (new Argument (CreateSelector (ec, expr,
parameters, ti)));
+ args.Add (new Argument (CreateSelector (ec, expr,
parameter, ti)));
// A query can be optimized when selector is not group
by specific
if (!element_selector.Equals (from))
- args.Add (new Argument (CreateSelector (ec,
element_selector, parameters, ti)));
+ args.Add (new Argument (CreateSelector (ec,
element_selector, parameter, ti)));
expr = new Invocation (MethodGroup, args);
if (next != null)
- return next.BuildQueryClause (ec, this,
parameters, ti);
+ return next.BuildQueryClause (ec, this,
parameter, ti);
return expr;
}
@@ -281,6 +297,54 @@
}
}
+ public class Let : ARangeVariableQueryClause
+ {
+ class RangeAnonymousTypeParameter : AnonymousTypeParameter
+ {
+ readonly Parameter parameter;
+
+ public RangeAnonymousTypeParameter (Expression
initializer, Parameter parameter)
+ : base (initializer, parameter.Name,
parameter.Location)
+ {
+ this.parameter = parameter;
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ Expression e = base.DoResolve (ec);
+ if (e != null) {
+ //
+ // Spread resolved initializer type
+ //
+ parameter.ParameterType = type;
+ parameter.Resolve (ec);
+ }
+
+ return e;
+ }
+ }
+
+ public Let (Block block, Expression expr)
+ : base (block, expr, expr.Location)
+ {
+ }
+
+ protected override void AddSelectorArguments (EmitContext ec,
ArrayList args, Parameter parentParameter, Parameter parameter,
+ TransparentIdentifiersScope ti)
+ {
+ args.Add (new Argument (CreateSelector (ec,
element_selector, parentParameter, ti)));
+ }
+
+ protected override AnonymousTypeParameter
CreateAnonymousTypeVariable (Parameter parameter)
+ {
+ return new RangeAnonymousTypeParameter (expr,
parameter);
+ }
+
+ protected override string MethodName {
+ get { return "Select"; }
+ }
+ }
+
public class Select : AQueryClause
{
public Select (Expression expr, Location loc)
@@ -303,6 +367,18 @@
protected override string MethodName {
get { return "SelectMany"; }
}
+
+ public override AQueryClause Next {
+ set {
+ element_selector = value.expr;
+
+ // Can be optimized as SelectMany element
selector
+ if (value is Select)
+ return;
+
+ next = value;
+ }
+ }
}
public class Where : AQueryClause
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches