Skip to content

Instantly share code, notes, and snippets.

@lucaswerkmeister
Created January 15, 2014 23:20
Show Gist options
  • Save lucaswerkmeister/8446745 to your computer and use it in GitHub Desktop.
Save lucaswerkmeister/8446745 to your computer and use it in GitHub Desktop.
Grammar changes for ceylon/ceylon-spec#869 – comprehensions beginning with if clause
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