Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ jobs:
./som.sh -cp core-lib/Smalltalk:core-lib/TestSuite:core-lib/SomSom/src/compiler:core-lib/SomSom/src/vm:core-lib/SomSom/src/vmobjects:core-lib/SomSom/src/interpreter:core-lib/SomSom/src/primitives \
core-lib/SomSom/tests/SomSomTests.som

- name: Integration Tests
run: |
python -m pip install --upgrade pip
pip install pytest
export VM=./som.sh
export CLASSPATH=Smalltalk
export AWFY=Examples/AreWeFastYet/Core
export TEST_EXPECTATIONS=./integration-tests.yml
pytest --tb=short core-lib/IntegrationTests

- name: CheckStyle
run: |
ant checkstyle
Expand Down
2 changes: 1 addition & 1 deletion core-lib
Submodule core-lib updated 252 files
130 changes: 130 additions & 0 deletions integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
known_failures: []


failing_as_unspecified:
- Tests/arbint_double_div_err.som
- Tests/arbint_double_div_zero_err.som
- Tests/arbint_modulus_err.som
- Tests/array_at_idx0_err.som
- Tests/array_at_idx2_err.som
- Tests/array_at_idx_err.som
- Tests/array_at_negative_idx_err.som
- Tests/array_at_put_idx0_err.som
- Tests/array_at_put_idx2_err.som
- Tests/call2.som

# I think this one is about E vs e, but maybe also double rendering
- Tests/double2.som
# - Tests/int_double_div.som
# - Tests/integer_asdouble.som


# I think IEEE allows for infinities here, and we probably want that
- Tests/double3.som
- Tests/double4.som
- Tests/double5.som
- Tests/double6.som
- Tests/double7.som
- Tests/double8.som
- Tests/double9.som
- Tests/double11.som
- Tests/double13.som

# Java seems to do some rounding in the transition, but it's also requiring bigints
- Tests/double_asinteger.som


- Tests/double_double_div_err.som
- Tests/double_double_div_zero_err1.som
- Tests/double_double_div_zero_err2.som
- Tests/double_double_div_zero_err3.som
- Tests/double_double_div_zero_err4.som
- Tests/double_modulus.som
- Tests/double_modulus_err.som

- Tests/exit_double.som
- Tests/exit_int_too_big.som
- Tests/exit_string.som

- Tests/fromstring_double_err.som
- Tests/fromstring_err.som

- Tests/hashcode2.som

- Tests/inst_var_at_bad_idx.som
- Tests/inst_var_at_put_bad_idx.som

- Tests/instance_fields_overlap/test.som
- Tests/instance_fields_overlap2.som

- Tests/int5.som
- Tests/int8.som
- Tests/int9.som

- Tests/int10.som
- Tests/int11.som
- Tests/int12.som
- Tests/int13.som
- Tests/int14.som
- Tests/int15.som
- Tests/int16.som
- Tests/int17.som

# too large shifts would take too much memory to support
# need to specify this some how
- Tests/int20.som
- Tests/int21.som
- Tests/int22.som
- Tests/int23.som
- Tests/int25.som
- Tests/int27.som
- Tests/int28.som
- Tests/int31.som

- Tests/int_double_div_err.som
- Tests/int_double_div_zero_err.som
- Tests/int_modulus.som
- Tests/int_modulus_err.som

- Tests/load_string.som

- Tests/mutate_methods.som
- Tests/mutate_superclass_method/test.som

- Tests/nested_backtrace1.som
- Tests/nested_backtrace2.som

- Tests/obj2.som

- Tests/perform_string.som
- Tests/perform_witharguments_wrong.som

- Tests/remainder_zero.som
- Tests/round.som

- Tests/shift_right.som
- Tests/shift_right_too_big.som
- Tests/shift_right_type_err.som

- Tests/str_escape_unknown.som

- Tests/system2.som
- Tests/system_global_lookup_string.som
- Tests/system_global_put_string.som

- Tests/test_literals_limit_1.som
- Tests/test_literals_limit_2.som
- Tests/unknown_field_write.som

# This should be specified so that the "set" of fields cannot be changed reflectively
# they obtained array can be changed, but it is expected to have no effect.
- Tests/mutate_fields.som


unsupported: []


