summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-04-16 13:51:23 +0000
committerMartin Odersky <odersky@gmail.com>2003-04-16 13:51:23 +0000
commit17a647a7408200cc9e32c056307c895d56cff976 (patch)
tree5780dad75e69af32c42f02ebe48e4b137040fc1a /sources
parent4d51076c624e8b08c0053adfca5008063ec7e849 (diff)
downloadscala-17a647a7408200cc9e32c056307c895d56cff976.tar.gz
scala-17a647a7408200cc9e32c056307c895d56cff976.tar.bz2
scala-17a647a7408200cc9e32c056307c895d56cff976.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r--sources/examples/expressions/expressions-current.scala6
-rw-r--r--sources/scala/List.scala16
-rw-r--r--sources/scalac/ast/parser/Parser.java55
-rw-r--r--sources/scalac/ast/parser/Scanner.java3
-rw-r--r--sources/scalac/ast/parser/Tokens.java3
-rw-r--r--sources/scalac/symtab/Modifiers.java8
-rw-r--r--sources/scalac/symtab/Symbol.java3
-rw-r--r--sources/scalac/symtab/classfile/ClassfileParser.java2
-rw-r--r--sources/scalac/util/Names.java2
9 files changed, 65 insertions, 33 deletions
diff --git a/sources/examples/expressions/expressions-current.scala b/sources/examples/expressions/expressions-current.scala
index 8783fc9544..abfb3a6ad4 100644
--- a/sources/examples/expressions/expressions-current.scala
+++ b/sources/examples/expressions/expressions-current.scala
@@ -39,9 +39,9 @@ abstract class Lang2 extends Lang {
class Show2(result: Ref[String]): visitor extends Visitor2 {
def caseNum(n: int) = result.elem = n.toString();
def casePlus(l: Exp, r: Exp) =
- result.elem =
- "(" + { l.visit(this); result.elem } +
- "+" + { r.visit(this); result.elem }+ ")";
+ result.elem =
+ "(" + { l.visit(this); result.elem } +
+ "+" + { r.visit(this); result.elem }+ ")";
}
}
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 4ed3044776..e3a099a3e5 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -176,7 +176,9 @@ trait List[a] extends Seq[a] {
/** Combines the elements of this list together using the binary
* operator <code>op</code>, from left to right, and starting with
- * the value <code>z</code>.
+ * the value <code>z</code>. Similar to <code>fold</code> but with
+ * a different order of the arguments, allowing to use nice constructions like
+ * <code>(z foldLeft l) { ... }</code>.
* @return <code>op(... (op(op(z,a0),a1) ...), an)</code> if the list
* is <code>[a0, a1, ..., an]</code>.
*/
@@ -185,20 +187,22 @@ trait List[a] extends Seq[a] {
case x :: xs => xs.foldLeft[b](f(z, x))(f)
}
+ def foldLeft_:[b](z: b)(f: (b, a) => b): b = foldLeft(z)(f);
+
def foldRight[b](z: b)(f: (a, b) => b): b = match {
case Nil => z
case x :: xs => f(x, xs.foldRight(z)(f))
}
def reduceLeft(f: (a, a) => a): a = this match {
- case Nil => error("reduceLeft of empty list")
- case x :: xs => xs.foldLeft(x)(f)
+ case Nil => error("Nil.reduceLeft")
+ case x :: xs => (xs foldLeft x)(f)
}
def reduceRight(f: (a, a) => a): a = match {
- case Nil => error("reduceRight of empty list")
+ case Nil => error("Nil.reduceRight")
case x :: Nil => x
- case x :: xs => xs.foldRight(x)(f)
+ case x :: xs => f(x, xs.reduceRight(f))
}
/**
@@ -219,7 +223,7 @@ trait List[a] extends Seq[a] {
* @return the elements of this list in reverse order.
*/
def reverse: List[a] = {
- foldLeft(Nil: List[a])((xs: List[a], x: a) => x :: xs)
+ foldLeft(Nil: List[a])((xs, x) => x :: xs)
}
/** Prints on standard output a raw textual representation of this list.
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 0a58f28dcd..1f086f93ba 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -618,7 +618,7 @@ public class Parser implements Tokens {
if (s.token == HASH)
t = make.SelectFromType(s.skipToken(), t, ident().toTypeName());
else if (s.token == LBRACKET)
- t = make.AppliedType(pos, t, varTypeArgs());
+ t = make.AppliedType(pos, t, varTypeArgs());//todo: change to typeArgs
else break;
}
return t;
@@ -768,7 +768,7 @@ public class Parser implements Tokens {
int pos = positions[sp];
Name postOp = operators[sp];
top = reduceStack(true, base, operands[sp], 0, true);
- return make.Select(pos, top, postOp);
+ return make.Select(pos, top, NameTransformer.encode(postOp));
}
}
return reduceStack(true, base, top, 0, true);
@@ -1204,29 +1204,49 @@ public class Parser implements Tokens {
TreeList params = new TreeList();
if (s.token == LBRACKET) {
s.nextToken();
- params.append(typeParam());
+ params.append(typeSig(Modifiers.PARAM));
while (s.token == COMMA) {
s.nextToken();
- params.append(typeParam());
+ params.append(typeSig(Modifiers.PARAM));
}
accept(RBRACKET);
}
return (TypeDef[])params.copyTo(new TypeDef[params.length()]);
}
- /** TypeSig ::= Id [<: Type]
+ /** TypeSig ::= [+ | -] Id TypeBounds
*/
- Tree typeParam() {
- int pos = s.pos;
- Name name = ident();
- Tree tp;
+ Tree typeSig(int mods) {
+ if (s.token == IDENTIFIER) {
+ if (s.name == PLUS) {
+ s.nextToken();
+ mods |= Modifiers.COVARIANT;
+ } else if (s.name == MINUS) {
+ s.nextToken();
+ mods |= Modifiers.CONTRAVARIANT;
+ }
+ }
+ return typeBounds(s.pos, mods, ident());
+ }
+
+ /** TypeBounds ::= [>: Type] [<: Type]
+ */
+ Tree typeBounds(int pos, int mods, Name name) {
+ Tree lobound;
+ Tree hibound;
+ if (s.token == SUPERTYPE) {
+ s.nextToken();
+ lobound = type();
+ } else {
+ lobound = scalaDot(pos, Names.All.toTypeName());
+ }
if (s.token == SUBTYPE) {
s.nextToken();
- tp = type();
+ hibound = type();
} else {
- tp = scalaDot(pos, Names.Any.toTypeName());
+ hibound = scalaDot(pos, Names.Any.toTypeName());
}
- return make.TypeDef(pos, Modifiers.PARAM, name.toTypeName(), tp);
+ return make.TypeDef(pos, mods, name.toTypeName(), hibound);
}
//////// DEFS ////////////////////////////////////////////////////////////////
@@ -1485,14 +1505,15 @@ public class Parser implements Tokens {
}
/** TypeDef ::= Id `=' Type
- * TypeSig ::= Id [`<:' Type]
+ * TypeSig ::= [`+' | `-'] Id [`>:' Type] [`<:' Type]
*/
Tree typeDefOrSig(int mods) {
int pos = s.pos;
+ if (s.token == IDENTIFIER && (s.name == PLUS || s.name == MINUS))
+ return typeSig(mods | Modifiers.DEFERRED);
Name name = ident().toTypeName();
- if (s.token == SUBTYPE) {
- s.nextToken();
- return make.TypeDef(pos, mods | Modifiers.DEFERRED, name, type());
+ if (s.token == SUPERTYPE || s.token == SUBTYPE) {
+ return typeBounds(pos, mods | Modifiers.DEFERRED, name);
} else if (s.token == EQUALS) {
s.nextToken();
return make.TypeDef(pos, mods, name, type());
@@ -1501,7 +1522,7 @@ public class Parser implements Tokens {
pos, mods | Modifiers.DEFERRED, name,
scalaDot(pos, Names.Any.toTypeName()));
} else {
- return syntaxError("`=' or `<:' expected", true);
+ return syntaxError("`=', `>:', or `<:' expected", true);
}
}
diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java
index 5cfe8292a6..19356a1830 100644
--- a/sources/scalac/ast/parser/Scanner.java
+++ b/sources/scalac/ast/parser/Scanner.java
@@ -113,7 +113,7 @@ public class Scanner extends TokenData {
case YIELD: case DO:
case COMMA: case SEMI: case DOT:
case COLON: case EQUALS: case ARROW:
- case LARROW: case SUBTYPE:
+ case LARROW: case SUBTYPE: case SUPERTYPE:
case HASH: case AS: case IS:
case RPAREN: case RBRACKET: case RBRACE:
break;
@@ -817,6 +817,7 @@ public class Scanner extends TokenData {
enterKeyword("=>", ARROW);
enterKeyword("<-", LARROW);
enterKeyword("<:", SUBTYPE);
+ enterKeyword(">:", SUPERTYPE);
enterKeyword("yield", YIELD);
enterKeyword("do", DO);
enterKeyword("#", HASH);
diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java
index c4499522df..385d23a8a8 100644
--- a/sources/scalac/ast/parser/Tokens.java
+++ b/sources/scalac/ast/parser/Tokens.java
@@ -73,7 +73,8 @@ public interface Tokens {
LARROW = 67,
ARROW = 68,
SUBTYPE = 69,
- HASH = 70,
+ SUPERTYPE = 70,
+ HASH = 71,
/* parenthesis */
LPAREN = 90,
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index 8d161ce117..a368b0b6ba 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -47,15 +47,17 @@ public interface Modifiers {
int ACCESSOR = 0x04000000; // function is an access function for a
// value or variable
- int BRIDGE = 0x0800000; // function is a bridge method.
+ int BRIDGE = 0x0800000; // function is a bridge method.
+ int SNDTIME = BRIDGE; // debug
int INTERFACE = 0x10000000; // symbol is a Java interface
int TRAIT = 0x20000000; // symbol is a Trait
- int SNDTIME = 0x40000000; //debug
+ int COVARIANT = 0x40000000; // symbol is a covariant type variable
+ int CONTRAVARIANT = 0x80000000; // symbol is a contravariant type variable
// masks
- int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT; // these modifiers can be set in source programs.
+ int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT | COVARIANT | CONTRAVARIANT; // these modifiers can be set in source programs.
int ACCESSFLAGS = PRIVATE | PROTECTED;
public static class Helper {
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 546e2db3d4..75563a6ced 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -500,7 +500,8 @@ public abstract class Symbol implements Modifiers, Kinds {
flags = flags & ~LOCKED;
if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) {
flags |= SNDTIME;
- return info();
+ Type tp = info();
+ flags &= ~SNDTIME;
} else {
assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
flags |= INITIALIZED;
diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java
index a0d69c4bed..097258c2b9 100644
--- a/sources/scalac/symtab/classfile/ClassfileParser.java
+++ b/sources/scalac/symtab/classfile/ClassfileParser.java
@@ -146,7 +146,7 @@ public class ClassfileParser implements ClassfileConstants {
if ((flags & 0x0010) != 0)
res |= Modifiers.FINAL;
if ((flags & 0x0200) != 0)
- res |= Modifiers.INTERFACE | Modifiers.ABSTRACTCLASS;
+ res |= Modifiers.INTERFACE | Modifiers.TRAIT | Modifiers.ABSTRACTCLASS;
return res | Modifiers.JAVA;
}
diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java
index 60afc67ffa..81b31b737c 100644
--- a/sources/scalac/util/Names.java
+++ b/sources/scalac/util/Names.java
@@ -27,6 +27,8 @@ public class Names {
public static final Name AMPAMP = encode("&&");
public static final Name COLONCOLON = encode("::");
+ public static final Name All = Name.fromString("All");
+ public static final Name AllRef = Name.fromString("AllRef");
public static final Name Any = Name.fromString("Any");
public static final Name AnyVal = Name.fromString("AnyVal");
public static final Name AnyRef = Name.fromString("AnyRef");