summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/meta/scalac/ast/Tree.java19
-rw-r--r--sources/scala/tools/scalai/ExpressionCompiler.java2
-rw-r--r--sources/scalac/ast/parser/Parser.java83
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java5
-rw-r--r--sources/scalac/backend/jvm/GenJVM.java2
-rw-r--r--sources/scalac/backend/jvm/GenJVMBCEL.java2
-rw-r--r--sources/scalac/transformer/Erasure.java2
-rw-r--r--sources/scalac/typechecker/Analyzer.java12
8 files changed, 81 insertions, 46 deletions
diff --git a/sources/meta/scalac/ast/Tree.java b/sources/meta/scalac/ast/Tree.java
index 611054180e..b84f6f8ba3 100644
--- a/sources/meta/scalac/ast/Tree.java
+++ b/sources/meta/scalac/ast/Tree.java
@@ -103,9 +103,7 @@ public class Tree {
n_FunType = node("FunType" , Type, NoSym),
n_CompoundType = node("CompoundType" , Type, NoSym),
n_AppliedType = node("AppliedType" , Type, NoSym),
- n_Try = node("Try" , Term, NoSym),
- n_While = node("While" , Term, NoSym),
- n_DoUntil = node("DoUntil" , Term, NoSym);
+ n_Try = node("Try" , Term, NoSym);
public final TreeNode[] nodes;
public int arrays;
@@ -204,7 +202,8 @@ public class Tree {
n_LabelDef.
setDescription("Labelled expression - the symbols in the array (must be Idents!) are those the label takes as argument").
- setRange(Phase.OPTIMIZER, Phase.END).
+ setRange(Phase.PARSER, Phase.END).
+ addField(t_TermName, "name", SymName).
addField(n_Ident.getType(1), "params").
addField(t_TermTree, "rhs");
@@ -345,18 +344,6 @@ public class Tree {
addField(t_TermTree, "block").
addField(t_TermTree, "catcher").
addField(t_TermTree, "finalizer");
-
- n_While.
- setDescription("While Loop").
- setRange(Phase.PARSER, Phase.END).
- addField(t_TermTree, "cond").
- addField(t_TermTree, "block");
-
- n_DoUntil.
- setDescription("Do-Until Loop").
- setRange(Phase.PARSER, Phase.END).
- addField(t_TermTree, "block").
- addField(t_TermTree, "cond");
}
//########################################################################
diff --git a/sources/scala/tools/scalai/ExpressionCompiler.java b/sources/scala/tools/scalai/ExpressionCompiler.java
index 5fcc4d925a..c3d5fc7225 100644
--- a/sources/scala/tools/scalai/ExpressionCompiler.java
+++ b/sources/scala/tools/scalai/ExpressionCompiler.java
@@ -97,7 +97,7 @@ public class ExpressionCompiler {
private Code compute(Tree tree) {
switch (tree) {
- case LabelDef(Tree.Ident[] params, Tree body):
+ case LabelDef(_, Tree.Ident[] params, Tree body):
Symbol symbol = tree.symbol();
Variable[] vars = new Variable[params.length];
for (int i = 0; i < params.length; i++) {
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index fc544b50d4..a32d9243c8 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -36,11 +36,16 @@ public class Parser implements Tokens {
*/
PatternNormalizer pN;
+ /** The current nesting depths of while and do loops.
+ */
+ int loopNestingDepth;
+
public Parser(Unit unit) {
s = new Scanner(unit);
make = unit.global.make;
pN = new PatternNormalizer( unit );
mapTreeComment = unit.global.mapTreeComment;
+ loopNestingDepth = 0;
}
/** this is the general parse method
@@ -320,27 +325,53 @@ public class Parser implements Tokens {
return t;
}
- Tree makeWhile(int pos, Tree cond, Tree body) {
- return
- make.Apply(
- pos,
- make.Apply(
- pos, ScalaRunTimeDot(pos, Names.While), new Tree[]{cond}),
- new Tree[]{body});
- }
-
- Tree makeDoWhile(int pos, Tree body, Tree cond) {
- return
- make.Apply(
- pos,
- make.Select(
- pos,
- make.Apply(
- pos,
- ScalaRunTimeDot(pos, Names.Do),
- new Tree[]{body}),
- Names.While),
- new Tree[]{cond});
+ Tree makeWhile(int pos, Tree cond, Tree body) {
+ return
+ make.Apply(
+ pos,
+ make.Apply(
+ pos, ScalaRunTimeDot(pos, Names.While), new Tree[]{cond}),
+ new Tree[]{body});
+ }
+
+ Tree makeDoWhile(int pos, Tree body, Tree cond) {
+ return
+ make.Apply(
+ pos,
+ make.Select(
+ pos,
+ make.Apply(
+ pos,
+ ScalaRunTimeDot(pos, Names.Do),
+ new Tree[]{body}),
+ Names.While),
+ new Tree[]{cond});
+ }
+
+ Tree makeWhile(int pos, Name lname, Tree cond, Tree body) {
+ Tree continu = make.Apply(
+ pos, make.Ident(pos, lname), Tree.EMPTY_ARRAY);
+ Tree rhs = make.If(
+ pos,
+ cond,
+ make.Block(body.pos, new Tree[]{body, continu}),
+ make.Block(pos, Tree.EMPTY_ARRAY));
+ return make.LabelDef(pos, lname, new Ident[0], rhs);
+ }
+
+ Tree makeDoWhile(int pos, Name lname, Tree body, Tree cond) {
+ Tree continu = make.Apply(
+ pos, make.Ident(pos, lname), Tree.EMPTY_ARRAY);
+ Tree rhs = make.Block(
+ body.pos,
+ new Tree[]{
+ body,
+ make.If(
+ cond.pos,
+ cond,
+ continu,
+ make.Block(pos, Tree.EMPTY_ARRAY))});
+ return make.LabelDef(pos, lname, new Ident[0], rhs);
}
/** Convert tree to formal parameter list
@@ -824,13 +855,18 @@ public class Parser implements Tokens {
}
return makeTry(pos, body, catcher, finalizer);
} else if (s.token == WHILE) {
+ Name lname = Name.fromString("label$" + loopNestingDepth);
+ loopNestingDepth++;
int pos = s.skipToken();
accept(LPAREN);
Tree cond = expr();
accept(RPAREN);
Tree body = expr();
- return makeWhile(pos, cond, body);
+ loopNestingDepth--;
+ return makeWhile(pos/*, lname*/, cond, body);
} else if (s.token == DO) {
+ Name lname = Name.fromString("label$" + loopNestingDepth);
+ loopNestingDepth++;
int pos = s.skipToken();
Tree body = expr();
if (s.token == SEMI) s.nextToken();
@@ -838,7 +874,8 @@ public class Parser implements Tokens {
accept(LPAREN);
Tree cond = expr();
accept(RPAREN);
- return makeDoWhile(pos, body, cond);
+ loopNestingDepth--;
+ return makeDoWhile(pos, lname, body, cond);
} else if (s.token == FOR) {
s.nextToken();
Tree[] enums;
diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java
index 664957e79a..39b312f4a7 100644
--- a/sources/scalac/ast/printer/TextTreePrinter.java
+++ b/sources/scalac/ast/printer/TextTreePrinter.java
@@ -374,9 +374,8 @@ public class TextTreePrinter implements TreePrinter {
print(body);
break;
- case LabelDef(Tree.Ident[] params, Tree rhs):
- assert tree.symbol() != null;
- printSymbolDefinition(tree.symbol(), null);
+ case LabelDef(Name name, Tree.Ident[] params, Tree rhs):
+ printSymbolDefinition(tree.symbol(), name);
printArray(params, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP);
print(rhs);
break;
diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java
index 3937fa2a7f..5059a4f9ed 100644
--- a/sources/scalac/backend/jvm/GenJVM.java
+++ b/sources/scalac/backend/jvm/GenJVM.java
@@ -220,7 +220,7 @@ class GenJVM {
Symbol sym = tree.symbol();
switch (tree) {
- case LabelDef(Tree.Ident[] params, Tree rhs): {
+ case LabelDef(_, Tree.Ident[] params, Tree rhs): {
JLabel label = new JLabel();
ctx.code.anchorLabelToNext(label);
ctx.labels.put(sym, new Pair(label, params));
diff --git a/sources/scalac/backend/jvm/GenJVMBCEL.java b/sources/scalac/backend/jvm/GenJVMBCEL.java
index 8c6634ba0a..0708cdd3d0 100644
--- a/sources/scalac/backend/jvm/GenJVMBCEL.java
+++ b/sources/scalac/backend/jvm/GenJVMBCEL.java
@@ -219,7 +219,7 @@ class GenJVMBCEL {
leaveMethod();
} break;
- case LabelDef(_, _):
+ case LabelDef(_, _, _):
global.fail("not implemented yet " + tree);
break;
diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java
index 63bb24931c..5e855c2cd3 100644
--- a/sources/scalac/transformer/Erasure.java
+++ b/sources/scalac/transformer/Erasure.java
@@ -509,6 +509,7 @@ public class Erasure extends Transformer implements Modifiers {
case This(_):
case Literal(_):
case TypeTerm():
+ case LabelDef(_, _,_):
return super.transform(tree).setType(owntype);
case Bad():
@@ -516,7 +517,6 @@ public class Erasure extends Transformer implements Modifiers {
case PatDef(_,_,_):
case Import(_,_):
case CaseDef(_,_,_):
- case LabelDef(_,_):
case Visitor(_):
case Function(_,_):
case SingletonType(_):
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 519cb58c7e..d8bcef64f2 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -2290,6 +2290,18 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case Literal(Object value):
return tree.setType(value2Type(value));
+ case LabelDef(Name name, Ident[] params, Tree body):
+ assert params.length == 0;
+ pushContext(tree, context.owner, new Scope(context.scope));
+ Symbol lsym = new TermSymbol(tree.pos, name, context.owner, LABEL);
+ lsym.setInfo(
+ Type.MethodType(Symbol.EMPTY_ARRAY, definitions.UNIT_TYPE));
+ context.scope.enter(lsym);
+ Tree body1 = transform(body, mode, pt);
+ popContext();
+ return copy.LabelDef(tree, lsym, params, body1)
+ .setSymbol(lsym).setType(definitions.UNIT_TYPE);
+
case TypeTerm():
return tree;