Skip to content

Commit

Permalink
Type.Atom... yields Meta.AtomConstructor
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Jan 15, 2025
1 parent 30e5005 commit d426ab3
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ is_same_object_builtin value_1 value_2 = @Builtin_Method "Meta.is_same_object"
is_a_builtin value typ = @Builtin_Method "Meta.is_a"
type_of_builtin value = @Builtin_Method "Meta.type_of"
get_annotation_builtin target method parameter_name = @Builtin_Method "Meta.get_annotation"
is_atom_constructor_builtin value = @Builtin_Method "Meta.is_atom_constructor"
find_atom_constructor_builtin value = @Builtin_Method "Meta.find_atom_constructor"
is_atom_builtin value = @Builtin_Method "Meta.is_atom"
is_error_builtin value = @Builtin_Method "Meta.is_error"
is_type_builtin value = @Builtin_Method "Meta.is_type"
Expand Down
18 changes: 10 additions & 8 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,15 @@ atom_with_hole factory = @Tail_Call Meta_Helpers.atom_with_hole_builtin factory
Arguments:
- value: The runtime entity to get the meta representation of.
meta : Any -> Atom | Constructor | Primitive | Polyglot | Unresolved_Symbol | Error
meta value = if Meta_Helpers.is_atom_builtin value then Atom.Value value else
if Meta_Helpers.is_atom_constructor_builtin value then Constructor.Value value else
if Meta_Helpers.is_polyglot_builtin value then Polyglot.Value value else
if Meta_Helpers.is_unresolved_symbol_builtin value then Unresolved_Symbol.Value value else
if Meta_Helpers.is_error_builtin value then Error.Value value.catch else
if Meta_Helpers.is_type_builtin value then Type.Value value.catch else
Primitive.Value value
meta ~value =
ac = Meta_Helpers.find_atom_constructor_builtin value...
if ac.is_nothing.not then Constructor.Value ac else
if Meta_Helpers.is_atom_builtin value... then Atom.Value value else
if Meta_Helpers.is_polyglot_builtin value then Polyglot.Value value else
if Meta_Helpers.is_unresolved_symbol_builtin value then Unresolved_Symbol.Value value else
if Meta_Helpers.is_error_builtin value then Error.Value value.catch else
if Meta_Helpers.is_type_builtin value then Type.Value value.catch else
Primitive.Value value

## PRIVATE
ADVANCED
Expand Down Expand Up @@ -379,7 +381,7 @@ type Language
Arguments:
- value: The value to check.
is_atom_constructor : Any -> Boolean
is_atom_constructor value = @Tail_Call Meta_Helpers.is_atom_constructor_builtin value
is_atom_constructor ~value = Meta_Helpers.find_atom_constructor_builtin value . is_nothing . not

## PRIVATE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public static ThunkExecutorNode build() {
return ThunkExecutorNodeGen.create();
}

@NeverDefault
public static ThunkExecutorNode getUncached() {
return ThunkExecutorNodeGen.getUncached();
}

