mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +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.nodes.NodeInfo;
|
||||
import com.oracle.truffle.api.nodes.RootNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
|
||||
@NodeInfo(
|
||||
@ -36,7 +37,16 @@ public class QualifiedAccessorNode extends RootNode {
|
||||
*/
|
||||
public Object execute(VirtualFrame frame) {
|
||||
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 {
|
||||
return atomConstructor;
|
||||
}
|
||||
|
@ -9,15 +9,20 @@ class BooleanTest extends InterpreterTest {
|
||||
interpreterContext: InterpreterContext
|
||||
): Unit = {
|
||||
|
||||
val defaultImports =
|
||||
"""
|
||||
|from Standard.Base.Data.Boolean import all
|
||||
|import Standard.Base.IO
|
||||
|""".stripMargin
|
||||
|
||||
"support if_then_else" in {
|
||||
val code =
|
||||
"""from Standard.Base.Data.Boolean import all
|
||||
|import Standard.Base.IO
|
||||
|
|
||||
|main =
|
||||
| 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"
|
||||
|""".stripMargin
|
||||
s"""$defaultImports
|
||||
|
|
||||
|main =
|
||||
| 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"
|
||||
|""".stripMargin
|
||||
eval(code)
|
||||
consumeOut shouldEqual List("true when true", "false when false")
|
||||
}
|
||||
@ -57,32 +62,55 @@ class BooleanTest extends InterpreterTest {
|
||||
|
||||
"support logical AND and OR operators" in {
|
||||
val code =
|
||||
"""from Standard.Base.Data.Boolean import all
|
||||
|import Standard.Base.IO
|
||||
|
|
||||
|main =
|
||||
| IO.println True&&False
|
||||
| IO.println True&&True
|
||||
| IO.println False||False
|
||||
| IO.println True||False
|
||||
| IO.println ((True && False) || (True && True))
|
||||
|""".stripMargin
|
||||
s"""$defaultImports
|
||||
|
|
||||
|main =
|
||||
| IO.println True&&False
|
||||
| IO.println True&&True
|
||||
| IO.println True&&Boolean.True
|
||||
| IO.println False||False
|
||||
| IO.println True||False
|
||||
| IO.println ((True && False) || (True && True))
|
||||
|""".stripMargin
|
||||
eval(code)
|
||||
consumeOut shouldEqual List("False", "True", "False", "True", "True")
|
||||
consumeOut shouldEqual List(
|
||||
"False",
|
||||
"True",
|
||||
"True",
|
||||
"False",
|
||||
"True",
|
||||
"True"
|
||||
)
|
||||
}
|
||||
|
||||
"support negation" in {
|
||||
val code =
|
||||
"""from Standard.Base.Data.Boolean import all
|
||||
|import Standard.Base.IO
|
||||
|
|
||||
|main =
|
||||
| IO.println True.not
|
||||
| IO.println False.not
|
||||
| IO.println (1==2 . not)
|
||||
|""".stripMargin
|
||||
s"""$defaultImports
|
||||
|
|
||||
|main =
|
||||
| IO.println True.not
|
||||
| IO.println Boolean.True.not
|
||||
| IO.println False.not
|
||||
| IO.println Boolean.False.not
|
||||
| IO.println (1==2 . not)
|
||||
|""".stripMargin
|
||||
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
|
||||
) { diff =>
|
||||
if (diff.modified.nonEmpty) {
|
||||
println(s"Generating index for ${libName} ")
|
||||
log.info(s"Generating index for $libName")
|
||||
val command = Seq(
|
||||
Platform.executableFileName(ensoExecutable.toString),
|
||||
"--no-compile-dependencies",
|
||||
|
Loading…
Reference in New Issue
Block a user