diff --git a/bin/kotlin b/bin/kotlin new file mode 100755 index 00000000000..dac7f9ffec1 --- /dev/null +++ b/bin/kotlin @@ -0,0 +1,30 @@ +#!/bin/sh -e + +die() { + echo "$@" >&2 + exit 1 +} + +root=`cd $(dirname $0)/..; pwd` + +ideaRoot= +for d in /Applications/Nika-*.app; do + if [ -d "$d/lib" ]; then + ideaRoot="$d" + break + fi +done + +test -n "$ideaRoot" || die "Idea root not found" + +classpath="$root/out/production/cli" +classpath="$classpath:$root/out/production/backend:$root/out/production/frontend:$root/out/production/frontend.java" +classpath="$classpath:$root/out/production/stdlib" +classpath="$classpath:$root/lib/*:$ideaRoot/lib/*:$ideaRoot/lib/rt/*" + +exec java \ + -classpath "$classpath" \ + org.jetbrains.jet.cli.KotlinCompiler \ + "$@" + +# vim: set ts=4 sw=4 et: diff --git a/build.xml b/build.xml index 952ccdd3dba..c6aa63a9a03 100644 --- a/build.xml +++ b/build.xml @@ -2,9 +2,10 @@ + - + @@ -35,6 +36,7 @@ + @@ -73,7 +75,7 @@ - + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index cb4a2600153..da59861265d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1046,11 +1046,10 @@ public class ExpressionCodegen extends JetVisitor { isInterface = CodegenUtil.isInterface(containingDeclaration); } else { - if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT) - isInterface = false; + if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) + isInterface = true; else { - JetClass jetClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration); - isInterface = jetClass == null || jetClass.isTrait(); + isInterface = false; } } } @@ -2768,7 +2767,11 @@ If finally block is present, its last expression is the value of try expression. JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, rangeExpression); assert jetType != null; final DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); - if (isClass(descriptor, "IntRange")) { + if (isClass(descriptor, "IntRange") || + isClass(descriptor, "CharRange") || + isClass(descriptor, "ByteRange") || + isClass(descriptor, "LongRange") || + isClass(descriptor, "ShortRange")) { return true; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 15da00768dd..2939e4ba879 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -92,6 +92,7 @@ public class IntrinsicMethods { declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray()); declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure()); declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 1, new StupidSync()); + declareOverload(myStdLib.getLibraryScope().getFunctions("iterator"), 0, new IteratorIterator()); declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT); declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java new file mode 100644 index 00000000000..53a62983440 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java @@ -0,0 +1,21 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; + +import java.util.List; + +/** + * @author alex.tkachman + */ +public class IteratorIterator implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver) { + return receiver; + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java index c742cd0d633..3dc18b19361 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java @@ -19,23 +19,26 @@ public class RangeTo implements IntrinsicMethod { @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { if(arguments.size()==1) { + final Type leftType = receiver.type; + final Type rightType = codegen.expressionType(arguments.get(0)); receiver.put(Type.INT_TYPE, v); - codegen.gen(arguments.get(0), Type.INT_TYPE); - v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;"); - return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE); + codegen.gen(arguments.get(0), rightType); + v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); + return StackValue.onStack(expectedType); } else { JetBinaryExpression expression = (JetBinaryExpression) element; final Type leftType = codegen.expressionType(expression.getLeft()); - if (JetTypeMapper.isIntPrimitive(leftType)) { - codegen.gen(expression.getLeft(), Type.INT_TYPE); - codegen.gen(expression.getRight(), Type.INT_TYPE); - v.invokestatic(expectedType.getInternalName(), "rangeTo", "(" + leftType.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); - return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE); - } - else { - throw new UnsupportedOperationException("ranges are only supported for int objects"); - } + final Type rightType = codegen.expressionType(expression.getRight()); +// if (JetTypeMapper.isIntPrimitive(leftType)) { + codegen.gen(expression.getLeft(), leftType); + codegen.gen(expression.getRight(), rightType); + v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); + return StackValue.onStack(expectedType); +// } +// else { +// throw new UnsupportedOperationException("ranges are only supported for int objects"); +// } } } } diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java index 1eab1a0e29b..66c129f3ef9 100644 --- a/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java +++ b/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java @@ -120,7 +120,7 @@ public class CompileEnvironment { rtJar = findActiveRtJar(failOnError); if ((rtJar == null || !rtJar.exists())) { - throw new CompileEnvironmentException("No rt.jar found under JAVA_HOME=" + javaHome); + throw new CompileEnvironmentException("No JDK rt.jar found under JAVA_HOME=" + javaHome); } } return rtJar; @@ -337,10 +337,12 @@ public class CompileEnvironment { } } - public void compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) { + public boolean compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime, boolean includeSources) { CompileSession session = new CompileSession(myEnvironment); session.addSources(sourceFileOrDir); - session.addStdLibSources(false); + if (includeSources) { + session.addStdLibSources(false); + } String mainClass = null; for (JetFile file : session.getSourceFileNamespaces()) { @@ -350,7 +352,7 @@ public class CompileEnvironment { } } if (!session.analyze(myErrorStream)) { - return; + return false; } ClassFileFactory factory = session.generate(); @@ -367,6 +369,7 @@ public class CompileEnvironment { else { throw new CompileEnvironmentException("Output directory or jar file is not specified - no files will be saved to the disk"); } + return true; } public static void writeToOutputDirectory(ClassFileFactory factory, final String outputDir) { diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java index 56db85a522d..8daf27b6cf8 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java @@ -25,6 +25,8 @@ public class KotlinCompiler { public String module; @Argument(value = "includeRuntime", description = "include Kotlin runtime in to resulting jar") public boolean includeRuntime; + @Argument(value = "excludeStdlib", description = "do not load stdlib (to compile stdlib itself)") + public boolean excludeStdlib; } public static void main(String[] args) { @@ -33,9 +35,14 @@ public class KotlinCompiler { try { Args.parse(arguments, args); } - catch (Throwable t) { + catch (IllegalArgumentException e) { System.out.println("Usage: KotlinCompiler [-output |-jar ] [-src |-module ] [-includeRuntime]"); + System.exit(1); + return; + } + catch (Throwable t) { t.printStackTrace(); + System.exit(1); return; } @@ -44,7 +51,8 @@ public class KotlinCompiler { try { environment.setJavaRuntime(CompileEnvironment.findRtJar(true)); if (!environment.initializeKotlinRuntime()) { - System.out.println("No runtime library found"); + System.err.println("No Kotlin runtime library found"); + System.exit(1); return; } @@ -53,10 +61,15 @@ public class KotlinCompiler { return; } else { - environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime); + if (!environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime, !arguments.excludeStdlib)) { + System.exit(1); + return; + } } } catch (CompileEnvironmentException e) { - System.out.println(e.getMessage()); + System.err.println(e.getMessage()); + System.exit(1); + return; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index fb9e23b0585..dd239673dfe 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -138,7 +138,7 @@ public class JavaDescriptorResolver { @Nullable public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) { String qualifiedName = psiClass.getQualifiedName(); - + if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { // TODO: only if -$$TImpl class is created by Kotlin return null; @@ -161,7 +161,7 @@ public class JavaDescriptorResolver { @Nullable public ClassDescriptor resolveClass(@NotNull String qualifiedName) { - + if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { // TODO: only if -$$TImpl class is created by Kotlin return null; @@ -356,7 +356,7 @@ public class JavaDescriptorResolver { @Override public JetSignatureVisitor visitClassBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { + return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { if (isJavaLangObject(jetType)) { @@ -369,7 +369,7 @@ public class JavaDescriptorResolver { @Override public JetSignatureVisitor visitInterfaceBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { + return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { upperBounds.add(jetType); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java index c4b9053e3a1..ab9b7350f29 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java @@ -21,7 +21,7 @@ public class JavaSemanticServices { public JavaSemanticServices(Project project, JetSemanticServices jetSemanticServices, BindingTrace trace) { this.trace = trace; this.descriptorResolver = new JavaDescriptorResolver(project, this); - this.typeTransformer = new JavaTypeTransformer(jetSemanticServices.getStandardLibrary(), descriptorResolver); + this.typeTransformer = new JavaTypeTransformer(this, jetSemanticServices.getStandardLibrary(), descriptorResolver); this.jetSemanticServices = jetSemanticServices; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 40a6c60b35d..96e64c6f08c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -19,12 +19,15 @@ import java.util.Map; */ public class JavaTypeTransformer { + private final JavaSemanticServices javaSemanticServices; private final JavaDescriptorResolver resolver; private final JetStandardLibrary standardLibrary; private Map primitiveTypesMap; private Map classTypesMap; + private Map classDescriptorMap; - public JavaTypeTransformer(JetStandardLibrary standardLibrary, JavaDescriptorResolver resolver) { + public JavaTypeTransformer(JavaSemanticServices javaSemanticServices, JetStandardLibrary standardLibrary, JavaDescriptorResolver resolver) { + this.javaSemanticServices = javaSemanticServices; this.resolver = resolver; this.standardLibrary = standardLibrary; } @@ -61,7 +64,7 @@ public class JavaTypeTransformer { @NotNull public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) { final JetType[] r = new JetType[1]; - JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary, typeVariableResolver) { + JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(javaSemanticServices, standardLibrary, typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { r[0] = jetType; @@ -197,4 +200,21 @@ public class JavaTypeTransformer { } return classTypesMap; } + + public Map getPrimitiveWrappersClassDescriptorMap() { + if (classDescriptorMap == null) { + classDescriptorMap = new HashMap(); + classDescriptorMap.put("java.lang.Byte", standardLibrary.getByte()); + classDescriptorMap.put("java.lang.Short", standardLibrary.getShort()); + classDescriptorMap.put("java.lang.Character", standardLibrary.getChar()); + classDescriptorMap.put("java.lang.Integer", standardLibrary.getInt()); + classDescriptorMap.put("java.lang.Long", standardLibrary.getLong()); + classDescriptorMap.put("java.lang.Float", standardLibrary.getFloat()); + classDescriptorMap.put("java.lang.Double", standardLibrary.getDouble()); + classDescriptorMap.put("java.lang.Boolean", standardLibrary.getBoolean()); + //classDescriptorMap.put("java.lang.Object", standardLibrary.get + classDescriptorMap.put("java.lang.String", standardLibrary.getString()); + } + return classDescriptorMap; + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 520da450766..0f51cf0df1e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetStandardClasses; @@ -24,12 +23,14 @@ import java.util.List; */ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAdapter { + private final JavaSemanticServices javaSemanticServices; private final JavaDescriptorResolver javaDescriptorResolver; private final JetStandardLibrary jetStandardLibrary; private final TypeVariableResolver typeVariableResolver; - public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary, TypeVariableResolver typeVariableResolver) { - this.javaDescriptorResolver = javaDescriptorResolver; + public JetTypeJetSignatureReader(JavaSemanticServices javaSemanticServices, JetStandardLibrary jetStandardLibrary, TypeVariableResolver typeVariableResolver) { + this.javaSemanticServices = javaSemanticServices; + this.javaDescriptorResolver = javaSemanticServices.getDescriptorResolver(); this.jetStandardLibrary = jetStandardLibrary; this.typeVariableResolver = typeVariableResolver; } @@ -95,7 +96,13 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public void visitClassType(String name, boolean nullable) { String ourName = name.replace('/', '.'); - this.classDescriptor = javaDescriptorResolver.resolveClass(ourName); + + this.classDescriptor = this.javaSemanticServices.getTypeTransformer().getPrimitiveWrappersClassDescriptorMap().get(ourName); + + if (this.classDescriptor == null) { + this.classDescriptor = javaDescriptorResolver.resolveClass(ourName); + } + if (this.classDescriptor == null) { throw new IllegalStateException("class not found by name: " + ourName); // TODO: wrong exception } @@ -114,7 +121,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public JetSignatureVisitor visitTypeArgument(final char wildcard) { - return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) { + return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { @@ -125,7 +132,19 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public JetSignatureVisitor visitArrayType(final boolean nullable) { - return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) { + return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { + @Override + public void visitBaseType(char descriptor, boolean nullable) { + JetType primitiveType = getPrimitiveType(descriptor, nullable); + JetType arrayType; + if (!nullable) { + arrayType = jetStandardLibrary.getPrimitiveArrayType(primitiveType); + } else { + arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(primitiveType), nullable); + } + JetTypeJetSignatureReader.this.done(arrayType); + } + @Override protected void done(@NotNull JetType jetType) { JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable); diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 48e139cbb96..f782b5e0473 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -22,53 +22,71 @@ fun T?.sure() : T fun String?.plus(other: Any?) : String +fun Iterator.iterator() : Iterator + trait Iterator { fun next() : T val hasNext : Boolean } +fun ByteIterator.iterator() : ByteIterator + abstract open class ByteIterator() : Iterator { abstract open fun nextByte() : Byte override fun next() : Byte } +fun ShortIterator.iterator() : ShortIterator + abstract open class ShortIterator() : Iterator { abstract open fun nextShort() : Short override fun next() : Short } +fun CharIterator.iterator() : CharIterator + abstract open class CharIterator() : Iterator { abstract open fun nextChar() : Char override fun next() : Char } +fun IntIterator.iterator() : IntIterator + abstract open class IntIterator() : Iterator { abstract open fun nextInt() : Int override fun next() : Int } +fun LongIterator.iterator() : LongIterator + abstract open class LongIterator() : Iterator { abstract open fun nextLong() : Long override fun next() : Long } +fun FloatIterator.iterator() : FloatIterator + abstract open class FloatIterator() : Iterator { abstract open fun nextFloat() : Float override fun next() : Float } +fun DoubleIterator.iterator() : DoubleIterator + abstract open class DoubleIterator() : Iterator { abstract open fun nextDouble() : Double override fun next() : Double } +fun BooleanIterator.iterator() : BooleanIterator + abstract open class BooleanIterator() : Iterator { abstract open fun nextBoolean() : Boolean @@ -238,7 +256,7 @@ trait Range> { fun contains(item : T) : Boolean } -class IntRange(val start : Int, val size : Int, val isReversed : Boolean = false) : Range, IntIterable { +class IntRange(val start : Int, val size : Int) : Range, IntIterable { fun iterator () : IntIterator fun contains (elem: Int) : Boolean @@ -247,10 +265,12 @@ class IntRange(val start : Int, val size : Int, val isReversed : Boolean = false fun minus() : IntRange - fun step(step: Int) : IntIterable + fun step(step: Int) : IntIterator + + val isReversed : Boolean } -class LongRange(val start : Long, val size : Long, val isReversed : Boolean = false) : Range, LongIterable { +class LongRange(val start : Long, val size : Long) : Range, LongIterable { fun iterator () : LongIterator fun contains (elem: Long) : Boolean @@ -259,10 +279,12 @@ class LongRange(val start : Long, val size : Long, val isReversed : Boolean = fa fun minus() : LongRange - fun step(step: Long) : LongIterable + fun step(step: Long) : LongIterator + + val isReversed : Boolean } -class ByteRange(val start : Byte, val size : Int, val isReversed : Boolean = false) : Range, ByteIterable { +class ByteRange(val start : Byte, val size : Int) : Range, ByteIterable { fun iterator () : ByteIterator fun contains (elem: Byte) : Boolean @@ -271,10 +293,12 @@ class ByteRange(val start : Byte, val size : Int, val isReversed : Boolean = fal fun minus() : ByteRange - fun step(step: Int) : ByteIterable + fun step(step: Int) : ByteIterator + + val isReversed : Boolean } -class ShortRange(val start : Short, val size : Int, val isReversed : Boolean = false) : Range, ShortIterable { +class ShortRange(val start : Short, val size : Int) : Range, ShortIterable { fun iterator () : ShortIterator fun contains (elem: Byte) : Boolean @@ -283,10 +307,12 @@ class ShortRange(val start : Short, val size : Int, val isReversed : Boolean = f fun minus() : ShortRange - fun step(step: Int) : ShortIterable + fun step(step: Int) : ShortIterator + + val isReversed : Boolean } -class CharRange(val start : Char, val size : Int, val isReversed : Boolean = false) : Range, CharIterable { +class CharRange(val start : Char, val size : Int) : Range, CharIterable { fun iterator () : CharIterator fun contains (elem: Char) : Boolean @@ -295,7 +321,33 @@ class CharRange(val start : Char, val size : Int, val isReversed : Boolean = fal fun minus() : CharRange - fun step(step: Int) : CharIterable + fun step(step: Int) : CharIterator + + val isReversed : Boolean +} + +class FloatRange(val start : Float, val size : Float) : Range { + fun contains (elem: Float) : Boolean + + val end : Float + + fun minus() : FloatRange + + fun step(step: Float) : FloatIterator + + val isReversed : Boolean +} + +class DoubleRange(val start : Double, val size : Double) : Range { + fun contains (elem: Double) : Boolean + + val end : Double + + fun minus() : DoubleRange + + fun step(step: Double) : DoubleIterator + + val isReversed : Boolean } abstract class Number : Hashable { @@ -363,13 +415,13 @@ class Double : Number, Comparable { fun mod(other : Short) : Double fun mod(other : Byte) : Double - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range - fun rangeTo(other : Long) : Range - fun rangeTo(other : Int) : Range - fun rangeTo(other : Short) : Range - fun rangeTo(other : Byte) : Range - fun rangeTo(other : Char) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : DoubleRange + fun rangeTo(other : Long) : DoubleRange + fun rangeTo(other : Int) : DoubleRange + fun rangeTo(other : Short) : DoubleRange + fun rangeTo(other : Byte) : DoubleRange + fun rangeTo(other : Char) : DoubleRange fun inc() : Double fun dec() : Double @@ -426,13 +478,13 @@ class Float : Number, Comparable { fun mod(other : Byte) : Float fun mod(other : Char) : Float - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range - fun rangeTo(other : Long) : Range - fun rangeTo(other : Int) : Range - fun rangeTo(other : Short) : Range - fun rangeTo(other : Byte) : Range - fun rangeTo(other : Char) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange + fun rangeTo(other : Long) : DoubleRange + fun rangeTo(other : Int) : DoubleRange + fun rangeTo(other : Short) : FloatRange + fun rangeTo(other : Byte) : FloatRange + fun rangeTo(other : Char) : FloatRange fun inc() : Float fun dec() : Float @@ -489,8 +541,8 @@ class Long : Number, Comparable { fun mod(other : Byte) : Long fun mod(other : Char) : Long - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : LongRange fun rangeTo(other : Short) : LongRange @@ -560,8 +612,8 @@ class Int : Number, Comparable { fun mod(other : Byte) : Int fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : IntRange @@ -631,12 +683,12 @@ class Char : Number, Comparable { fun mod(other : Byte) : Int // fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange - fun rangeTo(other : Short) : IntRange - fun rangeTo(other : Byte) : IntRange + fun rangeTo(other : Short) : ShortRange + fun rangeTo(other : Byte) : CharRange fun rangeTo(other : Char) : CharRange fun inc() : Char @@ -694,8 +746,8 @@ class Short : Number, Comparable { fun mod(other : Byte) : Int fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange @@ -757,8 +809,8 @@ class Byte : Number, Comparable { fun mod(other : Byte) : Int fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index 186e94242d3..6c23f5d6422 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -504,6 +504,14 @@ public class JetStandardLibrary { initStdClasses(); return doubleArrayType; } + + public JetType getPrimitiveArrayType(JetType jetType) { + if (jetType.equals(getIntType())) { + return getIntArrayType(); + } else { + throw new IllegalStateException("not implemented"); + } + } public ClassDescriptor getByteArrayClass() { initStdClasses(); diff --git a/compiler/testData/codegen/regressions/kt765.kt b/compiler/testData/codegen/regressions/kt765.kt new file mode 100644 index 00000000000..e2869f81853 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt765.kt @@ -0,0 +1,13 @@ +fun box() : String { + System.out?.println(System.out?.println(10.flt..11.flt)) + + for(f in 10.flt..11.flt step 0.3.flt) { + System.out?.println(f) + } + + for(f in 10.dbl..11.dbl step 0.3.dbl) { + System.out?.println(f) + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/regressions/kt821.kt b/compiler/testData/codegen/regressions/kt821.kt index c9eea791ac6..47b7d3f465f 100644 --- a/compiler/testData/codegen/regressions/kt821.kt +++ b/compiler/testData/codegen/regressions/kt821.kt @@ -2,9 +2,6 @@ fun box() : String { val r1 = IntRange(1, 4) if(r1.end != 4 || r1.isReversed || r1.size != 4) return "fail" - val r2 = IntRange(1, 4, true) - if(r2.end != -2 || !r2.isReversed || r2.size != 4) return "fail" - val r3 = -(0..5) if(r3.start != 5 || r3.end != 0 || !r3.isReversed || r3.size != 6) return "fail" @@ -14,9 +11,6 @@ fun box() : String { val r5 = ByteRange(1, 4) if(r5.end != 4.byt || r5.isReversed || r5.size != 4) return "fail" - val r6 = ByteRange(1, 4, true) - if(r6.end != -2.byt || !r6.isReversed) return "fail" - val r7 = -(0.byt..5.byt) if(r7.start != 5.byt || r7.end != 0.byt || !r7.isReversed) return "fail" @@ -26,9 +20,6 @@ fun box() : String { val r10 = ShortRange(1, 4) if(r10.end != 4.sht || r10.isReversed || r10.size != 4) return "fail" - val r11 = ShortRange(1, 4, true) - if(r11.end != -2.sht || !r11.isReversed) return "fail" - val r12 = -(0.sht..5.sht) if(r12.start != 5.sht || r12.end != 0.sht || !r12.isReversed) return "fail" @@ -38,9 +29,6 @@ fun box() : String { val r14 = CharRange('a', 4) if(r14.end != 'd' || r14.isReversed || r14.size != 4) return "fail" - val r15 = CharRange('D', 4, true) - if(r15.end != 'A' || !r15.isReversed) return "fail" - val r16 = -('a'..'e') if(r16.start != 'e' || r16.end != 'a' || !r16.isReversed) return "fail" diff --git a/compiler/testData/codegen/regressions/kt925.kt b/compiler/testData/codegen/regressions/kt925.kt new file mode 100644 index 00000000000..2db14c16b4b --- /dev/null +++ b/compiler/testData/codegen/regressions/kt925.kt @@ -0,0 +1,54 @@ +fun test1() : Boolean { + val r1 = 1..10 + var s1 = 0 + for(e in r1 step 2) { + s1 += e + } + return s1 == 25 +} + +fun test2() : Boolean { + val r1 = 1.byt..10.byt + var s1 = 0 + for(e in r1 step 2) { + s1 += e + } + return s1 == 25 +} + +fun test3() : Boolean { + val r1 = 1.byt..10.lng + var s1 = 0.lng + for(e in r1 step 2) { + s1 += e + } + return s1 == 25.lng +} + +fun test4() : Boolean { + val r1 = 1.byt..10.sht + var s1 = 0.sht + for(e in r1 step 2) { + s1 += e + } + return s1 == 25.sht +} + +fun test5() : Boolean { + val r1 = 'a'..'h' + var s1 = 0 + for(e in r1 step 2) { + s1 ++ + } + return s1 == 4 +} + +fun box() : String { + if(test1().not()) return "test1 failed" + if(test2().not()) return "test2 failed" + if(test3().not()) return "test3 failed" + if(test4().not()) return "test4 failed" + if(test5().not()) return "test4 failed" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/readClass/type/Int.kt b/compiler/testData/readClass/type/Int.kt new file mode 100644 index 00000000000..0a3853f134f --- /dev/null +++ b/compiler/testData/readClass/type/Int.kt @@ -0,0 +1,3 @@ +package test + +fun fff(): Int = 1 diff --git a/compiler/testData/readClass/type/IntArray.kt b/compiler/testData/readClass/type/IntArray.kt new file mode 100644 index 00000000000..8fc8ef58b92 --- /dev/null +++ b/compiler/testData/readClass/type/IntArray.kt @@ -0,0 +1,3 @@ +package test + +fun nothing(): IntArray = throw Exception() diff --git a/compiler/testData/readClass/type/IntQ.kt b/compiler/testData/readClass/type/IntQ.kt new file mode 100644 index 00000000000..8ccad22eeb6 --- /dev/null +++ b/compiler/testData/readClass/type/IntQ.kt @@ -0,0 +1,3 @@ +package test + +fun fff(): Int? = 1 diff --git a/compiler/testData/writeSignature/ArrayOfCharSequence.kt b/compiler/testData/writeSignature/ArrayOfCharSequence.kt new file mode 100644 index 00000000000..ff263b502d5 --- /dev/null +++ b/compiler/testData/writeSignature/ArrayOfCharSequence.kt @@ -0,0 +1,6 @@ +fun never(): Array = throw Exception() + +// method: namespace::never +// jvm signature: ()[Ljava/lang/CharSequence; +// generic signature: null +// kotlin signature: ()[Ljava/lang/CharSequence; // TODO: need to skip kotlin signature diff --git a/compiler/testData/writeSignature/ArrayOfInt.kt b/compiler/testData/writeSignature/ArrayOfInt.kt new file mode 100644 index 00000000000..934bbb102d6 --- /dev/null +++ b/compiler/testData/writeSignature/ArrayOfInt.kt @@ -0,0 +1,6 @@ +fun never(): Array = throw Exception() + +// method: namespace::never +// jvm signature: ()[Ljava/lang/Integer; +// generic signature: null +// kotlin signature: ()[Ljava/lang/Integer; // TODO: need to skip kotlin signature diff --git a/compiler/testData/writeSignature/IntArray.kt b/compiler/testData/writeSignature/IntArray.kt new file mode 100644 index 00000000000..72062baedde --- /dev/null +++ b/compiler/testData/writeSignature/IntArray.kt @@ -0,0 +1,6 @@ +fun never(): IntArray = throw Exception() + +// method: namespace::never +// jvm signature: ()[I +// generic signature: null +// kotlin signature: ()[I // TODO: need to skip kotlin signature diff --git a/compiler/testData/writeSignature/ListOfString.kt b/compiler/testData/writeSignature/ListOfCharSequence.kt similarity index 100% rename from compiler/testData/writeSignature/ListOfString.kt rename to compiler/testData/writeSignature/ListOfCharSequence.kt diff --git a/compiler/tests/org/jetbrains/jet/WriteSignatureTest.java b/compiler/tests/org/jetbrains/jet/WriteSignatureTest.java index 278772c9dae..f648e4dc260 100644 --- a/compiler/tests/org/jetbrains/jet/WriteSignatureTest.java +++ b/compiler/tests/org/jetbrains/jet/WriteSignatureTest.java @@ -210,8 +210,8 @@ public class WriteSignatureTest extends TestCaseWithTmpdir { new ClassReader(classInputStream).accept(visitor, ClassReader.SKIP_CODE|ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES); - Assert.assertNotNull(visitor.readSignature); - + Assert.assertNotNull("method not found: " + className + "::" + methodName, visitor.readSignature); + return visitor.readSignature; } finally { Closeables.closeQuietly(classInputStream); diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index 6275a968154..261e4450425 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -367,4 +367,12 @@ public class PrimitiveTypesTest extends CodegenTestCase { public void testKt821 () { blackBoxFile("regressions/kt821.kt"); } + + public void testKt925 () { + blackBoxFile("regressions/kt925.kt"); + } + + public void testKt765 () { + blackBoxFile("regressions/kt765.kt"); + } } diff --git a/stdlib/src/jet/ByteRange.java b/stdlib/src/jet/ByteRange.java index 754445a4459..bb81716170e 100644 --- a/stdlib/src/jet/ByteRange.java +++ b/stdlib/src/jet/ByteRange.java @@ -11,14 +11,6 @@ public final class ByteRange implements Range, ByteIterable, JetObject { this.count = count; } - public ByteRange(byte startValue, int count, boolean reversed) { - this(startValue, reversed ? -count : count); - } - - public ByteRange(byte startValue, int count, boolean reversed, int defaultMask) { - this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); - } - @Override public boolean contains(Byte item) { if (item == null) return false; @@ -44,13 +36,20 @@ public final class ByteRange implements Range, ByteIterable, JetObject { return count < 0 ? -count : count; } + public ByteIterator step(int step) { + if(step < 0) + return new MyIterator(getEnd(), -count, -step); + else + return new MyIterator(start, count, step); + } + public ByteRange minus() { return new ByteRange(getEnd(), -count); } @Override public ByteIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -67,27 +66,27 @@ public final class ByteRange implements Range, ByteIterable, JetObject { return new ByteRange((byte) 0, length); } - public static ByteRange rangeTo(byte from, byte to) { - if(from > to) { - return new ByteRange(to, from-to+1, true); - } - else { - return new ByteRange(from, to-from+1); - } - } - private static class MyIterator extends ByteIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private byte cur; + private int step; private int count; private final boolean reversed; - public MyIterator(byte startValue, int count) { + public MyIterator(byte startValue, int count, int step) { cur = startValue; - reversed = count < 0; - this.count = reversed ? -count : count; + this.step = step; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override @@ -97,12 +96,14 @@ public final class ByteRange implements Range, ByteIterable, JetObject { @Override public byte nextByte() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (byte) (cur + step); } else { - return cur++; + cur += step; + return (byte) (cur - step); } } diff --git a/stdlib/src/jet/CharRange.java b/stdlib/src/jet/CharRange.java index e295795527e..f7721fb9140 100644 --- a/stdlib/src/jet/CharRange.java +++ b/stdlib/src/jet/CharRange.java @@ -11,14 +11,6 @@ public final class CharRange implements Range, CharIterable, JetObjec this.count = count; } - public CharRange(char startValue, int count, boolean reversed) { - this(startValue, reversed ? -count : count); - } - - public CharRange(char startValue, int count, boolean reversed, int defaultMask) { - this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); - } - @Override public boolean contains(Character item) { if (item == null) return false; @@ -48,9 +40,16 @@ public final class CharRange implements Range, CharIterable, JetObjec return new CharRange(getEnd(), -count); } + public CharIterator step(int step) { + if(step < 0) + return new MyIterator(getEnd(), -count, -step); + else + return new MyIterator(start, count, step); + } + @Override public CharIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -67,27 +66,27 @@ public final class CharRange implements Range, CharIterable, JetObjec return new CharRange((char) 0, length); } - public static CharRange rangeTo(char from, char to) { - if(from > to) { - return new CharRange(to, from-to+1, true); - } - else { - return new CharRange(from, to-from+1); - } - } - private static class MyIterator extends CharIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private char cur; + private int step; private int count; private final boolean reversed; - public MyIterator(char startValue, int count) { + public MyIterator(char startValue, int count, int step) { cur = startValue; - reversed = count < 0; - this.count = reversed ? -count : count; + this.step = step; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override @@ -97,12 +96,14 @@ public final class CharRange implements Range, CharIterable, JetObjec @Override public char nextChar() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (char) (cur + step); } else { - return cur++; + cur += step; + return (char) (cur - step); } } diff --git a/stdlib/src/jet/DoubleRange.java b/stdlib/src/jet/DoubleRange.java new file mode 100644 index 00000000000..8020039f222 --- /dev/null +++ b/stdlib/src/jet/DoubleRange.java @@ -0,0 +1,117 @@ +package jet; + +public final class DoubleRange implements Range, JetObject { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(DoubleRange.class, false); + + private final double start; + private final double size; + + public DoubleRange(double startValue, double size) { + this.start = startValue; + this.size = size; + } + + @Override + public boolean contains(Double item) { + if (item == null) return false; + if (size >= 0) { + return item >= start && item < start + size; + } + return item <= start && item > start + size; + } + + public DoubleIterator step(double step) { + if(step < 0) + return new MyIterator(getEnd(), -size, -step); + else + return new MyIterator(start, size, step); + } + + public boolean getIsReversed() { + return size < 0; + } + + public double getStart() { + return start; + } + + public double getEnd() { + return size < 0 ? start + size: start + size; + } + + public double getSize() { + return size < 0 ? -size : size; + } + + public DoubleRange minus() { + return new DoubleRange(getEnd(), -size); + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + + public static DoubleRange count(int length) { + return new DoubleRange(0, length); + } + + private static class MyIterator extends DoubleIterator { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); + + private double cur; + private double step; + private final double end; + + private final boolean reversed; + + public MyIterator(double startValue, double size, double step) { + cur = startValue; + this.step = step; + if(size < 0) { + reversed = true; + end = startValue-size; + startValue -= size; + } + else { + reversed = false; + this.end = startValue + size; + } + } + + @Override + public boolean getHasNext() { + if(reversed) + return cur >= end; + else + return cur <= end; + } + + @Override + public double nextDouble() { + if(reversed) { + cur -= step; + return cur + step; + } + else { + cur += step; + return cur - step; + } + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + } +} diff --git a/stdlib/src/jet/FloatRange.java b/stdlib/src/jet/FloatRange.java new file mode 100644 index 00000000000..e6b3b8894b2 --- /dev/null +++ b/stdlib/src/jet/FloatRange.java @@ -0,0 +1,117 @@ +package jet; + +public final class FloatRange implements Range, JetObject { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(FloatRange.class, false); + + private final float start; + private final float size; + + public FloatRange(float startValue, float size) { + this.start = startValue; + this.size = size; + } + + @Override + public boolean contains(Float item) { + if (item == null) return false; + if (size >= 0) { + return item >= start && item < start + size; + } + return item <= start && item > start + size; + } + + public FloatIterator step(float step) { + if(step < 0) + return new MyIterator(getEnd(), -size, -step); + else + return new MyIterator(start, size, step); + } + + public boolean getIsReversed() { + return size < 0; + } + + public float getStart() { + return start; + } + + public float getEnd() { + return size < 0 ? start + size: start + size; + } + + public float getSize() { + return size < 0 ? -size : size; + } + + public FloatRange minus() { + return new FloatRange(getEnd(), -size); + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + + public static FloatRange count(int length) { + return new FloatRange(0, length); + } + + private static class MyIterator extends FloatIterator { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); + + private float cur; + private float step; + private final float end; + + private final boolean reversed; + + public MyIterator(float startValue, float size, float step) { + cur = startValue; + this.step = step; + if(size < 0) { + reversed = true; + end = startValue-size; + startValue -= size; + } + else { + reversed = false; + this.end = startValue + size; + } + } + + @Override + public boolean getHasNext() { + if(reversed) + return cur >= end; + else + return cur <= end; + } + + @Override + public float nextFloat() { + if(reversed) { + cur -= step; + return cur + step; + } + else { + cur += step; + return cur - step; + } + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + } +} diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index 646a095e842..68d127ded00 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -11,14 +11,6 @@ public final class IntRange implements Range, IntIterable, JetObject { this.count = count; } - public IntRange(int startValue, int count, boolean reversed) { - this(startValue, reversed ? -count : count); - } - - public IntRange(int startValue, int count, boolean reversed, int defaultMask) { - this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); - } - @Override public boolean contains(Integer item) { if (item == null) return false; @@ -28,6 +20,13 @@ public final class IntRange implements Range, IntIterable, JetObject { return item <= start && item > start + count; } + public IntIterator step(int step) { + if(step < 0) + return new MyIterator(getEnd(), -count, -step); + else + return new MyIterator(start, count, step); + } + public boolean getIsReversed() { return count < 0; } @@ -50,7 +49,7 @@ public final class IntRange implements Range, IntIterable, JetObject { @Override public IntIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -67,27 +66,27 @@ public final class IntRange implements Range, IntIterable, JetObject { return new IntRange(0, length); } - public static IntRange rangeTo(int from, int to) { - if(from > to) { - return new IntRange(to, from-to+1, true); - } - else { - return new IntRange(from, to-from+1); - } - } - private static class MyIterator extends IntIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private int cur; + private int step; private int count; private final boolean reversed; - public MyIterator(int startValue, int count) { + public MyIterator(int startValue, int count, int step) { cur = startValue; - reversed = count < 0; - this.count = reversed ? -count : count; + this.step = step; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override @@ -97,12 +96,14 @@ public final class IntRange implements Range, IntIterable, JetObject { @Override public int nextInt() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return cur + step; } else { - return cur++; + cur += step; + return cur - step; } } diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index 3a047c7b65f..50cf408d53f 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -11,12 +11,11 @@ public final class LongRange implements Range, LongIterable, JetObject { this.count = count; } - public LongRange(long startValue, long count, boolean reversed) { - this(startValue, reversed ? -count : count); - } - - public LongRange(int startValue, int count, boolean reversed, int defaultMask) { - this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); + public LongIterator step(long step) { + if(step < 0) + return new MyIterator(getEnd(), -count, -step); + else + return new MyIterator(start, count, step); } @Override @@ -50,7 +49,7 @@ public final class LongRange implements Range, LongIterable, JetObject { @Override public LongIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -63,31 +62,31 @@ public final class LongRange implements Range, LongIterable, JetObject { return null; } - public static IntRange count(int length) { - return new IntRange(0, length); - } - - public static IntRange rangeTo(int from, int to) { - if(from > to) { - return new IntRange(to, from-to+1, true); - } - else { - return new IntRange(from, to-from+1); - } + public static LongRange count(int length) { + return new LongRange(0, length); } private static class MyIterator extends LongIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private long cur; + private long step; private long count; private final boolean reversed; - public MyIterator(long startValue, long count) { + public MyIterator(long startValue, long count, long step) { cur = startValue; - reversed = count < 0; - this.count = reversed ? -count : count; + this.step = step; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override @@ -97,12 +96,14 @@ public final class LongRange implements Range, LongIterable, JetObject { @Override public long nextLong() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (cur + step); } else { - return cur++; + cur += step; + return (cur - step); } } diff --git a/stdlib/src/jet/ShortRange.java b/stdlib/src/jet/ShortRange.java index 0d96d652d88..b00fab53562 100644 --- a/stdlib/src/jet/ShortRange.java +++ b/stdlib/src/jet/ShortRange.java @@ -11,12 +11,11 @@ public final class ShortRange implements Range, ShortIterable, JetObject this.count = count; } - public ShortRange(short startValue, int count, boolean reversed) { - this(startValue, reversed ? -count : count); - } - - public ShortRange(short startValue, int count, boolean reversed, int defaultMask) { - this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); + public ShortIterator step(int step) { + if(step < 0) + return new MyIterator(getEnd(), -count, -step); + else + return new MyIterator(start, count, step); } @Override @@ -50,7 +49,7 @@ public final class ShortRange implements Range, ShortIterable, JetObject @Override public ShortIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -67,27 +66,27 @@ public final class ShortRange implements Range, ShortIterable, JetObject return new ShortRange((byte) 0, length); } - public static ShortRange rangeTo(short from, short to) { - if(from > to) { - return new ShortRange(to, from-to+1, true); - } - else { - return new ShortRange(from, to-from+1); - } - } - private static class MyIterator extends ShortIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private short cur; + private int step; private int count; private final boolean reversed; - public MyIterator(short startValue, int count) { + public MyIterator(short startValue, int count, int step) { cur = startValue; - reversed = count < 0; - this.count = reversed ? -count : count; + this.step = step; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override @@ -97,12 +96,14 @@ public final class ShortRange implements Range, ShortIterable, JetObject @Override public short nextShort() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (short) (cur + step); } else { - return cur++; + cur += step; + return (short) (cur - step); } } diff --git a/stdlib/src/jet/runtime/Ranges.java b/stdlib/src/jet/runtime/Ranges.java new file mode 100644 index 00000000000..ff5952afe03 --- /dev/null +++ b/stdlib/src/jet/runtime/Ranges.java @@ -0,0 +1,380 @@ +package jet.runtime; + +import jet.*; + +import java.util.Arrays; +import java.util.List; + +/** +* @author alex.tkachman +*/ +public class Ranges { + private Ranges() { + } + + public static ByteRange rangeTo(byte from, byte to) { + if(from > to) { + return new ByteRange(from, to-from-1); + } + else { + return new ByteRange(from, to-from+1); + } + } + + public static ShortRange rangeTo(byte from, short to) { + if(from > to) { + return new ShortRange(from, to-from-1); + } + else { + return new ShortRange(from, to-from+1); + } + } + + public static IntRange rangeTo(byte from, int to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(byte from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static FloatRange rangeTo(byte from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(byte from, double to) { + return new DoubleRange(from, to-from); + } + + public static CharRange rangeTo(byte from, char to) { + if(from > to) { + return new CharRange((char) from, to-from-1); + } + else { + return new CharRange((char) from, to-from+1); + } + } + + public static ShortRange rangeTo(short from, byte to) { + if(from > to) { + return new ShortRange(from, to-from-1); + } + else { + return new ShortRange(from, to-from+1); + } + } + + public static ShortRange rangeTo(short from, short to) { + if(from > to) { + return new ShortRange(from, to-from-1); + } + else { + return new ShortRange(from, to-from+1); + } + } + + public static IntRange rangeTo(short from, int to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(short from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static FloatRange rangeTo(short from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(short from, double to) { + return new DoubleRange(from, to-from); + } + + public static ShortRange rangeTo(short from, char to) { + if(from > to) { + return new ShortRange(from, to-from-1); + } + else { + return new ShortRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, byte to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, short to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, int to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(int from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static FloatRange rangeTo(int from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(int from, double to) { + return new DoubleRange(from, to-from); + } + + public static IntRange rangeTo(int from, char to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, byte to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, short to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, int to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static FloatRange rangeTo(long from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(long from, double to) { + return new DoubleRange(from, to-from); + } + + public static LongRange rangeTo(long from, char to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static FloatRange rangeTo(float from, byte to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, short to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, int to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, long to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(float from, double to) { + return new DoubleRange(from, to-from); + } + + public static FloatRange rangeTo(float from, char to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, byte to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, short to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, int to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, long to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, float to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, double to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, char to) { + return new DoubleRange(from, to-from); + } + + public static CharRange rangeTo(char from, byte to) { + if(from > to) { + return new CharRange(from, to-from-1); + } + else { + return new CharRange(from, to-from+1); + } + } + + public static ShortRange rangeTo(char from, short to) { + if(from > to) { + return new ShortRange((short) from, to-from-1); + } + else { + return new ShortRange((short) from, to-from+1); + } + } + + public static IntRange rangeTo(char from, int to) { + if(from > to) { + return new IntRange(from, to-from-1); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(char from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static FloatRange rangeTo(char from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(char from, double to) { + return new DoubleRange(from, to-from); + } + + public static CharRange rangeTo(char from, char to) { + if(from > to) { + return new CharRange(from, to-from-1); + } + else { + return new CharRange(from, to-from+1); + } + } + + public static void main(String[] args) { + List strings = Arrays.asList("byte", "short", "int", "long", "float", "double", "char"); + for(String t1 : strings) + for(String t2 : strings) { + String resType; + if(t1.equals("double") || t2.equals("double")) { + resType = "DoubleRange"; + } + else if(t1.equals("float") || t2.equals("float")) { + resType = "FloatRange"; + } + else if(t1.equals("long") || t2.equals("long")) { + resType = "LongRange"; + } + else if(t1.equals("int") || t2.equals("int")) { + resType = "IntRange"; + } + else if(t1.equals("short") || t2.equals("short")) { + resType = "ShortRange"; + } + else if(t1.equals("char") || t2.equals("char")) { + resType = "CharRange"; + } + else { + resType = "ByteRange"; + } + + if(resType.equals("FloatRange") || resType.equals("DoubleRange")) { + System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {\n" + + " return new " + resType + "(from, to-from);\n" + + "}"); + } + else { + System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {" + + "\n if(from > to) {\n" + + " return new " + resType + "(from, to-from-1);\n" + + " }\n" + + " else {\n" + + " return new " + resType + "(from, to-from+1);\n" + + " }\n" + + "}"); + } + } + } +}