Skip to content

Commit

Permalink
Support multi-dimensional Vectors with warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
hubertp committed Dec 6, 2022
1 parent b45ef9d commit fed4ead
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.WarningsLibrary;
import org.enso.interpreter.runtime.error.WithWarnings;

public abstract class ExpectStringNode extends Node {
Expand All @@ -32,9 +34,13 @@ String doString(String str) {
return str;
}

@Specialization
String doWarning(WithWarnings value) {
return execute(value.getValue());
@Specialization(guards = "warnings.hasWarnings(warning)")
String doWarning(Object warning, @CachedLibrary(limit = "3") WarningsLibrary warnings) {
try {
return execute(warnings.removeWarnings(warning));
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
}
}

@Fallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
Expand Down Expand Up @@ -32,18 +33,22 @@ public final class Array implements TruffleObject {
*
* @param items the element values
*/
@Builtin.Method(expandVarargs = 4, description = "Creates an array with given elements.", autoRegister = false)
@Builtin.Method(
expandVarargs = 4,
description = "Creates an array with given elements.",
autoRegister = false)
public Array(Object... items) {
this.items = items;
this.withWarnings = hasWarningElements(items);
}

/**
* Creates an uninitialized array of the given size.
*
* @param size the size of the created array.
*/
@Builtin.Method(description = "Creates an uninitialized array of a given size.", autoRegister = false)
@Builtin.Method(
description = "Creates an uninitialized array of a given size.",
autoRegister = false)
public Array(long size) {
this.items = new Object[(int) size];
}
Expand Down Expand Up @@ -131,47 +136,48 @@ boolean hasType() {
return true;
}

@ExplodeLoop
private boolean hasWarningElements(Object[] items) {
private boolean hasWarningElements(Object[] items, WarningsLibrary warnings) {
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof WithWarnings) {
if (warnings.hasWarnings(items[i])) {
return true;
}
}
return false;
}

@ExportMessage
boolean hasWarnings() {
boolean hasWarnings(@CachedLibrary(limit = "3") WarningsLibrary warnings) {
if (withWarnings == null) {
withWarnings = hasWarningElements(items);
withWarnings = hasWarningElements(items, warnings);
}
return withWarnings;
}

@ExportMessage
@ExplodeLoop
Warning[] getWarnings(Node location) {
ArrayRope<Warning> warnings = new ArrayRope<>();
Warning[] getWarnings(Node location, @CachedLibrary(limit = "3") WarningsLibrary warnings) {
ArrayRope<Warning> ropeOfWarnings = new ArrayRope<>();
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof WithWarnings w) {
if (location != null) {
warnings = warnings.prepend(w.getReassignedWarnings(location));
} else {
warnings = warnings.prepend(w.collectWarnings());
if (warnings.hasWarnings(items[i])) {
try {
ropeOfWarnings = ropeOfWarnings.prepend(warnings.getWarnings(items[i], location));
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
}
}
}
return warnings.toArray(Warning[]::new);
return ropeOfWarnings.toArray(Warning[]::new);
}

@ExportMessage
@ExplodeLoop
Array removeWarnings() {
Array removeWarnings(@CachedLibrary(limit = "3") WarningsLibrary warnings) {
Object[] items = new Object[this.items.length];
for (int i = 0; i < this.items.length; i++) {
if (this.items[i] instanceof WithWarnings w) {
items[i] = w.getValue();
if (warnings.hasWarnings(this.items[i])) {
try {
items[i] = warnings.removeWarnings(this.items[i]);
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
}
} else {
items[i] = this.items[i];
}
Expand Down
8 changes: 8 additions & 0 deletions test/Tests/src/Semantic/Warnings_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ spec = Test.group "Dataflow Warnings" <|
r.should_equal [0, 1, 20, 3, 40, 5, 60, 7, 80, 9]
Warning.get_all r . map .value . should_contain_the_same_elements_as [100, 300, 500, 700, 900]

Test.specify "should be preserved after operations on multi-dimensional Vector" <|
even x = (Warning.attach x x) % 2
nested_range_even x =
(0.up_to x).to_vector.map even
res = [1, 2, 3, 4].map nested_range_even

res . should_equal [[0], [0, 1], [0, 1, 0], [0, 1, 0, 1]]
Warning.get_all res . map .value . should_equal [3, 2, 1, 0, 2, 1, 0, 1, 0, 0]
Warning.get_all (res.at 2) . map .value . should_equal [2, 1, 0]

main = Test_Suite.run_main spec

0 comments on commit fed4ead

Please sign in to comment.