range literals initial

This commit is contained in:
Dmitry Jemerov
2011-04-28 19:24:07 +02:00
parent 5e2d8869cf
commit b95498624f
7 changed files with 72 additions and 0 deletions
+1
View File
@@ -6,6 +6,7 @@
<module fileurl="file://$PROJECT_DIR$/examples/examples.iml" filepath="$PROJECT_DIR$/examples/examples.iml" />
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
</modules>
</component>
</project>
+1
View File
@@ -10,6 +10,7 @@
<orderEntry type="jdk" jdkName="IDEA 10.x" jdkType="IDEA JDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="asm" level="project" />
<orderEntry type="module" module-name="stdlib" />
</component>
</module>
@@ -4,6 +4,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.tree.IElementType;
import jet.IntRange;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -32,11 +33,15 @@ public class ExpressionCodegen extends JetVisitor {
private static final String CLASS_ITERABLE = "java/lang/Iterable";
private static final String CLASS_ITERATOR = "java/util/Iterator";
private static final String CLASS_INT_RANGE = "jet/IntRange";
private static final String ITERABLE_ITERATOR_DESCRIPTOR = "()Ljava/util/Iterator;";
private static final String ITERATOR_HASNEXT_DESCRIPTOR = "()Z";
private static final String ITERATOR_NEXT_DESCRIPTOR = "()Ljava/lang/Object;";
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
private static final Type ITERATOR_TYPE = Type.getType(Iterator.class);
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
private final Stack<Label> myContinueTargets = new Stack<Label>();
private final Stack<Label> myBreakTargets = new Stack<Label>();
@@ -706,6 +711,9 @@ public class ExpressionCodegen extends JetVisitor {
else if (opToken == JetTokens.ELVIS) {
generateElvis(expression);
}
else if (opToken == JetTokens.RANGE) {
generateRange(expression);
}
else {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
if (op instanceof FunctionDescriptor) {
@@ -816,6 +824,21 @@ public class ExpressionCodegen extends JetVisitor {
myStack.push(StackValue.onStack(exprType));
}
private void generateRange(JetBinaryExpression expression) {
final Type leftType = expressionType(expression.getLeft());
if (isIntPrimitive(leftType)) {
v.anew(INT_RANGE_TYPE);
v.dup();
gen(expression.getLeft(), Type.INT_TYPE);
gen(expression.getRight(), Type.INT_TYPE);
v.invokespecial(CLASS_INT_RANGE, "<init>", INT_RANGE_CONSTRUCTOR_DESCRIPTOR);
myStack.push(StackValue.onStack(INT_RANGE_TYPE));
}
else {
throw new UnsupportedOperationException("ranges are only supported for int objects");
}
}
private static boolean isNumberPrimitive(DeclarationDescriptor descriptor) {
if (!(descriptor instanceof ClassDescriptor)) {
return false;
@@ -1,5 +1,6 @@
package org.jetbrains.jet.codegen;
import jet.IntRange;
import org.jetbrains.jet.parsing.JetParsingTest;
import java.awt.*;
@@ -358,4 +359,13 @@ public class NamespaceGenTest extends CodegenTestCase {
main.invoke(null, new Object[] { data });
assertEquals(10, data[0]);
}
public void testIntRange() throws Exception {
loadText("fun foo() = 1..10");
final Method main = generateFunction();
IntRange result = (IntRange) main.invoke(null);
assertTrue(result.contains(1));
assertTrue(result.contains(10));
assertFalse(result.contains(11));
}
}
+20
View File
@@ -0,0 +1,20 @@
package jet;
public class IntRange implements Range<Integer> {
private final int startValue;
private final int endValue;
public IntRange(int startValue, int endValue) {
this.startValue = startValue;
this.endValue = endValue;
}
@Override
public boolean contains(Integer item) {
if (item == null) return false;
if (startValue <= endValue) {
return item >= startValue && item <= endValue;
}
return item <= startValue && item >= endValue;
}
}
+5
View File
@@ -0,0 +1,5 @@
package jet;
public interface Range<T extends Comparable<T>> {
boolean contains(T item);
}
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>