Skip to content

Commit

Permalink
Add TupleType, LengthTupleType
Browse files Browse the repository at this point in the history
TupleType is the abstract supertype of ListTupleType (previously just
called TupleType) and LengthTupleType.

Closes #52.
  • Loading branch information
lucaswerkmeister committed Nov 4, 2015
1 parent 3ee7245 commit 8b6c3fd
Show file tree
Hide file tree
Showing 17 changed files with 244 additions and 26 deletions.
7 changes: 6 additions & 1 deletion source/ceylon/ast/core/CascadingNarrowingTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ shared interface CascadingNarrowingTransformer<out Result> satisfies NarrowingTr
case (is SimpleType) { return transformSimpleType(that); }
case (is OptionalType) { return transformOptionalType(that); }
case (is SequentialType) { return transformSequentialType(that); }
case (is ListTupleType) { return transformListTupleType(that); }
case (is TupleType) { return transformTupleType(that); }
case (is IterableType) { return transformIterableType(that); }
case (is GroupedType) { return transformGroupedType(that); }
case (is CallableType) { return transformCallableType(that); }
Expand Down Expand Up @@ -581,6 +581,11 @@ shared interface CascadingNarrowingTransformer<out Result> satisfies NarrowingTr
case (is KeySubscript) { return transformKeySubscript(that); }
case (is RangeSubscript) { return transformRangeSubscript(that); }
}
shared actual default Result transformTupleType(TupleType that) {
switch (that)
case (is ListTupleType) { return transformListTupleType(that); }
case (is LengthTupleType) { return transformLengthTupleType(that); }
}
shared actual default Result transformType(Type that) {
switch (that)
case (is MainType) { return transformMainType(that); }
Expand Down
5 changes: 5 additions & 0 deletions source/ceylon/ast/core/CeylonExpressionTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,11 @@ shared class CeylonExpressionTransformer(String indentLevel = " ") satisfies
`` indent + indentLevel ``parameterLists = ``transformWithIndent(that.parameterLists)``;
`` indent + indentLevel ``qualifier = ``transformWithIndent(that.qualifier)``;
``indent``}";
transformLengthTupleType(LengthTupleType that)
=> "LengthTupleType {
`` indent + indentLevel ``elementType = ``transformWithIndent(that.elementType)``;
`` indent + indentLevel ``length = ``transformWithIndent(that.length)``;
``indent``}";
transformLetExpression(LetExpression that)
=> "LetExpression {
`` indent + indentLevel ``patterns = ``transformWithIndent(that.patterns)``;
Expand Down
6 changes: 6 additions & 0 deletions source/ceylon/ast/core/Editor.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ shared interface Editor satisfies ImmediateNarrowingTransformer<Node> {
=> that.copy(transformLIdentifier(that.name), transformLazySpecifier(that.specifier), that.parameterLists.collect(transformParameters), nullsafeInvoke(that.qualifier, transformThis));
shared actual default LazySpecifier transformLazySpecifier(LazySpecifier that)
=> that.copy(transformExpression(that.expression));
shared actual default LengthTupleType transformLengthTupleType(LengthTupleType that)
=> that.copy(transformPrimaryType(that.elementType), transformIntegerLiteral(that.length));
shared actual default LetExpression transformLetExpression(LetExpression that)
=> that.copy(transformPatternList(that.patterns), transformDisjoiningExpressionOrIfElseExpressionOrLetExpression(that.expression));
shared actual default Literal transformLiteral(Literal that) {
Expand Down Expand Up @@ -644,6 +646,10 @@ shared interface Editor satisfies ImmediateNarrowingTransformer<Node> {
=> that.copy(transformSwitchClause(that.clause), that.caseExpressions.collect(transformCaseExpression), nullsafeInvoke(that.elseExpression, transformDisjoiningExpressionOrIfElseExpressionOrLetExpression));
shared actual default TuplePattern transformTuplePattern(TuplePattern that)
=> that.copy(that.elementPatterns.collect(transformPattern), nullsafeInvoke(that.variadicElementPattern, transformVariadicVariable));
shared actual default TupleType transformTupleType(TupleType that) {
assert (is TupleType ret = super.transformTupleType(that));
return ret;
}
shared actual default UnioningExpression transformUnioningExpression(UnioningExpression that) {
assert (is UnioningExpression ret = super.transformUnioningExpression(that));
return ret;
Expand Down
2 changes: 2 additions & 0 deletions source/ceylon/ast/core/ImmediateNarrowingTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ shared interface ImmediateNarrowingTransformer<out Result> satisfies NarrowingTr
=> that.transform(this);
shared actual default Result transformThenElseExpression(ThenElseExpression that)
=> that.transform(this);
shared actual default Result transformTupleType(TupleType that)
=> that.transform(this);
shared actual default Result transformType(Type that)
=> that.transform(this);
shared actual default Result transformTypeIsh(TypeIsh that)
Expand Down
44 changes: 44 additions & 0 deletions source/ceylon/ast/core/LengthTupleType.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"A length-based tuple type, that is,
an [[element type|elementType]], followed by a [[length]] enclosed in brackets.
`T[n]` is a shortcut for a tuple of exactly `n` `T` elements;
for instance, `Integer[3]` is equivalent to `[Integer,Integer,Integer]`.
Examples:
Boolean[8]
Integer[3]"
shared class LengthTupleType(elementType, length)
extends TupleType() {

"The element type."
shared PrimaryType elementType;
"The length.
This may only be a decimal iteral;
hexadecimal and binary lengths are illegal."
shared IntegerLiteral length;

assert (!(length.text.startsWith("$") || length.text.startsWith("#")));

shared actual [PrimaryType, IntegerLiteral] children = [elementType, length];

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

shared actual Boolean equals(Object that) {
if (is LengthTupleType that) {
return elementType == that.elementType && length == that.length;
} else {
return false;
}
}

shared actual Integer hash
=> 31 * (elementType.hash + 31 * length.hash);

shared LengthTupleType copy(PrimaryType elementType = this.elementType, IntegerLiteral length = this.length) {
value ret = LengthTupleType(elementType, length);
copyExtraInfoTo(ret);
return ret;
}
}
5 changes: 3 additions & 2 deletions source/ceylon/ast/core/ListTupleType.ceylon
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
"A tuple type.
"A list-based tuple type (commonly just called a “tuple type”), that is,
a [[type list|typeList]] enclosed in brackets.
Examples:
[String,Integer,Integer]
[Float,Integer*]
[]"
shared class ListTupleType(typeList)
extends PrimaryType() {
extends TupleType() {

"The types of this tuple type."
shared TypeList typeList;
Expand Down
2 changes: 1 addition & 1 deletion source/ceylon/ast/core/PrimaryType.ceylon
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"A primary type; only [[intersection|IntersectionType]]
and [[union types|UnionType]] come before these."
shared abstract class PrimaryType()
of SimpleType | ListTupleType | IterableType | GroupedType | OptionalType | SequentialType | CallableType
of SimpleType | TupleType | IterableType | GroupedType | OptionalType | SequentialType | CallableType
extends UnionableType() {
}
2 changes: 2 additions & 0 deletions source/ceylon/ast/core/Transformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ shared interface Transformer<out Result> {
shared formal Result transformLargerOperation(LargerOperation that);
shared formal Result transformLazySpecification(LazySpecification that);
shared formal Result transformLazySpecifier(LazySpecifier that);
shared formal Result transformLengthTupleType(LengthTupleType that);
shared formal Result transformLetExpression(LetExpression that);
shared formal Result transformLiteral(Literal that);
shared formal Result transformLocalModifier(LocalModifier that);
Expand Down Expand Up @@ -283,6 +284,7 @@ shared interface Transformer<out Result> {
shared formal Result transformTuple(Tuple that);
shared formal Result transformTuplePattern(TuplePattern that);
shared formal Result transformListTupleType(ListTupleType that);
shared formal Result transformTupleType(TupleType that);
shared formal Result transformType(Type that);
shared formal Result transformTypeAliasDefinition(TypeAliasDefinition that);
shared formal Result transformTypeArgument(TypeArgument that);
Expand Down
10 changes: 10 additions & 0 deletions source/ceylon/ast/core/TupleType.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"A tuple type, which may be either [[list-based|ListTupleType]] (commonly just called a “tuple type”) or [[length-based|LengthTupleType]].
Examples:
[String,Integer,Integer]
Boolean[8]"
shared abstract class TupleType()
of ListTupleType | LengthTupleType
extends PrimaryType() {
}
4 changes: 4 additions & 0 deletions source/ceylon/ast/core/Visitor.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ shared interface Visitor satisfies WideningTransformer<Anything> {
transformLargerOperation(LargerOperation that) => visitLargerOperation(that);
transformLazySpecification(LazySpecification that) => visitLazySpecification(that);
transformLazySpecifier(LazySpecifier that) => visitLazySpecifier(that);
transformLengthTupleType(LengthTupleType that) => visitLengthTupleType(that);
transformLetExpression(LetExpression that) => visitLetExpression(that);
transformLiteral(Literal that) => visitLiteral(that);
transformLocalModifier(LocalModifier that) => visitLocalModifier(that);
Expand Down Expand Up @@ -280,6 +281,7 @@ shared interface Visitor satisfies WideningTransformer<Anything> {
transformTuple(Tuple that) => visitTuple(that);
transformTuplePattern(TuplePattern that) => visitTuplePattern(that);
transformListTupleType(ListTupleType that) => visitListTupleType(that);
transformTupleType(TupleType that) => visitTupleType(that);
transformType(Type that) => visitType(that);
transformTypeAliasDefinition(TypeAliasDefinition that) => visitTypeAliasDefinition(that);
transformTypeArgument(TypeArgument that) => visitTypeArgument(that);
Expand Down Expand Up @@ -481,6 +483,7 @@ shared interface Visitor satisfies WideningTransformer<Anything> {
shared default void visitLazySpecification(LazySpecification that) => super.transformLazySpecification(that);
shared default void visitLazySpecifier(LazySpecifier that) => super.transformLazySpecifier(that);
shared default void visitLIdentifier(LIdentifier that) => super.transformLIdentifier(that);
shared default void visitLengthTupleType(LengthTupleType that) => super.transformLengthTupleType(that);
shared default void visitLetExpression(LetExpression that) => super.transformLetExpression(that);
shared default void visitLiteral(Literal that) => super.transformLiteral(that);
shared default void visitLocalModifier(LocalModifier that) => super.transformLocalModifier(that);
Expand Down Expand Up @@ -593,6 +596,7 @@ shared interface Visitor satisfies WideningTransformer<Anything> {
shared default void visitTuple(Tuple that) => super.transformTuple(that);
shared default void visitTuplePattern(TuplePattern that) => super.transformTuplePattern(that);
shared default void visitListTupleType(ListTupleType that) => super.transformListTupleType(that);
shared default void visitTupleType(TupleType that) => super.transformTupleType(that);
shared default void visitTypeAliasDefinition(TypeAliasDefinition that) => super.transformTypeAliasDefinition(that);
shared default void visitTypeArguments(TypeArguments that) => super.transformTypeArguments(that);
shared default void visitTypeArgument(TypeArgument that) => super.transformTypeArgument(that);
Expand Down
2 changes: 2 additions & 0 deletions source/ceylon/ast/core/WideningTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ shared interface WideningTransformer<out Result> satisfies Transformer<Result> {
shared actual default Result transformLargerOperation(LargerOperation that) => transformComparisonOperation(that);
shared actual default Result transformLazySpecification(LazySpecification that) => transformSpecification(that);
shared actual default Result transformLazySpecifier(LazySpecifier that) => transformAnySpecifier(that);
shared actual default Result transformLengthTupleType(LengthTupleType that) => transformTupleType(that);
shared actual default Result transformLetExpression(LetExpression that) => transformExpression(that);
shared actual default Result transformLiteral(Literal that) => transformAtom(that);
shared actual default Result transformLocalModifier(LocalModifier that) => transformTypeModifier(that);
Expand Down Expand Up @@ -271,6 +272,7 @@ shared interface WideningTransformer<out Result> satisfies Transformer<Result> {
shared actual default Result transformTuple(Tuple that) => transformAtom(that);
shared actual default Result transformTuplePattern(TuplePattern that) => transformPattern(that);
shared actual default Result transformListTupleType(ListTupleType that) => transformPrimaryType(that);
shared actual default Result transformTupleType(TupleType that) => transformPrimaryType(that);
shared actual default Result transformType(Type that) => transformTypeIsh(that);
shared actual default Result transformTypeAliasDefinition(TypeAliasDefinition that) => transformTypeDeclaration(that);
shared actual default Result transformTypeArgument(TypeArgument that) => transformTypeIsh(that);
Expand Down
32 changes: 32 additions & 0 deletions source/ceylon/ast/redhat/LengthTupleType.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import ceylon.ast.core {
LengthTupleType,
Node,
PrimaryType
}
import com.redhat.ceylon.compiler.typechecker.tree {
Tree {
JSequenceType=SequenceType
},
JNode=Node
}

"Converts a RedHat AST [[SequenceType|JSequenceType]] to a `ceylon.ast` [[LengthTupleType]]."
shared LengthTupleType lengthTupleTypeToCeylon(JSequenceType lengthTupleType, Anything(JNode,Node) update = noop) {
assert (is PrimaryType elementType = typeToCeylon(lengthTupleType.elementType, update));
assert (exists jLength = lengthTupleType.length);
value result = LengthTupleType(elementType, integerLiteralToCeylon(jLength, update));
update(lengthTupleType, result);
return result;
}

"Compiles the given [[code]] for a Length Tuple Type
into a [[LengthTupleType]] using the Ceylon compiler
(more specifically, the rule for a `primaryType`)."
shared LengthTupleType? compileLengthTupleType(String code, Anything(JNode,Node) update = noop) {
if (is JSequenceType jPrimaryType = createParser(code).primaryType(),
jPrimaryType.length exists) {
return lengthTupleTypeToCeylon(jPrimaryType, update);
} else {
return null;
}
}
56 changes: 35 additions & 21 deletions source/ceylon/ast/redhat/RedHatTransformer.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,15 @@ shared class RedHatTransformer(TokenFactory tokens) satisfies ImmediateNarrowing
return ret;
}

shared actual JSequenceType transformLengthTupleType(LengthTupleType that) {
JSequenceType ret = JSequenceType(null);
ret.elementType = transformPrimaryType(that.elementType);
ret.endToken = tokens.token("[", lbracket);
ret.length = transformIntegerLiteral(that.length);
ret.endToken = tokens.token("]", rbracket);
return ret;
}

shared actual JLetExpression transformLetExpression(LetExpression that) {
JLetExpression ret = JLetExpression(null);
JLetClause letClause = JLetClause(tokens.token("let", letType));
Expand All @@ -2179,6 +2188,30 @@ shared class RedHatTransformer(TokenFactory tokens) satisfies ImmediateNarrowing
shared actual JIdentifier transformLIdentifier(LIdentifier that)
=> JIdentifier(tokens.token(that.name, lidentifier, that.usePrefix then that.name.size + 2 else that.name.size));

shared actual JTupleType transformListTupleType(ListTupleType that) {
JTupleType ret = JTupleType(tokens.token("[", lbracket));
value firstElementType = that.typeList.elements.first;
if (exists firstElementType) {
switch (firstElementType)
case (is Type) { ret.addElementType(transformType(firstElementType)); }
case (is DefaultedType) { ret.addElementType(transformDefaultedType(firstElementType)); }
for (elementType in that.typeList.elements.rest) {
ret.endToken = tokens.token(",", comma);
switch (elementType)
case (is Type) { ret.addElementType(transformType(elementType)); }
case (is DefaultedType) { ret.addElementType(transformDefaultedType(elementType)); }
}
}
if (exists var = that.typeList.variadic) {
if (that.typeList.elements nonempty) {
ret.endToken = tokens.token(",", comma);
}
ret.addElementType(transformVariadicType(var));
}
ret.endToken = tokens.token("]", rbracket);
return ret;
}

shared actual JLiteral transformLiteral(Literal that) {
assert (is JLiteral ret = super.transformLiteral(that));
return ret;
Expand Down Expand Up @@ -3154,27 +3187,8 @@ shared class RedHatTransformer(TokenFactory tokens) satisfies ImmediateNarrowing
return ret;
}

shared actual JTupleType transformListTupleType(ListTupleType that) {
JTupleType ret = JTupleType(tokens.token("[", lbracket));
value firstElementType = that.typeList.elements.first;
if (exists firstElementType) {
switch (firstElementType)
case (is Type) { ret.addElementType(transformType(firstElementType)); }
case (is DefaultedType) { ret.addElementType(transformDefaultedType(firstElementType)); }
for (elementType in that.typeList.elements.rest) {
ret.endToken = tokens.token(",", comma);
switch (elementType)
case (is Type) { ret.addElementType(transformType(elementType)); }
case (is DefaultedType) { ret.addElementType(transformDefaultedType(elementType)); }
}
}
if (exists var = that.typeList.variadic) {
if (that.typeList.elements nonempty) {
ret.endToken = tokens.token(",", comma);
}
ret.addElementType(transformVariadicType(var));
}
ret.endToken = tokens.token("]", rbracket);
shared actual JTupleType|JSequenceType transformTupleType(TupleType that) {
assert (is JTupleType|JSequenceType ret = super.transformTupleType(that));
return ret;
}

Expand Down
33 changes: 33 additions & 0 deletions source/ceylon/ast/redhat/TupleType.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import ceylon.ast.core {
TupleType,
Node
}
import com.redhat.ceylon.compiler.typechecker.tree {
Tree {
JSequenceType=SequenceType,
JTupleType=TupleType
},
JNode=Node
}

"Converts a RedHat AST [[TupleType|JTupleType]] or [[SequenceType|JSequenceType]] to a `ceylon.ast` [[TupleType]]."
shared TupleType tupleTypeToCeylon(JTupleType|JSequenceType tupleType, Anything(JNode,Node) update = noop) {
switch (tupleType)
case (is JTupleType) { return listTupleTypeToCeylon(tupleType, update); }
case (is JSequenceType) { return lengthTupleTypeToCeylon(tupleType, update); }
}

"Compiles the given [[code]] for a Tuple Type
into a [[TupleType]] using the Ceylon compiler
(more specifically, the rule for a `primaryType`)."
shared TupleType? compileTupleType(String code, Anything(JNode,Node) update = noop) {
if (is JTupleType|JSequenceType jPrimaryType = createParser(code).primaryType()) {
if (is JSequenceType jPrimaryType, !jPrimaryType.length exists) {
return null;
} else {
return tupleTypeToCeylon(jPrimaryType, update);
}
} else {
return null;
}
}
8 changes: 7 additions & 1 deletion source/ceylon/ast/redhat/Type.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ shared Type typeToCeylon(JStaticType type, Anything(JNode,Node) update = noop) {
switch (type)
case (is JSimpleType) { return simpleTypeToCeylon(type, update); }
case (is JOptionalType) { return optionalTypeToCeylon(type, update); }
case (is JSequenceType) { return sequentialTypeToCeylon(type, update); }
case (is JSequenceType) {
if (type.length exists) {
return lengthTupleTypeToCeylon(type, update);
} else {
return sequentialTypeToCeylon(type, update);
}
}
case (is JTupleType) { return listTupleTypeToCeylon(type, update); }
case (is JIterableType) { return iterableTypeToCeylon(type, update); }
case (is JUnionType) { return unionTypeToCeylon(type, update); }
Expand Down
Loading

0 comments on commit 8b6c3fd

Please sign in to comment.