/**
* Forces the thunk to its resulting value.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.enso.interpreter.node.expression.builtin.meta;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.dsl.Suspend;
import org.enso.interpreter.node.BaseNode;
import org.enso.interpreter.node.MethodRootNode;
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.state.State;

@BuiltinMethod(
type = "Meta",
name = "find_atom_constructor",
description = "Checks if the argument is a constructor.",
autoRegister = false)
final class FindAtomConstructorNode extends Node {
EnsoObject execute(VirtualFrame frame, @Suspend @AcceptsError Object value, State state) {
var ac = findConstructor(value, frame, state);
if (ac != null) {
return ac;
} else {
var ctx = EnsoContext.get(this);
return ctx.getNothing();
}
}

static AtomConstructor findConstructor(Object value, VirtualFrame frame, State state) {
for (; ; ) {
if (value instanceof AtomConstructor atom) {
return atom;
}
if (value instanceof Function fn) {
if (AtomConstructor.accessorFor(fn) instanceof AtomConstructor atom) {
return atom;
}
if (MethodRootNode.constructorFor(fn) instanceof AtomConstructor atom) {
return atom;
}
if (fn.isThunk()) {
var thunkSolver = ThunkExecutorNode.getUncached();
value = thunkSolver.executeThunk(frame, value, state, BaseNode.TailStatus.NOT_TAIL);
continue;
}
}
return null;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ public abstract class Atom extends EnsoObject {
* Creates a new Atom for a given constructor.
*
* @param constructor the Atom's constructor
* @param skipCheck don't assert whether the arity is non-zero
*/
Atom(AtomConstructor constructor) {
Atom(AtomConstructor constructor, boolean skipCheck) {
assert skipCheck || constructor.getArity() != 0;
this.constructor = constructor;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ static NodeFactory<UnboxingAtom.FieldSetterNode>[] getFieldSetterNodeFactories(i
private final Object[] fields;

private BoxingAtom(AtomConstructor constructor, Object[] fields) {
super(constructor);
super(constructor, false);
this.fields = fields;
}

private BoxingAtom(AtomConstructor constructor) {
super(constructor);
super(constructor, true);
this.fields = NO_FIELDS;
}

Expand Down Expand Up @@ -101,7 +101,11 @@ private static class InstantiatorNode extends UnboxingAtom.InstantiatorNode {
@Override
public Atom execute(AtomConstructor constructor, Layout layout, Object[] args) {
assert constructor.getBoxedLayout() == layout;
return new BoxingAtom(constructor, args);
if (args.length == 0) {
return constructor.newInstance(new Object[0]);
} else {
return new BoxingAtom(constructor, args);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Object execute(VirtualFrame frame) {
} else if (atomConstructor == falseCtor) {
return false;
} else {
return atomConstructor.newInstance();
return atomConstructor.getConstructorFunction();
}
} else {
return atomConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ abstract class UnboxingAtom extends Atom {
protected final Layout layout;

protected UnboxingAtom(AtomConstructor constructor, Layout layout) {
super(constructor);
super(constructor, false);
this.layout = layout;
}

Expand Down
4 changes: 3 additions & 1 deletion test/Base_Tests/src/Data/Time/Date_Range_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ add_specs suite_builder =
r.is_empty . should_equal r.to_vector.is_empty
r.not_empty . should_equal r.to_vector.not_empty

r.map .day_of_week . should_equal (r.to_vector.map .day_of_week)
x = r.map .day_of_week
y = r.to_vector.map .day_of_week
x . should_equal y
p = d-> d.day_of_week == Day_Of_Week.Monday
r.filter p . should_equal (r.to_vector.filter p)
r.partition p . should_equal (r.to_vector.partition p)
Expand Down
17 changes: 17 additions & 0 deletions test/Base_Tests/src/Semantic/Meta_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ test_method a b = a + b

type Test_Type
Value x
No_Value

type Sum_Type
Variant_A x
Expand Down Expand Up @@ -350,6 +351,22 @@ add_specs suite_builder =
Meta.get_annotation My_Type .Value "bar" . should_equal Nothing
Meta.get_annotation My_Type .Value "baz" . should_equal (My_Type.Value 1 2 3)

group_builder.specify "atom constructor with suspended evalution" <|
m = Meta.meta (Test_Type.No_Value...)
case m of
ac : Meta.Constructor ->
ac.name . should_equal "No_Value"
_ ->
Test.fail "Expecting Meta.Constructor, but was: "+m.to_text

group_builder.specify "atom without suspended evalution" <|
m = Meta.meta Test_Type.No_Value
case m of
a : Meta.Atom ->
a.constructor.name . should_equal "No_Value"
_ ->
Test.fail "Expecting Meta.Constructor, but was: "+m.to_text

suite_builder.group "Check Nothing and NaN" group_builder->
group_builder.specify "Nothing.is_a Nothing" <|
Nothing.is_a Nothing . should_be_true
Expand Down

0 comments on commit d426ab3

Please sign in to comment.