summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ScalaReference.tex23
-rw-r--r--sources/scala/List.scala14
-rw-r--r--sources/scala/tools/scaladoc/SymbolTablePrinter.java2
-rw-r--r--sources/scalac/ast/parser/Scanner.scala33
-rw-r--r--sources/scalac/typechecker/Analyzer.java26
5 files changed, 65 insertions, 33 deletions
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex
index fa8045290b..b5605be662 100644
--- a/doc/reference/ScalaReference.tex
+++ b/doc/reference/ScalaReference.tex
@@ -96,16 +96,21 @@ varid ::= lower {letter $|$ digit} [`_' [id]]
id ::= upper {letter $|$ digit} [`_' [id]]
| varid
| op
+ | `\' stringLit
\end{lstlisting}
-There are two ways to form an identifier. First, an identifier can
+There are three ways to form an identifier. First, an identifier can
start with a letter which can be followed by an arbitrary sequence of
letters and digits. Second, an identifier can be start with a special
character followed by an arbitrary sequence of special characters. In
the first case, the identifier prefix may be immediately followed by
an underscore `\lstinline@_@' character and another string of
-characters that by themselves make up an identifier. As usual, a
-longest match rule applies. For instance, the string
+characters that by themselves make up an identifier. Finally, an
+identifier may also start with an escape character \lstinline@`\'@
+which is followed by an arbitrary string in apostrophes (host systems
+may impose some restrictions on which strings are legal for
+identifiers). As usual, a longest match rule applies. For instance,
+the string
\begin{lstlisting}
big_bob++=z3
@@ -4132,6 +4137,7 @@ form.
id ::= upper {letter | digit} [`_' [id]]
| varid
| op
+ | `\'stringLit
intLit ::= $\mbox{\rm\em ``as in Java''}$
floatLit ::= $\mbox{\rm\em ``as in Java''}$
@@ -4207,18 +4213,17 @@ grammar.
BlockExpr ::= `{' CaseClause {CaseClause} `}'
| `{' Block `}'
Block ::= {BlockStat `;'} [Expr]
-
- Enumerators ::= Generator {`;' Enumerator}
- Enumerator ::= Generator
- | Expr
- Generator ::= val Pattern1 `<-' Expr
- Block ::= {BlockStat `;'} [Expr]
BlockStat ::= Import
| Def
| {LocalModifier} ClsDef
| Expr
|
+ Enumerators ::= Generator {`;' Enumerator}
+ Enumerator ::= Generator
+ | Expr
+ Generator ::= val Pattern1 `<-' Expr
+
CaseClause ::= case Pattern [`if' PostfixExpr] `=>' Block
Constr ::= StableId [TypeArgs] [`(' [Exprs] `)']
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 9459184829..135a998000 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -71,12 +71,14 @@ object List {
Pair(f :: fs, s :: ss)
}
- /** Converts an array into a list.
- * @param arr the array to convert
- * @returns a list that contains the same elements than <code>arr</code>
- * in the same order
+ /** Converts an iterator to a list
+ * @param it the iterator to convert
+ * @returns a list that contains the elements returned by successive
+ * calls to <code>it.next</code>
*/
- def fromArray[a](arr: Array[a]): List[a] = fromArray(arr, 0, arr.length);
+ def fromIterator[a](it: Iterator[a]): List[a] =
+ if (it.hasNext) it.next :: fromIterator(it);
+ else Nil;
/** Converts a range of an array into a list.
* @param arr the array to convert
@@ -112,7 +114,7 @@ object List {
start = end;
end = str.indexOf(separator, end);
}
- res.reverse
+ res.reverse
}
}
diff --git a/sources/scala/tools/scaladoc/SymbolTablePrinter.java b/sources/scala/tools/scaladoc/SymbolTablePrinter.java
index c5811f39a8..eef0016c11 100644
--- a/sources/scala/tools/scaladoc/SymbolTablePrinter.java
+++ b/sources/scala/tools/scaladoc/SymbolTablePrinter.java
@@ -490,8 +490,8 @@ public class SymbolTablePrinter extends scalac.symtab.SymbolTablePrinter {
return this;
case ConstantType(Type base, Object value):
- print("(");
printType(base, user);
+ print("(");
print(value.toString());
print(")");
return this;
diff --git a/sources/scalac/ast/parser/Scanner.scala b/sources/scalac/ast/parser/Scanner.scala
index d7376395eb..5181812b9c 100644
--- a/sources/scalac/ast/parser/Scanner.scala
+++ b/sources/scalac/ast/parser/Scanner.scala
@@ -202,6 +202,13 @@ class Scanner(unit: Unit) extends TokenData {
nextch();
getOperatorRest(index);
return;
+ case `\\' =>
+ nextch();
+ if (ch == '"')//"
+ getStringLit();
+ else
+ syntaxError(pos, "illegal character");
+ return;
case '/' =>
nextch();
if (!skipComment()) {
@@ -222,17 +229,7 @@ class Scanner(unit: Unit) extends TokenData {
getNumber(index, 10);
return;
case '\"' => //" scala-mode: need to understand literals
- nextch();
- litlen = 0;
- while (ch != '\"'/*"*/ && ch != CR && ch != LF && ch != SU)
- getlitch();
- if (ch == '\"'/*"*/) {
- token = STRINGLIT;
- name = Name.fromSource(lit, 0, litlen);
- nextch();
- } else {
- syntaxError("unclosed character literal");
- }
+ getStringLit();
return;
case '\'' =>
nextch();
@@ -446,6 +443,20 @@ class Scanner(unit: Unit) extends TokenData {
}
}
+ private def getStringLit(): unit = {
+ nextch();
+ litlen = 0;
+ while (ch != '\"'/*"*/ && ch != CR && ch != LF && ch != SU)
+ getlitch();
+ if (ch == '\"'/*"*/) {
+ token = STRINGLIT;
+ name = Name.fromSource(lit, 0, litlen);
+ nextch();
+ } else {
+ syntaxError("unclosed character literal");
+ }
+ }
+
/** returns true if argument corresponds to a keyword.
* Used in dtd2scala tool.
*/
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 59a569ddba..e807c41994 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -1297,9 +1297,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
clazz.primaryConstructor());
// MZ: this is a hack, but I didn't know how to do it better
if ((clazz.flags & (JAVA | CASE)) == (JAVA | CASE)) {
- Symbol[] altconstr = clazz.allConstructors().alternativeSymbols();
- tree.type = tree.type.prefix().memberType(
- altconstr[altconstr.length - 1]);
+ Symbol[] altconstr = clazz.allConstructors().alternativeSymbols();
+ tree.type = tree.type.prefix().memberType(
+ altconstr[altconstr.length - 1]);
}
switch (tree.type) {
case PolyType(Symbol[] tparams, Type restp):
@@ -1397,10 +1397,24 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (value1 != null)
return make.Literal(tree.pos, value1)
.setType(Type.ConstantType(pt, value1));
+ break;
}
- typeError(tree.pos, owntype, pt);
- Type.explainTypes(owntype, pt);
- tree.type = Type.ErrorType;
+ if ((mode & EXPRmode) != 0) {
+ Symbol coerceMeth = tree.type.lookup(Names.coerce);
+ if (coerceMeth != Symbol.NONE) {
+ Type coerceType = checkAccessible(
+ tree.pos, coerceMeth, tree.type.memberType(coerceMeth),
+ tree);
+ tree = make.Select(tree.pos, tree, Names.coerce)
+ .setSymbol(coerceMeth)
+ .setType(coerceType);
+ return adapt(tree, mode, pt);
+ }
+ } else if ((mode & CONSTRmode) == 0) {
+ typeError(tree.pos, owntype, pt);
+ Type.explainTypes(owntype, pt);
+ tree.type = Type.ErrorType;
+ } // for constructors, delay until after the `new'.
}
return tree;
}