do_not_run:
- Tests/case_insensitive.som
# floating point printing changes between JDK versions, I think
- Tests/double_double_div.som
10 changes: 9 additions & 1 deletion src/som/compiler/ClassGenerationContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,18 @@ public void startClassSide() {
classSide = true;
}

public void addField(final SSymbol field) {
public void addField(final SSymbol field) throws ProgramDefinitionError {
if (classSide) {
if (classFields.contains(field)) {
throw new ProgramDefinitionError("The class " + name.getEmbeddedString()
+ " cannot have two fields with the name `" + field.getEmbeddedString() + "`.");
}
classFields.add(field);
} else {
if (instanceFields.contains(field)) {
throw new ProgramDefinitionError("The class " + name.getEmbeddedString()
+ " cannot have two fields with the name `" + field.getEmbeddedString() + "`.");
}
instanceFields.add(field);
}
}
Expand Down
16 changes: 6 additions & 10 deletions src/som/compiler/MethodGenerationContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ public MethodGenerationContext(final ClassGenerationContext holderGenc) {
this(holderGenc, null);
}

public void addArgument(final String arg) {
public void addArgument(final String arg) throws ProgramDefinitionError {
if (arguments.contains(arg)) {
throw new ProgramDefinitionError(
"A method cannot have two arguments with the same name `" + arg + "` in class "
+ holderGenc.getName().getEmbeddedString() + ".");
}
arguments.add(arg);
}

Expand Down Expand Up @@ -195,15 +200,6 @@ public void setSignature(final SSymbol sig) {
signature = sig;
}

public boolean addArgumentIfAbsent(final String arg) {
if (arguments.contains(arg)) {
return false;
}

arguments.add(arg);
return true;
}

public boolean isFinished() {
return finished;
}
Expand Down
27 changes: 16 additions & 11 deletions src/som/compiler/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ private boolean expectOneOf(final List<Symbol> ss) {
throw new IllegalStateException(err.toString());
}

private void fields() {
private void fields() throws ProgramDefinitionError {
if (accept(Or)) {
while (sym == Identifier) {
String var = variable();
Expand All @@ -333,7 +333,7 @@ private void primitiveBlock() {
expect(Primitive);
}

private void pattern(final MethodGenerationContext mgenc) {
private void pattern(final MethodGenerationContext mgenc) throws ProgramDefinitionError {
switch (sym) {
case Identifier:
unaryPattern(mgenc);
Expand All @@ -351,16 +351,18 @@ private void unaryPattern(final MethodGenerationContext mgenc) {
mgenc.setSignature(unarySelector());
}

private void binaryPattern(final MethodGenerationContext mgenc) {
private void binaryPattern(final MethodGenerationContext mgenc)
throws ProgramDefinitionError {
mgenc.setSignature(binarySelector());
mgenc.addArgumentIfAbsent(argument());
mgenc.addArgument(argument());
}

private void keywordPattern(final MethodGenerationContext mgenc) {
private void keywordPattern(final MethodGenerationContext mgenc)
throws ProgramDefinitionError {
StringBuilder kw = new StringBuilder();
do {
kw.append(keyword());
mgenc.addArgumentIfAbsent(argument());
mgenc.addArgument(argument());
} while (sym == Keyword);

mgenc.setSignature(universe.symbolFor(kw.toString()));
Expand Down Expand Up @@ -845,7 +847,7 @@ private String string() {
}

private void nestedBlock(final MethodGenerationContext mgenc) throws ProgramDefinitionError {
mgenc.addArgumentIfAbsent("$block self");
mgenc.addArgument("$block self");

expect(NewBlock);
if (sym == Colon) {
Expand Down Expand Up @@ -880,15 +882,17 @@ private void nestedBlock(final MethodGenerationContext mgenc) throws ProgramDefi
expect(EndBlock);
}

private void blockPattern(final MethodGenerationContext mgenc) {
private void blockPattern(final MethodGenerationContext mgenc)
throws ProgramDefinitionError {
blockArguments(mgenc);
expect(Or);
}

private void blockArguments(final MethodGenerationContext mgenc) {
private void blockArguments(final MethodGenerationContext mgenc)
throws ProgramDefinitionError {
do {
expect(Colon);
mgenc.addArgumentIfAbsent(argument());
mgenc.addArgument(argument());
} while (sym == Colon);
}

Expand Down Expand Up @@ -944,7 +948,8 @@ private void genPopVariable(final MethodGenerationContext mgenc,
SSymbol varName = universe.symbolFor(var);
if (!mgenc.hasField(varName)) {
throw new ParseError("Trying to write to field with the name '" + var
+ "', but field does not seem exist in class.", Symbol.NONE, this);
+ "', but field does not seem exist in the class "
+ mgenc.getHolder().getName().getEmbeddedString() + ".", Symbol.NONE, this);
}
bcGen.emitPOPFIELD(mgenc, varName);
}
Expand Down
13 changes: 9 additions & 4 deletions src/som/primitives/IntegerPrimitives.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void invoke(final Frame frame, final Interpreter interpreter) {
installInstancePrimitive(new SPrimitive("sqrt", universe) {
@Override
public void invoke(final Frame frame, final Interpreter interpreter) {
SInteger self = (SInteger) frame.pop();
SNumber self = (SNumber) frame.pop();
frame.push(self.primSqrt(universe));
}
});
Expand Down Expand Up @@ -204,9 +204,14 @@ public void invoke(final Frame frame, final Interpreter interpreter) {
installInstancePrimitive(new SPrimitive("as32BitUnsignedValue", universe) {
@Override
public void invoke(final Frame frame, final Interpreter interpreter) {
SInteger rcvr = (SInteger) frame.pop();
frame.push(
universe.newInteger(Integer.toUnsignedLong((int) rcvr.getEmbeddedInteger())));
SNumber receiver = (SNumber) frame.pop();
int value;
if (receiver instanceof SInteger rcvr) {
value = (int) rcvr.getEmbeddedInteger();
} else {
value = ((SBigInteger) receiver).getEmbeddedBiginteger().intValue();
}
frame.push(universe.newInteger(Integer.toUnsignedLong(value)));
}
});

Expand Down
27 changes: 24 additions & 3 deletions src/som/primitives/ObjectPrimitives.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void invoke(final Frame frame, final Interpreter interpreter) {
SSymbol selector = (SSymbol) arg;

SInvokable invokable = self.getSOMClass(universe).lookupInvokable(selector);
invokable.invoke(frame, interpreter);
interpreter.activateOrDnu(selector, invokable);
}
});

Expand All @@ -108,7 +108,28 @@ public void invoke(final Frame frame, final Interpreter interpreter) {
SClass clazz = (SClass) arg2;

SInvokable invokable = clazz.lookupInvokable(selector);
invokable.invoke(frame, interpreter);
interpreter.activateOrDnu(selector, invokable);
}
});

installInstancePrimitive(new SPrimitive("perform:withArguments:inSuperclass:", universe) {
@Override
public void invoke(final Frame frame, final Interpreter interpreter) {
SAbstractObject arg3 = frame.pop();
SAbstractObject arg2 = frame.pop();
SAbstractObject arg = frame.pop();
// Object self = frame.getStackElement(0);

SSymbol selector = (SSymbol) arg;
SArray args = (SArray) arg2;
SClass clazz = (SClass) arg3;

for (int i = 0; i < args.getNumberOfIndexableFields(); i++) {
frame.push(args.getIndexableField(i));
}

SInvokable invokable = clazz.lookupInvokable(selector);
interpreter.activateOrDnu(selector, invokable);
}
});

Expand All @@ -127,7 +148,7 @@ public void invoke(final Frame frame, final Interpreter interpreter) {
}

SInvokable invokable = self.getSOMClass(universe).lookupInvokable(selector);
invokable.invoke(frame, interpreter);
interpreter.activateOrDnu(selector, invokable);
}
});

Expand Down
3 changes: 2 additions & 1 deletion src/som/primitives/SystemPrimitives.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public void invoke(final Frame frame, final Interpreter interpreter) {
try {
result = universe.loadClass(argument);
} catch (ProgramDefinitionError e) {
universe.errorExit(e.toString());
Universe.errorPrintln("Program Definition Error: " + e.getMessage());
universe.exit(1);
}
frame.push(result != null ? result : universe.nilObject);
}
Expand Down
Loading