Skip to content

Commit

Permalink
case boolean of can be performed on non-primitive booleans
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Feb 10, 2025
1 parent f6e5ef9 commit b7e55e7
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.enso.interpreter.test;

import static org.junit.Assert.assertEquals;

import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.test.utils.ContextUtils;
import org.graalvm.polyglot.Context;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class CaseOfTest {
private static Context ctx;
private static EnsoContext leak;

@BeforeClass
public static void initCtx() throws Exception {
ctx = ContextUtils.createDefaultContext();
leak = ContextUtils.leakContext(ctx);
}

@AfterClass
public static void closeCtx() {
ctx.close();
ctx = null;
leak = null;
}

@Test
public void caseOfBoolean() {
doCaseOfBoolean(true, false);
}

@Test
public void caseOfInteropBoolean() {
var t = new WrappedPrimitive(true);
var f = new WrappedPrimitive(false);
doCaseOfBoolean(t, f);
}

@Test
public void caseOfMultiValueBoolean() {
var n = EnsoMultiValue.NewNode.getUncached();

var bAndT =
new Type[] {leak.getBuiltins().bool().getType(), leak.getBuiltins().number().getInteger()};
var t = n.newValue(bAndT, 2, 0, new Object[] {true, 300});
var f = n.newValue(bAndT, 2, 0, new Object[] {false, 200});
doCaseOfBoolean(t, f);
}

private void doCaseOfBoolean(Object t, Object f) {
var code =
"""
from Standard.Base import True, False
choose v = case v of
True -> 1
False -> 2
_ -> 3
""";

var choose = ContextUtils.evalModule(ctx, code, "choose.enso", "choose");

var one = choose.execute(t);
assertEquals("With " + t + " we should get 1", 1, one.asInt());
var two = choose.execute(f);
assertEquals("With " + f + " we should get 2", 2, two.asInt());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
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.NodeInfo;
import com.oracle.truffle.api.profiles.CountingConditionProfile;
import org.enso.interpreter.runtime.EnsoContext;

/** An implementation of the case expression specialised to working on booleans. */
@NodeInfo(shortName = "BooleanMatch")
Expand All @@ -31,12 +35,31 @@ public static BooleanBranchNode build(
}

@Specialization
void doAtom(VirtualFrame frame, Object state, boolean target) {
void doBoolean(VirtualFrame frame, Object state, boolean target) {
if (profile.profile(matched == target)) {
accept(frame, state, new Object[0]);
}
}

@Specialization(
guards = {"iop.isBoolean(target)"},
limit = "3")
void doInterop(
VirtualFrame frame,
Object state,
Object target,
@CachedLibrary("target") InteropLibrary iop) {
try {
var value = iop.asBoolean(target);
if (profile.profile(matched == value)) {
accept(frame, state, new Object[0]);
}
} catch (UnsupportedMessageException ex) {
var ctx = EnsoContext.get(this);
throw ctx.raiseAssertionPanic(this, null, ex);
}
}

@Fallback
void doFallback(VirtualFrame frame, Object state, Object target) {}
}

0 comments on commit b7e55e7

Please sign in to comment.