diff options
Diffstat (limited to 'sources')
-rw-r--r-- | sources/examples/expressions/expressions-current.scala | 6 | ||||
-rw-r--r-- | sources/scala/List.scala | 16 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 55 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Scanner.java | 3 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Tokens.java | 3 | ||||
-rw-r--r-- | sources/scalac/symtab/Modifiers.java | 8 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 3 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/ClassfileParser.java | 2 | ||||
-rw-r--r-- | sources/scalac/util/Names.java | 2 |
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"); |