Use .. to identify autoscoped constructors (#9285)

This commit is contained in:
Jaroslav Tulach 2024-03-06 10:28:15 +01:00 committed by GitHub
parent 1cc7ca1338
commit 6acec1b30b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 46 additions and 42 deletions

View File

@ -299,7 +299,7 @@ below.
- **Autoscoped Constructors:** Referencing constructors via their type name may
lead to long and boilerplate code. To simplify referencing constructors when
the _context is known_ a special `~` syntax is supported. Should there be a
the _context is known_ a special `..` syntax is supported. Should there be a
method `describe`:
```ruby
@ -310,13 +310,13 @@ below.
may use _autoscoped constructors_ and call
```ruby
describe (~Just 5)
describe (..Just 5)
```
the argument `(~Just 5)` is _recorded but not executed_ until it is send to
the argument `(..Just 5)` is _recorded but not executed_ until it is send to
the `describe` method. The argument of the `describe` method is known to be of
type `Maybe` and have `Just` constructor. The _scope_ is now known and the so
far deferred `~` value gets evaluated. `Maybe.Just 5` atom is constructed and
far deferred `..` value gets evaluated. `Maybe.Just 5` atom is constructed and
execution of `describe` method continues with such atom.
- **Body Without Atom Definitions:** If you provide a body and do not define any

View File

@ -72,11 +72,11 @@ public class AtomBenchmarks {
autoscoped_generator x i:Integer =
acc = x:List
if i == 0 then acc else
c = ~Cons i acc
c = ..Cons i acc
i1 = i - 1
@Tail_Call autoscoped_generator c i1
res = autoscoped_generator ~Nil length
res = autoscoped_generator ..Nil length
res
""";
private static final String REVERSE_LIST_CODE =

View File

@ -46,7 +46,7 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:N = v.to_text
create n = N.materialize (~False)
create n = N.materialize (..False)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
@ -69,7 +69,7 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:M = v.value
create n = M.materialize (~Construct n)
create n = M.materialize (..Construct n)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
@ -92,7 +92,7 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:M = [v.v1, v.v2]
create a b = M.materialize (~Construct a b)
create a b = M.materialize (..Construct a b)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
@ -115,7 +115,7 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:M = [v.v1, v.v2]
create a b =
v0 = ~Construct
v0 = ..Construct
v1 = v0 a
v2 = v1 b
M.materialize v2
@ -141,7 +141,7 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:M = [v.v1, v.v2]
create a b =
v0 = ~Construct v2=a v1=b
v0 = ..Construct v2=a v1=b
M.materialize v0
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
@ -164,15 +164,15 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:M = [v.v1, v.v2, v.v3, v.v4]
c0 _ = M.materialize (~Construct)
c1 a = M.materialize (~Construct a)
c12 a b = M.materialize (~Construct a b)
c123 a b c = M.materialize (~Construct a b c)
c1234 a b c d = M.materialize (~Construct a b c d)
c14 a d = M.materialize (~Construct a v4=d)
c13 a c = M.materialize (~Construct a v3=c)
c41 a d = M.materialize ((~Construct v4=d) a)
c31 a c = M.materialize ((~Construct v3=c) a)
c0 _ = M.materialize (..Construct)
c1 a = M.materialize (..Construct a)
c12 a b = M.materialize (..Construct a b)
c123 a b c = M.materialize (..Construct a b c)
c1234 a b c d = M.materialize (..Construct a b c d)
c14 a d = M.materialize (..Construct a v4=d)
c13 a c = M.materialize (..Construct a v3=c)
c41 a d = M.materialize ((..Construct v4=d) a)
c31 a c = M.materialize ((..Construct v3=c) a)
""");
var c0 = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "c0");
@ -211,7 +211,7 @@ public class AutoscopedConstructorTest extends TestBase {
materialize v:N = v.to_text
create n = N.materialize (~True)
create n = N.materialize (..True)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());

View File

@ -609,7 +609,7 @@ final class TreeToIr {
);
}
private Expression translateCall(Tree ast, boolean isMethod) {
private Expression translateCall(Tree ast, boolean isMethod) throws SyntaxException {
var args = new java.util.ArrayList<CallArgument>();
var hasDefaultsSuspended = false;
var tree = ast;
@ -670,6 +670,16 @@ final class TreeToIr {
var loc = getIdentifiedLocation(oprApp.getLhs());
args.add(new CallArgument.Specified(Option.empty(), self, loc, meta(), diag()));
}
} else if (tree instanceof Tree.OprApp oprApp
&& isDotDotOperator(oprApp.getOpr().getRight())
&& oprApp.getRhs() instanceof Tree.Ident ident) {
var methodName = buildName(ident);
func = new Name.MethodReference(
Option.empty(),
methodName,
methodName.location(),
meta(), diag()
);
} else if (args.isEmpty()) {
return null;
} else {
@ -1030,16 +1040,6 @@ final class TreeToIr {
}
case null -> translateSyntaxError(tree, new Syntax.UnsupportedSyntax("Strange unary -"));
};
case Tree.UnaryOprApp un when "~".equals(un.getOpr().codeRepr()) -> {
var methodName = buildName(un.getRhs());
var methodRef = new Name.MethodReference(
Option.empty(),
methodName,
methodName.location(),
meta(), diag()
);
yield methodRef;
}
case Tree.TypeSignature sig -> {
var methodName = buildName(sig.getVariable());
var methodReference = new CallArgument.Specified(
@ -1880,6 +1880,10 @@ final class TreeToIr {
return op != null && ".".equals(op.codeRepr());
}
private static boolean isDotDotOperator(Token.Operator op) {
return op != null && "..".equals(op.codeRepr());
}
private static Tree maybeManyParensed(Tree t) {
for (;;) {
switch (t) {

View File

@ -55,7 +55,7 @@ public final class UnresolvedConstructor implements EnsoObject {
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
return "~" + name;
return ".." + name;
}
@ExportMessage

View File

@ -437,20 +437,20 @@ add_specs suite_builder =
group_builder.specify "Foo.Value as autoscoped" <|
v = ~Value 10
v = ..Value 10
foo = v:Foo
Foo.Value 10 . should_equal foo
group_builder.specify "Autoscope to two different values" <|
v = ~Value 10
v = ..Value 10
foo = v:Foo
bar = v:Bar
Foo.Value 10 . should_equal foo
Bar.Value 10 . should_equal bar
group_builder.specify "Cannot find constructor" <|
v = ~Value 10
v = ..Value 10
b = Panic.recover Any <|
x = v:Back
@ -458,10 +458,10 @@ add_specs suite_builder =
b . should_fail_with Type_Error
msg = b.to_display_text
msg . should_contain "Cannot find constructor ~Value among Back"
msg . should_contain "Cannot find constructor ..Value among Back"
group_builder.specify "Choose first constructor" <|
v = ~Value 10
v = ..Value 10
m_foo (m:Foo|Bar|Back) = m
m_bar (m:Bar|Foo|Back) = m
@ -474,7 +474,7 @@ add_specs suite_builder =
m_back_bar v . should_equal <| Bar.Value 10
group_builder.specify "Choose suitable constructor" <|
v = ~Times 10
v = ..Times 10
m_foo (m:Foo|Bar) = m
m_bar (m:Bar|Foo) = m
@ -485,8 +485,8 @@ add_specs suite_builder =
m_back v . should_equal <| Back.Times 10
group_builder.specify "Lazy constructor with State" <|
v0 = ~Value
v1 = ~Value 33
v0 = ..Value
v1 = ..Value 33
State.run Number 42 <|
s42 = State.get Number
@ -506,7 +506,7 @@ add_specs suite_builder =
foo_vec (v:Vector) = v.map e->
e:Foo . foo
vec = [~Value 3, ~Value 4, ~Value 5]
vec = [..Value 3, ..Value 4, ..Value 5]
foo_vec vec . should_equal [3, 4, 5]