Created
January 15, 2014 23:20
-
-
Save lucaswerkmeister/8446745 to your computer and use it in GitHub Desktop.
Grammar changes for ceylon/ceylon-spec#869 – comprehensions beginning with if clause
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Ceylon.g b/Ceylon.g | |
index 1ef1226..3dee8ef 100644 | |
--- a/Ceylon.g | |
+++ b/Ceylon.g | |
@@ -1848,7 +1848,9 @@ anonymousFunction returns [Expression expression] | |
comprehension returns [Comprehension comprehension] | |
@init { $comprehension = new Comprehension(null); } | |
: forComprehensionClause | |
- { $comprehension.setForComprehensionClause($forComprehensionClause.comprehensionClause); } | |
+ { $comprehension.setInitialComprehensionClause($forComprehensionClause.comprehensionClause); } | |
+ | ifComprehensionClause | |
+ { $comprehension.setInitialComprehensionClause($ifComprehensionClause.comprehensionClause); } | |
; | |
comprehensionClause returns [ComprehensionClause comprehensionClause] | |
diff --git a/Ceylon.nodes b/Ceylon.nodes | |
index f1101ec..761729d 100644 | |
--- a/Ceylon.nodes | |
+++ b/Ceylon.nodes | |
@@ -823,7 +823,7 @@ | |
"A comprehension." | |
^(COMPREHENSION:POSITIONAL_ARGUMENT | |
- FOR_COMPREHENSION_CLAUSE) | |
+ INITIAL_COMPREHENSION_CLAUSE) | |
"A single clause of comprehension" | |
^(abstract COMPREHENSION_CLAUSE:CONTROL_CLAUSE | |
@@ -831,16 +831,19 @@ | |
ProducedType firstTypeModel; | |
boolean possiblyEmpty;) | |
+"A clause that can appear at the beginning of a comprehension." | |
+^(abstract INITIAL_COMPREHENSION_CLAUSE:COMPREHENSION_CLAUSE) | |
+ | |
"The expression at the end of a comprehension." | |
^(EXPRESSION_COMPREHENSION_CLAUSE:COMPREHENSION_CLAUSE | |
EXPRESSION) | |
"A quantifier clause in a comprehension." | |
-^(FOR_COMPREHENSION_CLAUSE:COMPREHENSION_CLAUSE | |
+^(FOR_COMPREHENSION_CLAUSE:INITIAL_COMPREHENSION_CLAUSE | |
FOR_ITERATOR | |
COMPREHENSION_CLAUSE) | |
"A filter clause in a comprehension." | |
-^(IF_COMPREHENSION_CLAUSE:COMPREHENSION_CLAUSE | |
+^(IF_COMPREHENSION_CLAUSE:INITIAL_COMPREHENSION_CLAUSE | |
CONDITION_LIST | |
COMPREHENSION_CLAUSE) | |
diff --git a/en/modules/expressions.xml b/en/modules/expressions.xml | |
index 77bde28..31c3360 100644 | |
--- a/en/modules/expressions.xml | |
+++ b/en/modules/expressions.xml | |
@@ -858,13 +858,14 @@ Digit{1,2} ":" Digit{2} ( ":" Digit{2} ( ":" Digit{3} )? )? | |
</listitem> | |
</itemizedlist> | |
- <para>Every comprehension begins with a <literal>for</literal> clause, and | |
- ends with an expression clause. There may be any number of intervening | |
+ <para>Every comprehension begins with a <literal>for</literal> or <literal>if</literal> | |
+ clause, and ends with an expression clause. There may be any number of intervening | |
<literal>for</literal> or <literal>if</literal> clauses. Each clause in the | |
comprehension is considered a child of the clause that immediately precedes | |
it.</para> | |
- <synopsis>Comprehension: ForComprehensionClause</synopsis> | |
+ <synopsis>Comprehension: InitialComprehensionClause</synopsis> | |
+ <synopsis>InitialComprehensionClause: ForComprehensionClause | IfComprehensionClause</synopsis> | |
<synopsis>ForComprehensionClause: "for" ForIterator ComprehensionClause</synopsis> | |
<synopsis>IfComprehensionClause: "if" ConditionList ComprehensionClause</synopsis> | |
<synopsis>ComprehensionClause: ForComprehensionClause | IfComprehensionClause | Expression</synopsis> | |
diff --git a/src/com/redhat/ceylon/compiler/typechecker/analyzer/ExpressionVisitor.java b/src/com/redhat/ceylon/compiler/typechecker/analyzer/ExpressionVisitor.java | |
index b93bdfe..eca37fc 100644 | |
--- a/src/com/redhat/ceylon/compiler/typechecker/analyzer/ExpressionVisitor.java | |
+++ b/src/com/redhat/ceylon/compiler/typechecker/analyzer/ExpressionVisitor.java | |
@@ -2755,8 +2755,8 @@ public class ExpressionVisitor extends Visitor { | |
private void checkComprehensionIndirectArgument(Tree.Comprehension c, | |
ProducedType paramType, boolean atLeastOne) { | |
- Tree.ForComprehensionClause fcc = ((Tree.Comprehension) c).getForComprehensionClause(); | |
- if (fcc.getPossiblyEmpty() && atLeastOne) { | |
+ Tree.InitialComprehensionClause icc = ((Tree.Comprehension) c).getInitialComprehensionClause(); | |
+ if (icc.getPossiblyEmpty() && atLeastOne) { | |
c.addError("variadic parameter is required but comprehension is possibly empty"); | |
} | |
ProducedType at = c.getTypeModel(); | |
@@ -2802,8 +2802,8 @@ public class ExpressionVisitor extends Visitor { | |
private void checkComprehensionPositionalArgument(Parameter p, ProducedReference pr, | |
Tree.Comprehension c, boolean atLeastOne) { | |
- Tree.ForComprehensionClause fcc = ((Tree.Comprehension) c).getForComprehensionClause(); | |
- if (fcc.getPossiblyEmpty() && atLeastOne) { | |
+ Tree.InitialComprehensionClause icc = ((Tree.Comprehension) c).getInitialComprehensionClause(); | |
+ if (icc.getPossiblyEmpty() && atLeastOne) { | |
c.addError("variadic parameter is required but comprehension is possibly empty"); | |
} | |
ProducedType paramType = pr.getTypedParameter(p).getFullType(); | |
@@ -2847,7 +2847,7 @@ public class ExpressionVisitor extends Visitor { | |
@Override public void visit(Tree.Comprehension that) { | |
super.visit(that); | |
- that.setTypeModel(that.getForComprehensionClause().getTypeModel()); | |
+ that.setTypeModel(that.getInitialComprehensionClause().getTypeModel()); | |
} | |
@Override public void visit(Tree.SpreadArgument that) { | |
@@ -4629,13 +4629,13 @@ public class ExpressionVisitor extends Visitor { | |
} | |
else if (a instanceof Tree.Comprehension) { | |
ut = et; | |
- Tree.ForComprehensionClause fcc = ((Tree.Comprehension) a).getForComprehensionClause(); | |
- result = fcc.getPossiblyEmpty() ? | |
+ Tree.InitialComprehensionClause icc = ((Tree.Comprehension) a).getInitialComprehensionClause(); | |
+ result = icc.getPossiblyEmpty() ? | |
unit.getSequentialType(et) : | |
unit.getSequenceType(et); | |
if (!requireSequential) { | |
ProducedType it = producedType(unit.getIterableDeclaration(), | |
- et, fcc.getFirstTypeModel()); | |
+ et, icc.getFirstTypeModel()); | |
result = intersectionType(result, it, unit); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment