mirror of
https://github.com/enso-org/enso.git
synced 2024-11-23 08:08:34 +03:00
Treat Boolean.False as false primitive (#6090)
Treat `Boolean.False` and `Boolean.True` as the corresponding primitives. Now, `Boolean.False == False` returns true. # Important Notes `False` and `True` constructs, that are converted to `ConstructorNode` during Truffle codegen, are handled specially in `ConstructorNode`. The easiest fix was to implement a similar special handling in `QualifiedAccessorNode`, although not the cleanest one. A better solution would be to provide transformation of `Boolean.True` IR to a true literal in `ApplicationSaturation` compiler pass. But `ApplicationSaturation` pass does not handle `True`. Moreover, for our case, it is unnecessarily complicated.
This commit is contained in:
parent
3f7c4a47da
commit
9bec3a4e71
@ -4,6 +4,7 @@ import com.oracle.truffle.api.TruffleLanguage;
|
|||||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||||
import com.oracle.truffle.api.nodes.RootNode;
|
import com.oracle.truffle.api.nodes.RootNode;
|
||||||
|
import org.enso.interpreter.runtime.EnsoContext;
|
||||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||||
|
|
||||||
@NodeInfo(
|
@NodeInfo(
|
||||||
@ -36,7 +37,16 @@ public class QualifiedAccessorNode extends RootNode {
|
|||||||
*/
|
*/
|
||||||
public Object execute(VirtualFrame frame) {
|
public Object execute(VirtualFrame frame) {
|
||||||
if (atomConstructor.getArity() == 0) {
|
if (atomConstructor.getArity() == 0) {
|
||||||
return atomConstructor.newInstance();
|
var trueCtor = EnsoContext.get(this).getBuiltins().bool().getTrue();
|
||||||
|
var falseCtor = EnsoContext.get(this).getBuiltins().bool().getFalse();
|
||||||
|
// This matches the shortcuts provided in ConstructorNode
|
||||||
|
if (atomConstructor == trueCtor) {
|
||||||
|
return true;
|
||||||
|
} else if (atomConstructor == falseCtor) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return atomConstructor.newInstance();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return atomConstructor;
|
return atomConstructor;
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,20 @@ class BooleanTest extends InterpreterTest {
|
|||||||
interpreterContext: InterpreterContext
|
interpreterContext: InterpreterContext
|
||||||
): Unit = {
|
): Unit = {
|
||||||
|
|
||||||
|
val defaultImports =
|
||||||
|
"""
|
||||||
|
|from Standard.Base.Data.Boolean import all
|
||||||
|
|import Standard.Base.IO
|
||||||
|
|""".stripMargin
|
||||||
|
|
||||||
"support if_then_else" in {
|
"support if_then_else" in {
|
||||||
val code =
|
val code =
|
||||||
"""from Standard.Base.Data.Boolean import all
|
s"""$defaultImports
|
||||||
|import Standard.Base.IO
|
|
|
||||||
|
|
|main =
|
||||||
|main =
|
| if True then IO.println "true when true" else IO.println "false when true"
|
||||||
| if True then IO.println "true when true" else IO.println "false when true"
|
| if False then IO.println "true when false" else IO.println "false when false"
|
||||||
| if False then IO.println "true when false" else IO.println "false when false"
|
|""".stripMargin
|
||||||
|""".stripMargin
|
|
||||||
eval(code)
|
eval(code)
|
||||||
consumeOut shouldEqual List("true when true", "false when false")
|
consumeOut shouldEqual List("true when true", "false when false")
|
||||||
}
|
}
|
||||||
@ -57,32 +62,55 @@ class BooleanTest extends InterpreterTest {
|
|||||||
|
|
||||||
"support logical AND and OR operators" in {
|
"support logical AND and OR operators" in {
|
||||||
val code =
|
val code =
|
||||||
"""from Standard.Base.Data.Boolean import all
|
s"""$defaultImports
|
||||||
|import Standard.Base.IO
|
|
|
||||||
|
|
|main =
|
||||||
|main =
|
| IO.println True&&False
|
||||||
| IO.println True&&False
|
| IO.println True&&True
|
||||||
| IO.println True&&True
|
| IO.println True&&Boolean.True
|
||||||
| IO.println False||False
|
| IO.println False||False
|
||||||
| IO.println True||False
|
| IO.println True||False
|
||||||
| IO.println ((True && False) || (True && True))
|
| IO.println ((True && False) || (True && True))
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
eval(code)
|
eval(code)
|
||||||
consumeOut shouldEqual List("False", "True", "False", "True", "True")
|
consumeOut shouldEqual List(
|
||||||
|
"False",
|
||||||
|
"True",
|
||||||
|
"True",
|
||||||
|
"False",
|
||||||
|
"True",
|
||||||
|
"True"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"support negation" in {
|
"support negation" in {
|
||||||
val code =
|
val code =
|
||||||
"""from Standard.Base.Data.Boolean import all
|
s"""$defaultImports
|
||||||
|import Standard.Base.IO
|
|
|
||||||
|
|
|main =
|
||||||
|main =
|
| IO.println True.not
|
||||||
| IO.println True.not
|
| IO.println Boolean.True.not
|
||||||
| IO.println False.not
|
| IO.println False.not
|
||||||
| IO.println (1==2 . not)
|
| IO.println Boolean.False.not
|
||||||
|""".stripMargin
|
| IO.println (1==2 . not)
|
||||||
|
|""".stripMargin
|
||||||
eval(code)
|
eval(code)
|
||||||
consumeOut shouldEqual List("False", "True", "True")
|
consumeOut shouldEqual List("False", "False", "True", "True", "True")
|
||||||
|
}
|
||||||
|
|
||||||
|
"literal equals atom constructor" in {
|
||||||
|
val code =
|
||||||
|
s"""$defaultImports
|
||||||
|
|
|
||||||
|
|main =
|
||||||
|
| IO.println (False == Boolean.False)
|
||||||
|
| IO.println (Boolean.False == False)
|
||||||
|
| IO.println (True == Boolean.True)
|
||||||
|
| IO.println (Boolean.True == True)
|
||||||
|
|
|
||||||
|
|""".stripMargin
|
||||||
|
eval(code)
|
||||||
|
consumeOut shouldEqual List("True", "True", "True", "True")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ object DistributionPackage {
|
|||||||
path.globRecursive("*.enso").get().toSet
|
path.globRecursive("*.enso").get().toSet
|
||||||
) { diff =>
|
) { diff =>
|
||||||
if (diff.modified.nonEmpty) {
|
if (diff.modified.nonEmpty) {
|
||||||
println(s"Generating index for ${libName} ")
|
log.info(s"Generating index for $libName")
|
||||||
val command = Seq(
|
val command = Seq(
|
||||||
Platform.executableFileName(ensoExecutable.toString),
|
Platform.executableFileName(ensoExecutable.toString),
|
||||||
"--no-compile-dependencies",
|
"--no-compile-dependencies",
|
||||||
|
Loading…
Reference in New Issue
Block a user