diff --git a/.classpath b/.classpath
index 308e984d7..fa34a17d2 100644
--- a/.classpath
+++ b/.classpath
@@ -5,6 +5,7 @@
+
diff --git a/.travis.yml b/.travis.yml
index d5db1af26..a199e11e3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,13 +3,13 @@ jdk:
- oraclejdk8
sudo: false
env:
- matrix:
- - TASK=tests
- - TASK=checkstyle
- - TASK=kompos
global:
- secure: PrFbSr/qjhVXrpiOzrcEMUZrnjEWJmvx5DC9QdaAmnUKpG9/7mJBQVgNziVj+GWfW84WJpkOsQf+I2lx7/cQsWQKad/t8wtypl30wGesSTpAgl5fCiKLOBAbOghKXir+WIaxtcATPPffur9OLh3ogEcmIQbVi682YUKmA5zF11JZdpCR4QONc/u+DqB29FuHru/cFiesYP0Oz82A+M0UtMcYsurKIxdKMD4YK/uSG892PUrcZU6STXlukhgQuy3PitSWkYV2KGxXMVKzWGM7dJvRggN05r/S871pscuRwZ+Doxqr9b17B3umCHi3i4KXmNH+Esb0p1mvegs0iS/b7RyA5SENre+H24n3SOeXTa3wSpTnF90XxQrDEBbY5wV7lN7MJG+pHxkOvoZt6pS3f7x2VYR8Joa4J+Gf6IDvxZMiCd1v3N1kc9ygyvJmHf5wDmLMdupk0/frojApDXfJT6bqiVL3S0FqZpXSPGAsKYf8wfn30Xz/YUBsnfUQ/a21Zz52+OTqPbt32Hf1FGYIEJSkZJUN90Q8rHVJt9zPg37xKCDuf6bxlvT040KSzuuXtizLkOnHq2rhg4Oad/JTw3d4NzPoRVzUI9qDKPrA7RdUAjmrB04Z1f3g/I6w3h2B9JTSFAzBcMZ5NYZhIqE31GQukgStaqC98y32/zo9xFs=
+ - secure: PrFbSr/qjhVXrpiOzrcEMUZrnjEWJmvx5DC9QdaAmnUKpG9/7mJBQVgNziVj+GWfW84WJpkOsQf+I2lx7/cQsWQKad/t8wtypl30wGesSTpAgl5fCiKLOBAbOghKXir+WIaxtcATPPffur9OLh3ogEcmIQbVi682YUKmA5zF11JZdpCR4QONc/u+DqB29FuHru/cFiesYP0Oz82A+M0UtMcYsurKIxdKMD4YK/uSG892PUrcZU6STXlukhgQuy3PitSWkYV2KGxXMVKzWGM7dJvRggN05r/S871pscuRwZ+Doxqr9b17B3umCHi3i4KXmNH+Esb0p1mvegs0iS/b7RyA5SENre+H24n3SOeXTa3wSpTnF90XxQrDEBbY5wV7lN7MJG+pHxkOvoZt6pS3f7x2VYR8Joa4J+Gf6IDvxZMiCd1v3N1kc9ygyvJmHf5wDmLMdupk0/frojApDXfJT6bqiVL3S0FqZpXSPGAsKYf8wfn30Xz/YUBsnfUQ/a21Zz52+OTqPbt32Hf1FGYIEJSkZJUN90Q8rHVJt9zPg37xKCDuf6bxlvT040KSzuuXtizLkOnHq2rhg4Oad/JTw3d4NzPoRVzUI9qDKPrA7RdUAjmrB04Z1f3g/I6w3h2B9JTSFAzBcMZ5NYZhIqE31GQukgStaqC98y32/zo9xFs=
+ matrix:
+ - TASK=tests
+ - TASK=checkstyle
+ - TASK=kompos
script:
- - if [ "$TASK" = "tests" ]; then ant tests; ./som -G --coveralls $COVERALLS_REPO_TOKEN core-lib/TestSuite/TestRunner.som; fi
+ - if [ "$TASK" = "tests" ]; then ant tests; ./som -G --coveralls "$COVERALLS_REPO_TOKEN" core-lib/TestSuite/TestRunner.som; fi
- if [ "$TASK" = "checkstyle" ]; then ant checkstyle; fi
- if [ "$TASK" = "kompos" ]; then nvm install 6 && ant && cd tools/kompos && npm install && npm test; fi
diff --git a/src/som/VMOptions.java b/src/som/VMOptions.java
index 826cc210c..4922943b1 100644
--- a/src/som/VMOptions.java
+++ b/src/som/VMOptions.java
@@ -41,7 +41,7 @@ private String[] processVmArguments(final String[] arguments) {
while (parsedArgument) {
if (currentArg >= arguments.length) {
- return null;
+ return new String[0];
} else {
if (arguments[currentArg].equals("--platform")) {
platformFile = arguments[currentArg + 1];
@@ -75,7 +75,7 @@ private String[] processVmArguments(final String[] arguments) {
if (currentArg < arguments.length) {
return Arrays.copyOfRange(arguments, currentArg, arguments.length);
} else {
- return null;
+ return new String[0];
}
}
diff --git a/src/som/compiler/MethodBuilder.java b/src/som/compiler/MethodBuilder.java
index 0cd4fe118..8944735db 100644
--- a/src/som/compiler/MethodBuilder.java
+++ b/src/som/compiler/MethodBuilder.java
@@ -40,6 +40,7 @@
import som.VM;
import som.compiler.MixinBuilder.MixinDefinitionError;
import som.compiler.MixinBuilder.MixinDefinitionId;
+import som.compiler.ProgramDefinitionError.SemanticDefinitionError;
import som.compiler.Variable.Argument;
import som.compiler.Variable.Local;
import som.interpreter.LexicalScope.MethodScope;
@@ -111,6 +112,14 @@ private MethodBuilder(final MixinBuilder holder, final MixinScope clsScope,
embeddedBlockMethods = new ArrayList();
}
+ public static class MethodDefinitionError extends SemanticDefinitionError {
+ private static final long serialVersionUID = 3901992766649011815L;
+
+ MethodDefinitionError(final String message, final SourceSection source) {
+ super(message, source);
+ }
+ }
+
public Collection getArguments() {
return arguments.values();
}
@@ -264,7 +273,8 @@ public void addArgumentIfAbsent(final String arg, final SourceSection source) {
addArgument(arg, source);
}
- public void addLocalIfAbsent(final String local, final SourceSection source) {
+ public void addLocalIfAbsent(final String local, final SourceSection source)
+ throws MethodDefinitionError {
if (locals.containsKey(local)) {
return;
}
@@ -272,7 +282,12 @@ public void addLocalIfAbsent(final String local, final SourceSection source) {
addLocal(local, source);
}
- public Local addLocal(final String local, final SourceSection source) {
+ public Local addLocal(final String local, final SourceSection source)
+ throws MethodDefinitionError {
+ if (arguments.containsKey(local)) {
+ throw new MethodDefinitionError("Method already defines argument " + local + ". Can't define local variable with same name.", source);
+ }
+
Local l = new Local(
local, currentScope.getFrameDescriptor().addFrameSlot(local), source);
assert !locals.containsKey(local);
diff --git a/src/som/compiler/MixinBuilder.java b/src/som/compiler/MixinBuilder.java
index 3f0650164..96e747746 100644
--- a/src/som/compiler/MixinBuilder.java
+++ b/src/som/compiler/MixinBuilder.java
@@ -37,6 +37,7 @@
import som.compiler.MixinDefinition.ClassSlotDefinition;
import som.compiler.MixinDefinition.SlotDefinition;
import som.compiler.MixinDefinition.SlotMutator;
+import som.compiler.ProgramDefinitionError.SemanticDefinitionError;
import som.compiler.Variable.Argument;
import som.interpreter.LexicalScope.MixinScope;
import som.interpreter.Method;
@@ -151,20 +152,11 @@ public MixinBuilder(final MixinBuilder outerBuilder,
this.structuralProbe = structuralProbe;
}
- public static class MixinDefinitionError extends Exception {
- private static final long serialVersionUID = 9200967710874738189L;
- private final String message;
- private final SourceSection source;
+ public static class MixinDefinitionError extends SemanticDefinitionError {
+ private static final long serialVersionUID = 5030639383869198851L;
MixinDefinitionError(final String message, final SourceSection source) {
- this.message = message;
- this.source = source;
- }
-
- @Override
- public String toString() {
- return source.getSource().getName() + ":" + source.getStartLine() + ":" +
- source.getStartColumn() + ":error: " + message;
+ super(message, source);
}
}
diff --git a/src/som/compiler/Parser.java b/src/som/compiler/Parser.java
index 3f5bee6ab..c5a8a931f 100644
--- a/src/som/compiler/Parser.java
+++ b/src/som/compiler/Parser.java
@@ -78,6 +78,7 @@
import som.VM;
import som.VmSettings;
import som.compiler.Lexer.Peek;
+import som.compiler.MethodBuilder.MethodDefinitionError;
import som.compiler.MixinBuilder.MixinDefinitionError;
import som.compiler.Variable.Local;
import som.interpreter.SNodeFactory;
@@ -161,9 +162,8 @@ public String toString() {
return "Parser(" + source.getName() + ", " + this.getCoordinate().toString() + ")";
}
- public static class ParseError extends Exception {
+ public static class ParseError extends ProgramDefinitionError {
private static final long serialVersionUID = 425390202979033628L;
- private final String message;
private final SourceCoordinate sourceCoordinate;
private final String text;
private final String rawBuffer;
@@ -172,7 +172,7 @@ public static class ParseError extends Exception {
private final Symbol found;
ParseError(final String message, final Symbol expected, final Parser parser) {
- this.message = message;
+ super(message);
this.sourceCoordinate = parser.getCoordinate();
this.text = parser.text;
this.rawBuffer = parser.lexer.getRawBuffer();
@@ -191,7 +191,7 @@ public SourceCoordinate getSourceCoordinate() {
@Override
public String getMessage() {
- String msg = message;
+ String msg = super.getMessage();
String foundStr;
if (Parser.printableSymbol(found)) {
@@ -209,7 +209,7 @@ public String getMessage() {
@Override
public String toString() {
- String msg = "%(file)s:%(line)d:%(column)d: error: " + message;
+ String msg = "%(file)s:%(line)d:%(column)d: error: " + super.getMessage();
String foundStr;
if (Parser.printableSymbol(found)) {
foundStr = found + " (" + text + ")";
@@ -279,7 +279,7 @@ public SourceCoordinate getCoordinate() {
return lexer.getStartCoordinate();
}
- public MixinBuilder moduleDeclaration() throws ParseError, MixinDefinitionError {
+ public MixinBuilder moduleDeclaration() throws ProgramDefinitionError {
comment();
return classDeclaration(null, AccessModifier.PUBLIC);
}
@@ -291,7 +291,7 @@ protected String className() throws ParseError {
}
private MixinBuilder classDeclaration(final MixinBuilder outerBuilder,
- final AccessModifier accessModifier) throws ParseError, MixinDefinitionError {
+ final AccessModifier accessModifier) throws ProgramDefinitionError {
expectIdentifier("class", "Found unexpected token %(found)s. " +
"Tried parsing a class declaration and expected 'class' instead.",
KeywordTag.class);
@@ -328,7 +328,7 @@ private MixinBuilder classDeclaration(final MixinBuilder outerBuilder,
}
private void inheritanceListAndOrBody(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
if (sym == NewTerm) {
defaultSuperclassAndBody(mxnBuilder);
} else {
@@ -337,7 +337,7 @@ private void inheritanceListAndOrBody(final MixinBuilder mxnBuilder)
}
private void defaultSuperclassAndBody(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
SourceSection source = getEmptySource();
MethodBuilder def = mxnBuilder.getClassInstantiationMethodBuilder();
ExpressionNode selfRead = def.getSelfRead(source);
@@ -352,7 +352,7 @@ private void defaultSuperclassAndBody(final MixinBuilder mxnBuilder)
}
private void explicitInheritanceListAndOrBody(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
SourceCoordinate superAndMixinCoord = getCoordinate();
inheritanceClause(mxnBuilder);
@@ -377,7 +377,7 @@ private void explicitInheritanceListAndOrBody(final MixinBuilder mxnBuilder)
}
private void mixinApplication(final MixinBuilder mxnBuilder, final int mixinId)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
expect(MixinOperator, KeywordTag.class);
SourceCoordinate coord = getCoordinate();
@@ -407,7 +407,7 @@ private void mixinApplication(final MixinBuilder mxnBuilder, final int mixinId)
}
private void inheritanceClause(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
ExpressionNode superClassResolution = inheritancePrefixAndSuperclass(mxnBuilder);
mxnBuilder.setSuperClassResolution(superClassResolution);
@@ -463,8 +463,7 @@ private ExpressionNode inheritancePrefixAndSuperclass(
return unaryMessage(self, false, null);
}
- private void classBody(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ private void classBody(final MixinBuilder mxnBuilder) throws ProgramDefinitionError {
classHeader(mxnBuilder);
sideDeclaration(mxnBuilder);
if (sym == Colon) {
@@ -473,7 +472,7 @@ private void classBody(final MixinBuilder mxnBuilder)
}
private void classSideDecl(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
mxnBuilder.switchToClassSide();
expect(Colon, KeywordTag.class);
@@ -487,7 +486,7 @@ private void classSideDecl(final MixinBuilder mxnBuilder)
}
private void classHeader(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
expect(NewTerm, null);
classComment(mxnBuilder);
@@ -533,7 +532,7 @@ private String comment() throws ParseError {
}
private void slotDeclarations(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
// Newspeak-speak: we do not support simSlotDecls, i.e.,
// simultaneous slots clauses (spec 6.3.2)
expect(Or, DelimiterOpeningTag.class);
@@ -548,7 +547,7 @@ private void slotDeclarations(final MixinBuilder mxnBuilder)
}
private void slotDefinition(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
comment();
if (sym == Or) { return; }
@@ -588,8 +587,7 @@ private String slotDecl() throws ParseError {
return identifier();
}
- private void initExprs(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ private void initExprs(final MixinBuilder mxnBuilder) throws ProgramDefinitionError {
MethodBuilder initializer = mxnBuilder.getInitializerMethodBuilder();
mxnBuilder.addInitializerExpression(expression(initializer));
@@ -600,8 +598,7 @@ private void initExprs(final MixinBuilder mxnBuilder)
}
}
- private void sideDeclaration(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ private void sideDeclaration(final MixinBuilder mxnBuilder) throws ProgramDefinitionError {
expect(NewTerm, DelimiterOpeningTag.class);
comment();
@@ -618,16 +615,14 @@ private void sideDeclaration(final MixinBuilder mxnBuilder)
expect(EndTerm, DelimiterClosingTag.class);
}
- private void nestedClassDeclaration(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ private void nestedClassDeclaration(final MixinBuilder mxnBuilder) throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
AccessModifier accessModifier = accessModifier();
MixinBuilder nestedCls = classDeclaration(mxnBuilder, accessModifier);
mxnBuilder.addNestedMixin(nestedCls.assemble(getSource(coord)));
}
- private void category(final MixinBuilder mxnBuilder)
- throws ParseError, MixinDefinitionError {
+ private void category(final MixinBuilder mxnBuilder) throws ProgramDefinitionError {
String categoryName;
// Newspeak-spec: this is not conform with Newspeak,
// as the category is normally not optional
@@ -746,7 +741,7 @@ public SourceSection getSource(final SourceCoordinate coord) {
}
private void methodDeclaration(final MixinBuilder mxnBuilder,
- final SSymbol category) throws ParseError, MixinDefinitionError {
+ final SSymbol category) throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
AccessModifier accessModifier = accessModifier();
@@ -812,7 +807,7 @@ protected void keywordPattern(final MethodBuilder builder) throws ParseError {
}
private ExpressionNode methodBlock(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
expect(NewTerm, DelimiterOpeningTag.class);
@@ -866,7 +861,7 @@ private String argument() throws ParseError {
}
private ExpressionNode blockContents(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
comment();
if (accept(Or, DelimiterOpeningTag.class)) {
locals(builder);
@@ -875,7 +870,7 @@ private ExpressionNode blockContents(final MethodBuilder builder)
return blockBody(builder);
}
- private void locals(final MethodBuilder builder) throws ParseError {
+ private void locals(final MethodBuilder builder) throws ParseError, MethodDefinitionError {
while (sym == Identifier) {
SourceCoordinate coord = getCoordinate();
String id = identifier();
@@ -885,8 +880,7 @@ private void locals(final MethodBuilder builder) throws ParseError {
}
}
- private ExpressionNode blockBody(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ private ExpressionNode blockBody(final MethodBuilder builder) throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
List expressions = new ArrayList();
@@ -921,7 +915,7 @@ private ExpressionNode blockBody(final MethodBuilder builder)
}
private ExpressionNode result(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
ExpressionNode exp = expression(builder);
@@ -935,7 +929,7 @@ private ExpressionNode result(final MethodBuilder builder)
}
private ExpressionNode expression(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
comment();
peekForNextSymbolFromLexer();
@@ -947,12 +941,12 @@ private ExpressionNode expression(final MethodBuilder builder)
}
private ExpressionNode assignation(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
return assignments(builder);
}
protected ExpressionNode assignments(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
if (sym != Identifier) {
@@ -981,7 +975,7 @@ protected SSymbol assignment() throws ParseError {
}
private ExpressionNode evaluation(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
ExpressionNode exp;
if (sym == Keyword) {
exp = keywordMessage(builder, builder.getSelfRead(getEmptySource()), false, false, null);
@@ -999,8 +993,7 @@ private boolean symIsMessageSend() {
|| symIn(binaryOpSyms) || sym == EventualSend;
}
- private ExpressionNode primary(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ private ExpressionNode primary(final MethodBuilder builder) throws ProgramDefinitionError {
switch (sym) {
case Identifier: {
SourceCoordinate coord = getCoordinate();
@@ -1051,7 +1044,7 @@ private ExpressionNode primary(final MethodBuilder builder)
}
private ExpressionNode outerSend(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
expectIdentifier("outer", KeywordTag.class);
String outer = identifier();
@@ -1063,8 +1056,7 @@ private ExpressionNode outerSend(final MethodBuilder builder)
protected ExpressionNode binaryConsecutiveMessages(
final MethodBuilder builder, ExpressionNode operand,
- boolean eventualSend, SourceSection sendOp) throws ParseError,
- MixinDefinitionError {
+ boolean eventualSend, SourceSection sendOp) throws ProgramDefinitionError {
while (sym == OperatorSequence || symIn(binaryOpSyms)) {
operand = binaryMessage(builder, operand, eventualSend, sendOp);
SourceCoordinate coord = getCoordinate();
@@ -1078,7 +1070,7 @@ protected ExpressionNode binaryConsecutiveMessages(
}
private ExpressionNode messages(final MethodBuilder builder,
- final ExpressionNode receiver) throws ParseError, MixinDefinitionError {
+ final ExpressionNode receiver) throws ProgramDefinitionError {
ExpressionNode msg;
SourceCoordinate coord = getCoordinate();
boolean eventualSend = accept(EventualSend, KeywordTag.class);
@@ -1152,8 +1144,7 @@ private ExpressionNode tryInliningBinaryMessage(final MethodBuilder builder,
protected ExpressionNode binaryMessage(final MethodBuilder builder,
final ExpressionNode receiver, final boolean eventualSend,
- final SourceSection sendOperator)
- throws ParseError, MixinDefinitionError {
+ final SourceSection sendOperator) throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
SSymbol msg = binarySelector();
ExpressionNode operand = binaryOperand(builder);
@@ -1169,8 +1160,7 @@ protected ExpressionNode binaryMessage(final MethodBuilder builder,
eventualSend, getSource(coord), sendOperator);
}
- private ExpressionNode binaryOperand(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ private ExpressionNode binaryOperand(final MethodBuilder builder) throws ProgramDefinitionError {
ExpressionNode operand = primary(builder);
// a binary operand can receive unaryMessages
@@ -1196,7 +1186,7 @@ private ExpressionNode binaryOperand(final MethodBuilder builder)
protected ExpressionNode keywordMessage(final MethodBuilder builder,
final ExpressionNode receiver, final boolean explicitRcvr,
- final boolean eventualSend, final SourceSection sendOperator) throws ParseError, MixinDefinitionError {
+ final boolean eventualSend, final SourceSection sendOperator) throws ProgramDefinitionError {
assert !(!explicitRcvr && eventualSend);
SourceCoordinate coord = getCoordinate();
List arguments = new ArrayList();
@@ -1290,25 +1280,33 @@ protected ExpressionNode inlineControlStructureIfPossible(
source);
} else if (!VmSettings.DYNAMIC_METRICS && "to:do:".equals(msgStr) &&
arguments.get(2) instanceof LiteralNode) {
- Local loopIdx = builder.addLocal("i:" + source.getCharIndex(), source);
- ExpressionNode inlinedBody = ((LiteralNode) arguments.get(2)).inline(builder, loopIdx);
- inlinedBody.markAsLoopBody();
- return IntToDoInlinedLiteralsNodeGen.create(inlinedBody, loopIdx.getSlot(), loopIdx.source,
- arguments.get(2), source, arguments.get(0), arguments.get(1));
+ try {
+ Local loopIdx = builder.addLocal("i:" + source.getCharIndex(), source);
+ ExpressionNode inlinedBody = ((LiteralNode) arguments.get(2)).inline(builder, loopIdx);
+ inlinedBody.markAsLoopBody();
+ return IntToDoInlinedLiteralsNodeGen.create(inlinedBody, loopIdx.getSlot(), loopIdx.source,
+ arguments.get(2), source, arguments.get(0), arguments.get(1));
+ } catch (MethodDefinitionError e) {
+ throw new RuntimeException(e);
+ }
} else if (!VmSettings.DYNAMIC_METRICS && "downTo:do:".equals(msgStr) &&
arguments.get(2) instanceof LiteralNode) {
- Local loopIdx = builder.addLocal("i:" + source.getCharIndex(), source);
- ExpressionNode inlinedBody = ((LiteralNode) arguments.get(2)).inline(builder, loopIdx);
- inlinedBody.markAsLoopBody();
- return IntDownToDoInlinedLiteralsNodeGen.create(inlinedBody, loopIdx.getSlot(), loopIdx.source,
- arguments.get(2), source, arguments.get(0), arguments.get(1));
+ try {
+ Local loopIdx = builder.addLocal("i:" + source.getCharIndex(), source);
+ ExpressionNode inlinedBody = ((LiteralNode) arguments.get(2)).inline(builder, loopIdx);
+ inlinedBody.markAsLoopBody();
+ return IntDownToDoInlinedLiteralsNodeGen.create(inlinedBody, loopIdx.getSlot(), loopIdx.source,
+ arguments.get(2), source, arguments.get(0), arguments.get(1));
+ } catch (MethodDefinitionError e) {
+ throw new RuntimeException(e);
+ }
}
}
return null;
}
private ExpressionNode formula(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
ExpressionNode operand = binaryOperand(builder);
SourceCoordinate coord = getCoordinate();
boolean evenutalSend = accept(EventualSend, KeywordTag.class);
@@ -1322,7 +1320,7 @@ private ExpressionNode formula(final MethodBuilder builder)
}
private ExpressionNode nestedTerm(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ throws ProgramDefinitionError {
expect(NewTerm, DelimiterOpeningTag.class);
ExpressionNode exp = expression(builder);
expect(EndTerm, DelimiterClosingTag.class);
@@ -1440,8 +1438,7 @@ private String string() throws ParseError {
return s;
}
- private ExpressionNode nestedBlock(final MethodBuilder builder)
- throws ParseError, MixinDefinitionError {
+ private ExpressionNode nestedBlock(final MethodBuilder builder) throws ProgramDefinitionError {
SourceCoordinate coord = getCoordinate();
expect(NewBlock, DelimiterOpeningTag.class);
diff --git a/src/som/compiler/ProgramDefinitionError.java b/src/som/compiler/ProgramDefinitionError.java
new file mode 100644
index 000000000..055d663ba
--- /dev/null
+++ b/src/som/compiler/ProgramDefinitionError.java
@@ -0,0 +1,31 @@
+package som.compiler;
+
+import com.oracle.truffle.api.source.SourceSection;
+
+public abstract class ProgramDefinitionError extends Exception {
+ private static final long serialVersionUID = 318305400750674461L;
+
+ public ProgramDefinitionError(final String message) {
+ super(message);
+ }
+
+ public abstract static class SemanticDefinitionError extends ProgramDefinitionError {
+ private static final long serialVersionUID = -3374814429682547685L;
+ private final SourceSection source;
+
+ protected SemanticDefinitionError(final String message, final SourceSection source) {
+ super(message);
+ this.source = source;
+ }
+
+ public SourceSection getSourceSection() {
+ return source;
+ }
+
+ @Override
+ public String toString() {
+ return source.getSource().getName() + ":" + source.getStartLine() + ":" +
+ source.getStartColumn() + ":error: " + getMessage();
+ }
+ }
+}
diff --git a/src/som/compiler/SourcecodeCompiler.java b/src/som/compiler/SourcecodeCompiler.java
index 106b454be..bfa006896 100644
--- a/src/som/compiler/SourcecodeCompiler.java
+++ b/src/som/compiler/SourcecodeCompiler.java
@@ -27,22 +27,20 @@
import com.oracle.truffle.api.source.Source;
import som.VM;
-import som.compiler.MixinBuilder.MixinDefinitionError;
-import som.compiler.Parser.ParseError;
import tools.SourceCoordinate;
import tools.language.StructuralProbe;
public class SourcecodeCompiler {
public MixinDefinition compileModule(final Source source,
- final StructuralProbe structuralProbe) throws ParseError, MixinDefinitionError {
+ final StructuralProbe structuralProbe) throws ProgramDefinitionError {
Parser parser = new Parser(
source.getReader(), source.getLength(), source, structuralProbe);
return compile(parser, source);
}
protected final MixinDefinition compile(final Parser parser,
- final Source source) throws ParseError, MixinDefinitionError {
+ final Source source) throws ProgramDefinitionError {
SourceCoordinate coord = parser.getCoordinate();
MixinBuilder mxnBuilder = parser.moduleDeclaration();
MixinDefinition result = mxnBuilder.assemble(parser.getSource(coord));
diff --git a/src/som/interpreter/InlinerForLexicallyEmbeddedMethods.java b/src/som/interpreter/InlinerForLexicallyEmbeddedMethods.java
index 7d1de4884..65c4f1457 100644
--- a/src/som/interpreter/InlinerForLexicallyEmbeddedMethods.java
+++ b/src/som/interpreter/InlinerForLexicallyEmbeddedMethods.java
@@ -1,6 +1,13 @@
package som.interpreter;
+import com.oracle.truffle.api.frame.FrameSlot;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.NodeUtil;
+import com.oracle.truffle.api.nodes.NodeVisitor;
+import com.oracle.truffle.api.source.SourceSection;
+
import som.compiler.MethodBuilder;
+import som.compiler.MethodBuilder.MethodDefinitionError;
import som.compiler.Variable.Local;
import som.interpreter.LexicalScope.MethodScope;
import som.interpreter.nodes.ExpressionNode;
@@ -8,12 +15,6 @@
import som.interpreter.nodes.UninitializedVariableNode.UninitializedVariableReadNode;
import som.interpreter.nodes.UninitializedVariableNode.UninitializedVariableWriteNode;
-import com.oracle.truffle.api.frame.FrameSlot;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.api.nodes.NodeUtil;
-import com.oracle.truffle.api.nodes.NodeVisitor;
-import com.oracle.truffle.api.source.SourceSection;
-
public class InlinerForLexicallyEmbeddedMethods implements NodeVisitor {
@@ -48,8 +49,12 @@ public boolean visit(final Node node) {
public UninitializedVariableReadNode getLocalRead(final Object slotIdentifier, final SourceSection source) {
String inlinedId = getEmbeddedSlotId(slotIdentifier);
- builder.addLocalIfAbsent(inlinedId, source);
- return (UninitializedVariableReadNode) builder.getReadNode(inlinedId, source);
+ try {
+ builder.addLocalIfAbsent(inlinedId, source);
+ return (UninitializedVariableReadNode) builder.getReadNode(inlinedId, source);
+ } catch (MethodDefinitionError e) {
+ throw new RuntimeException(e);
+ }
}
private String getEmbeddedSlotId(final Object slotIdentifier) {
@@ -62,7 +67,11 @@ public FrameSlot addLocalSlot(final Object orgSlotId,
final SourceSection source) {
String id = getEmbeddedSlotId(orgSlotId);
assert builder.getEmbeddedLocal(id) == null;
- return builder.addLocal(id, source).getSlot();
+ try {
+ return builder.addLocal(id, source).getSlot();
+ } catch (MethodDefinitionError e) {
+ throw new RuntimeException(e);
+ }
}
public FrameSlot getLocalSlot(final Object orgSlotId) {
@@ -79,9 +88,13 @@ public UninitializedVariableWriteNode getLocalWrite(final Object slotIdentifier,
final ExpressionNode valExp,
final SourceSection source) {
String inlinedId = getEmbeddedSlotId(slotIdentifier);
- builder.addLocalIfAbsent(inlinedId, source);
- return (UninitializedVariableWriteNode) builder.getWriteNode(inlinedId,
- valExp, source);
+ try {
+ builder.addLocalIfAbsent(inlinedId, source);
+ return (UninitializedVariableWriteNode) builder.getWriteNode(inlinedId,
+ valExp, source);
+ } catch (MethodDefinitionError e) {
+ throw new RuntimeException(e);
+ }
}
public ExpressionNode getReplacementForLocalArgument(final int argumentIndex,
diff --git a/src/som/interpreter/nodes/ArgumentReadNode.java b/src/som/interpreter/nodes/ArgumentReadNode.java
index 0eaa166f5..4a0435baa 100644
--- a/src/som/interpreter/nodes/ArgumentReadNode.java
+++ b/src/som/interpreter/nodes/ArgumentReadNode.java
@@ -56,6 +56,8 @@ protected boolean isTaggedWith(final Class> tag) {
return true;
} else if (tag == LocalArgRead.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
@@ -97,8 +99,6 @@ public void replaceWithLexicallyEmbeddedNode(
protected boolean isTaggedWith(final Class> tag) {
if (tag == KeywordTag.class) {
return true;
- } else if (tag == StatementTag.class) {
- return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
@@ -167,6 +167,8 @@ protected boolean isTaggedWith(final Class> tag) {
return true;
} else if (tag == LocalArgRead.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
@@ -209,8 +211,6 @@ protected LocalArgumentReadNode createLocalNode() {
protected boolean isTaggedWith(final Class> tag) {
if (tag == KeywordTag.class) {
return true;
- } else if (tag == StatementTag.class) {
- return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
@@ -244,8 +244,6 @@ public boolean isClassSide() {
protected boolean isTaggedWith(final Class> tag) {
if (tag == KeywordTag.class) {
return true;
- } else if (tag == StatementTag.class) {
- return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
@@ -291,8 +289,6 @@ public boolean isClassSide() {
protected boolean isTaggedWith(final Class> tag) {
if (tag == KeywordTag.class) {
return true;
- } else if (tag == StatementTag.class) {
- return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
diff --git a/src/som/interpreter/nodes/LocalVariableNode.java b/src/som/interpreter/nodes/LocalVariableNode.java
index cfd9c6d55..b785d7c13 100644
--- a/src/som/interpreter/nodes/LocalVariableNode.java
+++ b/src/som/interpreter/nodes/LocalVariableNode.java
@@ -7,6 +7,7 @@
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
import com.oracle.truffle.api.source.SourceSection;
import som.compiler.Variable.Local;
@@ -54,6 +55,8 @@ public final void replaceWithIndependentCopyForInlining(final SplitterForLexical
protected boolean isTaggedWith(final Class> tag) {
if (tag == LocalVariableTag.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
diff --git a/src/som/interpreter/nodes/MessageSendNode.java b/src/som/interpreter/nodes/MessageSendNode.java
index bf819af79..f5927e7a4 100644
--- a/src/som/interpreter/nodes/MessageSendNode.java
+++ b/src/som/interpreter/nodes/MessageSendNode.java
@@ -6,7 +6,8 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.Instrumentable;
-import com.oracle.truffle.api.instrumentation.StandardTags;
+import com.oracle.truffle.api.instrumentation.StandardTags.CallTag;
+import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeCost;
@@ -78,7 +79,9 @@ protected AbstractMessageSendNode(final SourceSection source) {
@Override
protected boolean isTaggedWith(final Class> tag) {
- if (tag == StandardTags.CallTag.class) {
+ if (tag == CallTag.class) {
+ return true;
+ } else if (tag == StatementTag.class) {
return true;
}
return super.isTaggedWith(tag);
diff --git a/src/som/interpreter/nodes/NonLocalVariableNode.java b/src/som/interpreter/nodes/NonLocalVariableNode.java
index c169497de..1d43fbdd3 100644
--- a/src/som/interpreter/nodes/NonLocalVariableNode.java
+++ b/src/som/interpreter/nodes/NonLocalVariableNode.java
@@ -8,6 +8,7 @@
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
import com.oracle.truffle.api.source.SourceSection;
import som.interpreter.InlinerAdaptToEmbeddedOuterContext;
@@ -44,6 +45,8 @@ public final void replaceWithCopyAdaptedToEmbeddedOuterContext(
protected boolean isTaggedWith(final Class> tag) {
if (tag == LocalVariableTag.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
diff --git a/src/som/interpreter/nodes/UninitializedVariableNode.java b/src/som/interpreter/nodes/UninitializedVariableNode.java
index 1df2656d2..d6ba8956b 100644
--- a/src/som/interpreter/nodes/UninitializedVariableNode.java
+++ b/src/som/interpreter/nodes/UninitializedVariableNode.java
@@ -4,6 +4,7 @@
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
import com.oracle.truffle.api.source.SourceSection;
import som.compiler.Variable.Local;
@@ -66,6 +67,8 @@ public UninitializedVariableReadNode(final UninitializedVariableReadNode node,
protected boolean isTaggedWith(final Class> tag) {
if (tag == LocalVarRead.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
@@ -149,6 +152,8 @@ public UninitializedVariableWriteNode(final UninitializedVariableWriteNode node,
protected boolean isTaggedWith(final Class> tag) {
if (tag == LocalVarWrite.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
diff --git a/src/som/interpreter/nodes/literals/LiteralNode.java b/src/som/interpreter/nodes/literals/LiteralNode.java
index 64058f1f4..f815852d1 100644
--- a/src/som/interpreter/nodes/literals/LiteralNode.java
+++ b/src/som/interpreter/nodes/literals/LiteralNode.java
@@ -23,6 +23,7 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.Instrumentable;
+import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.source.SourceSection;
@@ -65,6 +66,8 @@ public ExpressionNode inline(final MethodBuilder builder,
protected boolean isTaggedWith(final Class> tag) {
if (tag == LiteralTag.class) {
return true;
+ } else if (tag == StatementTag.class) {
+ return isMarkedAsRootExpression();
} else {
return super.isTaggedWith(tag);
}
diff --git a/src/som/vm/ObjectSystem.java b/src/som/vm/ObjectSystem.java
index cbb70662e..73c209898 100644
--- a/src/som/vm/ObjectSystem.java
+++ b/src/som/vm/ObjectSystem.java
@@ -18,11 +18,10 @@
import som.VM;
import som.VmSettings;
import som.compiler.AccessModifier;
-import som.compiler.MixinBuilder.MixinDefinitionError;
import som.compiler.MixinBuilder.MixinDefinitionId;
import som.compiler.MixinDefinition;
import som.compiler.MixinDefinition.SlotDefinition;
-import som.compiler.Parser.ParseError;
+import som.compiler.ProgramDefinitionError;
import som.compiler.SourcecodeCompiler;
import som.interpreter.LexicalScope.MixinScope;
import som.interpreter.SomLanguage;
@@ -105,7 +104,7 @@ public MixinDefinition loadModule(final Source source) throws IOException {
module = compiler.compileModule(source, structuralProbe);
loadedModules.put(uri, module);
return module;
- } catch (ParseError | MixinDefinitionError e) {
+ } catch (ProgramDefinitionError e) {
VM.errorExit(e.getMessage());
throw new IOException(e);
}
diff --git a/src/som/vmobjects/SArray.java b/src/som/vmobjects/SArray.java
index 410dc1b72..ef8d2da5a 100644
--- a/src/som/vmobjects/SArray.java
+++ b/src/som/vmobjects/SArray.java
@@ -27,6 +27,7 @@ public SArray(final long length, final SClass clazz) {
public SArray(final Object storage, final SClass clazz) {
assert !(storage instanceof Long);
+ assert storage != null;
this.storage = storage;
this.clazz = clazz;
}
diff --git a/src/tools/debugger/WebDebugger.java b/src/tools/debugger/WebDebugger.java
index 6412d6b07..7e1041091 100644
--- a/src/tools/debugger/WebDebugger.java
+++ b/src/tools/debugger/WebDebugger.java
@@ -1,6 +1,5 @@
package tools.debugger;
-import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -70,7 +69,7 @@ public class WebDebugger extends TruffleInstrument implements SuspendedCallback
private final Map> rootNodes = new HashMap<>();
private int nextActivityId = 0;
- private final Map, Suspension> activityToSuspension = new HashMap<>();
+ private final Map