Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Closes #70.
  • Loading branch information
lucaswerkmeister committed Nov 22, 2014
1 parent 462e8de commit cfd24e4
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 40 deletions.
2 changes: 1 addition & 1 deletion source/ceylon/ast/core/CeylonExpressionTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ shared class CeylonExpressionTransformer(String indentLevel = " ") satisfies
`` indent + indentLevel ``caseClauses = ``transformWithIndent(that.caseClauses)``;
`` indent + indentLevel ``elseCaseClause = ``transformWithIndent(that.elseCaseClause)``;
``indent``}";
transformSwitchClause(SwitchClause that) => "SwitchClause(``transformWithIndent(that.expression)``)";
transformSwitchClause(SwitchClause that) => "SwitchClause(``transformWithIndent(that.switched)``)";
transformThenOperation(ThenOperation that)
=> "ThenOperation {
`` indent + indentLevel ``condition = ``transformWithIndent(that.leftOperand)``;
Expand Down
17 changes: 8 additions & 9 deletions source/ceylon/ast/core/Editor.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -711,14 +711,8 @@ shared interface Editor satisfies ImmediateNarrowingTransformer<Node> {
assert (is RequiredParameter ret = super.transformRequiredParameter(that));
return ret;
}
shared actual default Resource transformResource(Resource that) {
Expression|SpecifiedVariable transformExpressionOrSpecifiedVariable(Expression|SpecifiedVariable that) {
switch (that)
case (is Expression) { return transformExpression(that); }
case (is SpecifiedVariable) { return transformSpecifiedVariable(that); }
}
return that.copy(transformExpressionOrSpecifiedVariable(that.resource));
}
shared actual default Resource transformResource(Resource that)
=> that.copy(transformExpressionOrSpecifiedVariable(that.resource));
shared actual default Resources transformResources(Resources that)
=> that.copy(that.resources.collect(transformResource));
shared actual default Return transformReturn(Return that)
Expand Down Expand Up @@ -796,7 +790,7 @@ shared interface Editor satisfies ImmediateNarrowingTransformer<Node> {
shared actual default SwitchCases transformSwitchCases(SwitchCases that)
=> that.copy(that.caseClauses.collect(transformCaseClause), nullsafeInvoke(that.elseCaseClause, transformElseCaseClause));
shared actual default SwitchClause transformSwitchClause(SwitchClause that)
=> that.copy(transformExpression(that.expression));
=> that.copy(transformExpressionOrSpecifiedVariable(that.switched));
shared actual default ThenOperation transformThenOperation(ThenOperation that)
=> that.copy(transformThenElseExpression(that.leftOperand), transformDisjoiningExpression(that.rightOperand));
shared actual default This transformThis(This that)
Expand Down Expand Up @@ -1001,4 +995,9 @@ shared interface Editor satisfies ImmediateNarrowingTransformer<Node> {
case (is FunctionModifier) { return transformFunctionModifier(that); }
case (is DynamicModifier) { return transformDynamicModifier(that); }
}
Expression|SpecifiedVariable transformExpressionOrSpecifiedVariable(Expression|SpecifiedVariable that) {
switch (that)
case (is Expression) { return transformExpression(that); }
case (is SpecifiedVariable) { return transformSpecifiedVariable(that); }
}
}
21 changes: 11 additions & 10 deletions source/ceylon/ast/core/SwitchClause.ceylon
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
"A ‘`switch`’ clause of a [[`switch` statement|SwitchCaseElse]], that is,
the keyword ‘`switch`’, followed by an [[expression]] enclosed in parentheses.
the keyword ‘`switch`’, followed by an expression or variable definition.
Examples:
switch (i.magnitude)
switch (child)"
shared class SwitchClause(expression)
switch (child)
switch (arg = process.arguments.first)"
shared class SwitchClause(switched)
extends Node() {

"The `switch` expression."
shared Expression expression;
"The `switch` expression or variable definition."
shared Expression|SpecifiedVariable switched;

shared actual [Expression] children = [expression];
shared actual [Expression|SpecifiedVariable] children = [switched];

shared actual Result transform<out Result>(Transformer<Result> transformer)
=> transformer.transformSwitchClause(this);

shared actual Boolean equals(Object that) {
if (is SwitchClause that) {
return expression == that.expression;
return switched == that.switched;
} else {
return false;
}
}

shared actual Integer hash
=> 31 * expression.hash;
=> 31 * switched.hash;

shared SwitchClause copy(Expression expression = this.expression) {
value ret = SwitchClause(expression);
shared SwitchClause copy(Expression|SpecifiedVariable switched = this.switched) {
value ret = SwitchClause(switched);
copyExtraInfoTo(ret);
return ret;
}
Expand Down
60 changes: 43 additions & 17 deletions source/ceylon/ast/redhat/RedHatTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ import com.redhat.ceylon.compiler.typechecker.tree {
JSwitchCaseList=SwitchCaseList,
JSwitchClause=SwitchClause,
JSwitchStatement=SwitchStatement,
JSwitched=Switched,
JSyntheticVariable=SyntheticVariable,
JTerm=Term,
JThenOp=ThenOp,
Expand Down Expand Up @@ -2779,27 +2780,39 @@ shared class RedHatTransformer(TokenFactory tokens) satisfies ImmediateNarrowing
JSwitchStatement ret = JSwitchStatement(null);
ret.switchClause = transformSwitchClause(that.clause);
ret.switchCaseList = transformSwitchCases(that.cases);
// the parser now adds synthetic variables to all ‘is’ cases.
// the parser now adds synthetic variables to all ‘is’ cases and the else case.
// this is mostly copied from the grammar.
value ex = ret.switchClause.expression.term;
if (is JBaseMemberExpression ex) {
value id = ex.identifier;
JIdentifier? id;
if (is JBaseMemberExpression ex = ret.switchClause.switched.expression?.term) {
id = ex.identifier;
} else if (exists var = ret.switchClause.switched.variable) {
id = var.identifier;
} else {
id = null;
}
if (exists id) {
JVariable makeVariable() {
value v = JVariable(null);
v.type = JSyntheticVariable(null);
v.identifier = id;
value se = JSpecifierExpression(null);
value e = JExpression(null);
value bme = JBaseMemberExpression(null);
bme.identifier = id;
bme.typeArguments = JInferredTypeArguments(null);
e.term = bme;
se.expression = e;
v.specifierExpression = se;
return v;
}
for (cc in CeylonIterable(ret.switchCaseList.caseClauses)) {
if (is JIsCase ic = cc.caseItem) {
value v = JVariable(null);
v.type = JSyntheticVariable(null);
v.identifier = id;
value se = JSpecifierExpression(null);
value e = JExpression(null);
value bme = JBaseMemberExpression(null);
bme.identifier = id;
bme.typeArguments = JInferredTypeArguments(null);
e.term = bme;
se.expression = e;
v.specifierExpression = se;
ic.variable = v;
ic.variable = makeVariable();
}
}
if (exists ec = ret.switchCaseList.elseClause) {
ec.variable = makeVariable();
}
}
return ret;
}
Expand All @@ -2818,7 +2831,20 @@ shared class RedHatTransformer(TokenFactory tokens) satisfies ImmediateNarrowing
shared actual JSwitchClause transformSwitchClause(SwitchClause that) {
JSwitchClause ret = JSwitchClause(tokens.token("switch", switch_clause));
tokens.token("(", lparen);
ret.expression = wrapTerm(transformExpression(that.expression));
ret.switched = JSwitched(null);
switch (switched = that.switched)
case (is Expression) { ret.switched.expression = wrapTerm(transformExpression(switched)); }
case (is SpecifiedVariable) {
JVariable var = JVariable(null);
value type = switched.type;
switch (type)
case (is Type) { var.type = transformType(type); }
case (is ValueModifier) { var.type = transformValueModifier(type); }
case (null) { var.type = JValueModifier(null); }
var.identifier = transformLIdentifier(switched.name);
var.specifierExpression = transformSpecifier(switched.specifier);
ret.switched.variable = var;
}
tokens.token(")", rparen);
return ret;
}
Expand Down
35 changes: 32 additions & 3 deletions source/ceylon/ast/redhat/SwitchClause.ceylon
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
import ceylon.ast.core {
SwitchClause
Expression,
SpecifiedVariable,
SwitchClause,
Type,
ValueModifier
}
import com.redhat.ceylon.compiler.typechecker.tree {
Tree {
JSwitchClause=SwitchClause
JStaticType=StaticType,
JSwitchClause=SwitchClause,
JValueModifier=ValueModifier
}
}

"Converts a RedHat AST [[SwitchClause|JSwitchClause]] to a `ceylon.ast` [[SwitchClause]]."
shared SwitchClause switchClauseToCeylon(JSwitchClause switchClause) {
return SwitchClause(expressionToCeylon(switchClause.expression));
Expression|SpecifiedVariable switched;
if (exists jExpression = switchClause.switched.expression) {
"Switch clause cannot have both expression and variable"
assert (!switchClause.switched.variable exists);
switched = expressionToCeylon(jExpression);
} else {
"Switch clause must have either expression or variable"
assert (exists jVariable = switchClause.switched.variable);
assert (exists jSpecifierExpression = jVariable.specifierExpression);
Type|ValueModifier? type;
assert (is JStaticType|JValueModifier jType = jVariable.type);
switch (jType)
case (is JStaticType) { type = typeToCeylon(jType); }
case (is JValueModifier) {
if (jType.mainToken exists) {
type = valueModifierToCeylon(jType);
} else {
// synthetic ValueModifier
type = null;
}
}
switched = SpecifiedVariable(lIdentifierToCeylon(jVariable.identifier), specifierToCeylon(jSpecifierExpression), type);
}
return SwitchClause(switched);
}

"Compiles the given [[code]] for a Switch Clause
Expand Down

0 comments on commit cfd24e4

Please sign in to comment.