Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dispatch of to_text, is_a & co. on intersection types #12192

Merged
merged 16 commits into from
Feb 12, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;

import java.math.BigInteger;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.number.EnsoBigInteger;
import org.enso.interpreter.test.WrappedPrimitive;
import org.enso.test.utils.ContextUtils;
import org.enso.test.utils.TestRootNode;
import org.graalvm.polyglot.Context;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/** Tests Truffle nodes for integer operations. */
public class FloatTest {

private static AbsNode absNode;
private static AddNode addNode;
private static TestRootNode root;
private static Context ctx;

@BeforeClass
public static void setup() {
ctx = ContextUtils.createDefaultContext();
ContextUtils.executeInContext(
ctx,
() -> {
absNode = AbsNode.build();
addNode = AddNode.build();

root = new TestRootNode();
root.insertChildren(absNode, addNode);
return null;
});
}

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

private static final EnsoBigInteger bigInt =
new EnsoBigInteger(new BigInteger("1000000000000000000000000000000000000"));
private static final EnsoBigInteger bigIntNegative =
new EnsoBigInteger(new BigInteger("-1000000000000000000000000000000000000"));

@Test
public void testAbs23() {
ContextUtils.executeInContext(
ctx,
() -> {
assertEquals(23.1, absNode.execute(23.1), 0.01);
assertEquals(23.1, absNode.execute(-23.1), 0.01);
return null;
});
}

@Test
public void testAdd21And1Point0() {
ContextUtils.executeInContext(
ctx,
() -> {
assertEquals(23.1, addNode.execute(22.0, 1.1), 0.01);
return null;
});
}

@Test
public void testAdd21And1() {
ContextUtils.executeInContext(
ctx,
() -> {
assertEquals(23.1, addNode.execute(22.1, 1L), 0.01);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AddNode for Float handles both long as well as double as second argument.

return null;
});
}

@Test
public void testAddMulti21And1() {
ContextUtils.executeInContext(
ctx,
() -> {
var nn = EnsoMultiValue.NewNode.getUncached();
var leak = ContextUtils.leakContext(ctx);
var floatType = leak.getBuiltins().number().getFloat();
var textType = leak.getBuiltins().text();
var both = new Type[] {floatType, textType};
var twentyTwoHello = nn.newValue(both, 2, 0, new Object[] {22.1, "Hello"});
assertEquals(23.2, addNode.execute(1.1, twentyTwoHello), 0.01);
return null;
});
}

@Test
public void testAddInterop21And1() {
ContextUtils.executeInContext(
ctx,
() -> {
var twentyOne = new WrappedPrimitive(21.1);
assertEquals(23.1, addNode.execute(2.0, twentyOne), 0.01);
return null;
});
}

@Test
public void testAddDoubleAndText() {
ContextUtils.executeInContext(
ctx,
() -> {
assertThrows(PanicException.class, () -> addNode.execute(23.1, "Hello"));
return null;
});
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package org.enso.interpreter.test;
package org.enso.interpreter.node.expression.builtin.number.integer;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import java.math.BigInteger;
import org.enso.interpreter.node.expression.builtin.number.integer.AbsNode;
import org.enso.interpreter.node.expression.builtin.number.integer.AddNode;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.number.EnsoBigInteger;
import org.enso.interpreter.test.WrappedPrimitive;
import org.enso.test.utils.ContextUtils;
import org.enso.test.utils.TestRootNode;
import org.graalvm.polyglot.Context;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.theories.Theories;
import org.junit.runner.RunWith;

/** Tests Truffle nodes for integer operations. */
@RunWith(Theories.class)
public class IntegerTest {

private static AbsNode absNode;
private static AddNode addNode;
private static TestRootNode root;
private static Context ctx;

@BeforeClass
Expand All @@ -33,6 +33,9 @@ public static void setup() {
() -> {
absNode = AbsNode.build();
addNode = AddNode.build();

root = new TestRootNode();
root.insertChildren(absNode, addNode);
return null;
});
}
Expand All @@ -49,15 +52,33 @@ public static void teardown() {
new EnsoBigInteger(new BigInteger("-1000000000000000000000000000000000000"));

@Test
public void testAbs() {
public void testAbs23() {
ContextUtils.executeInContext(
ctx,
() -> {
assertEquals(23L, absNode.execute(23L));
assertEquals(23L, absNode.execute(-23L));
return null;
});
}

@Test
public void testAbsBig() {
ContextUtils.executeInContext(
ctx,
() -> {
assertTrue(absNode.execute(Long.MIN_VALUE) instanceof EnsoBigInteger);
assertEquals(bigInt, absNode.execute(bigInt));
assertEquals(bigInt, absNode.execute(bigIntNegative));
return null;
});
}

@Test
public void testAbsPanic() {
ContextUtils.executeInContext(
ctx,
() -> {
assertThrows(
"Decimals are not supported", PanicException.class, () -> absNode.execute(23.0));
assertThrows(
Expand All @@ -67,11 +88,57 @@ public void testAbs() {
}

@Test
public void testAdd() {
public void testAdd21And1() {
ContextUtils.executeInContext(
ctx,
() -> {
assertEquals(23L, addNode.execute(22L, 1L));
return null;
});
}

@Test
public void testAdd21And1Point0() {
ContextUtils.executeInContext(
ctx,
() -> {
assertEquals(23.1, ((Number) addNode.execute(22L, 1.1)).doubleValue(), 0.01);
return null;
});
}

@Test
public void testAddMulti21And1() {
ContextUtils.executeInContext(
ctx,
() -> {
var nn = EnsoMultiValue.NewNode.getUncached();
var leak = ContextUtils.leakContext(ctx);
var intType = leak.getBuiltins().number().getInteger();
var textType = leak.getBuiltins().text();
var both = new Type[] {intType, textType};
var twentyTwoHello = nn.newValue(both, 2, 0, new Object[] {22L, "Hello"});
assertEquals(23L, addNode.execute(twentyTwoHello, 1L));
return null;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified IntegerNode.Binary accepts EnsoMultiValue

});
}

@Test
public void testAddInterop21And1() {
ContextUtils.executeInContext(
ctx,
() -> {
var twentyOne = new WrappedPrimitive(21L);
assertEquals(23L, addNode.execute(twentyOne, 2L));
return null;
});
}

@Test
public void testAddLongAndText() {
ContextUtils.executeInContext(
ctx,
() -> {
assertThrows(PanicException.class, () -> addNode.execute(23L, "Hello"));
return null;
});
Expand Down
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);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case bool of needs to handle both Boolean as well as EnsoMultiValue.

}

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());
}
}
Loading
Loading