mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 12:31:44 +03:00
Vector Type (#1133)
This commit is contained in:
parent
a2accd3444
commit
6301542546
@ -1,3 +1,5 @@
|
||||
from Base import all
|
||||
|
||||
reverse_list = list ->
|
||||
go = list -> acc -> case list of
|
||||
Cons h t -> go t (Cons h acc)
|
||||
@ -24,6 +26,11 @@ Number.times = act ->
|
||||
res = here.reverse_list (go Nil this)
|
||||
res
|
||||
|
||||
zeropad number =
|
||||
txt = number.to_text
|
||||
if number % 10 == number then "00" + txt else
|
||||
if number % 100 == number then "0" + txt else txt
|
||||
|
||||
measure = ~act -> label -> iter_size -> num_iters ->
|
||||
single_call = _ ->
|
||||
x1 = System.nano_time
|
||||
@ -34,5 +41,6 @@ measure = ~act -> label -> iter_size -> num_iters ->
|
||||
act_it_num = num_iters - it_num
|
||||
res = iter_size.times single_call
|
||||
avg = here.avg_list res
|
||||
IO.println (label + "/iteration:" + act_it_num.to_text + ": " + (avg/1000000).to_text + "ms")
|
||||
fmt = (avg / 1000000).to_text + "." + here.zeropad ((avg / 1000) % 1000)
|
||||
IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms")
|
||||
num_iters.times iteration
|
||||
|
@ -72,9 +72,12 @@ type List
|
||||
list:
|
||||
(Cons 0 <| Cons 1 <| Cons 2 <| Nil) . fold 0 (+)
|
||||
fold : Any -> (Any -> Any -> Any) -> Any
|
||||
fold init f = case this of
|
||||
Nil -> init
|
||||
Cons h t -> t.fold (f init h) f
|
||||
fold init f =
|
||||
go acc list = case list of
|
||||
Nil -> acc
|
||||
Cons h t -> go (f acc h) t
|
||||
res = go init this
|
||||
res
|
||||
|
||||
## Reverses the list, returning a list with the same elements, but in the
|
||||
opposite order.
|
||||
|
@ -1,6 +1,46 @@
|
||||
import Base.List
|
||||
import Builtins
|
||||
import Base.Vector
|
||||
from Builtins import Number, Unit
|
||||
|
||||
from Builtins export all
|
||||
|
||||
from Base.List export Nil, Cons
|
||||
from Base.Vector export Vector
|
||||
|
||||
## Represents a right-exclusive range of integer values.
|
||||
type Range
|
||||
type Range start end
|
||||
|
||||
## Applies a function to each element in the range.
|
||||
|
||||
> Example
|
||||
To print all the numbers from 1 to 100 use:
|
||||
1.upto 101 . each IO.println
|
||||
each function =
|
||||
it start end = if start == end then Unit else
|
||||
function start
|
||||
it start+1 end
|
||||
it this.start this.end
|
||||
Unit
|
||||
|
||||
## Combines all the elements of the range, by iteratively applying the
|
||||
passed function with next elements of the range.
|
||||
|
||||
In general, the result of
|
||||
Range start end . fold init f
|
||||
is the same as
|
||||
f (...(f (f init start) start+1)...) end-1
|
||||
|
||||
> Example
|
||||
In the following example, we'll compute the sum of all elements of a
|
||||
range:
|
||||
Range 0 100 . fold 0 (+)
|
||||
fold initial function =
|
||||
it acc start end = if start == end then acc else
|
||||
new_acc = function acc start
|
||||
it new_acc start+1 end
|
||||
res = it initial this.start this.end
|
||||
res
|
||||
|
||||
## Creates a new right-exclusive range of integers from `this` to `n`.
|
||||
Number.upto n = Range this n
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Base.Process.Exit_Code
|
||||
from Builtins import System, True, False
|
||||
from Base.Vector import Vector
|
||||
from Builtins import Array, System, True, False
|
||||
|
||||
## The builder object that is used to create operating system processes.
|
||||
type Process_Builder command arguments stdin
|
||||
@ -16,7 +17,7 @@ type Process_Result exit_code stdout stderr
|
||||
8
|
||||
Process.execute : String -> Exit_Code
|
||||
Process.execute command =
|
||||
result = System.create_process command (arguments = []) (input = "") (redirectIn = True) (redirectOut = True) (redirectErr = True)
|
||||
result = System.create_process command (arguments = Array.empty) (input = "") (redirectIn = True) (redirectOut = True) (redirectErr = True)
|
||||
Exit_Code.from_number result.exit_code
|
||||
|
||||
## Call a command with a list of arguments.
|
||||
@ -28,7 +29,7 @@ Process.execute command =
|
||||
Hello!
|
||||
Process.run_command : String -> Vector -> Exit_Code
|
||||
Process.run_command command arguments =
|
||||
result = System.create_process command arguments (input = "") (redirectIn = True) (redirectOut = True) (redirectErr = True)
|
||||
result = System.create_process command arguments.to_array (input = "") (redirectIn = True) (redirectOut = True) (redirectErr = True)
|
||||
Exit_Code.from_number result.exit_code
|
||||
|
||||
## Create a process using a builder returning the result of execution.
|
||||
@ -41,5 +42,5 @@ Process.run_command command arguments =
|
||||
Process_Result Exit_Success "test" ""
|
||||
Process.create : Process_Builder -> Process_Result
|
||||
Process.create b =
|
||||
result = System.create_process b.command b.arguments b.stdin (redirectIn = False) (redirectOut = False) (redirectErr = False)
|
||||
result = System.create_process b.command b.arguments.to_array b.stdin (redirectIn = False) (redirectOut = False) (redirectErr = False)
|
||||
Process_Result (Exit_Code.from_number result.exit_code) result.stdout result.stderr
|
||||
|
106
distribution/std-lib/Base/src/Vector.enso
Normal file
106
distribution/std-lib/Base/src/Vector.enso
Normal file
@ -0,0 +1,106 @@
|
||||
from Builtins import Array
|
||||
from Base import all
|
||||
|
||||
## The basic, immutable, vector type.
|
||||
|
||||
A vector allows to store an arbitrary number of elements, in linear memory.
|
||||
It is the recommended data structure for most applications.
|
||||
|
||||
> Example
|
||||
A vector containing the elements `1`, `2`, and `3`, in this order is:
|
||||
[1, 2, 3]
|
||||
|
||||
> Example
|
||||
A vector containing 50 elements, each being the number `42`, can be
|
||||
created by:
|
||||
Vector.fill length=50 item=42
|
||||
type Vector
|
||||
type Vector to_array
|
||||
|
||||
## Gets an element from the vector at a specified index (0-based).
|
||||
|
||||
> Example
|
||||
To get the second element of the vector `[1, 2, 3]`, use:
|
||||
[1, 2, 3].at 1
|
||||
at : Number -> Any
|
||||
at index = this.to_array.at index
|
||||
|
||||
## Returns the number of elements stored in this vector.
|
||||
length : Number
|
||||
length = this.to_array.length
|
||||
|
||||
## Combines all the elements of the vector, by iteratively applying the
|
||||
passed function with next elements of the vector.
|
||||
|
||||
In general, the result of
|
||||
[l0, l1, ..., ln] . fold init f
|
||||
is the same as
|
||||
f (...(f (f init l0) l1)...) ln
|
||||
|
||||
> Example
|
||||
In the following example, we'll compute the sum of all elements of a
|
||||
vector:
|
||||
[0, 1, 2] . fold 0 (+)
|
||||
fold : Any -> (Any -> Any -> Any) -> Any
|
||||
fold initial function =
|
||||
arr = this.to_array
|
||||
f = acc -> ix -> function acc (arr.at ix)
|
||||
res = 0.upto this.length . fold initial f
|
||||
res
|
||||
|
||||
## Creates a new vector of the given length, initializing elements using
|
||||
the provided constructor function.
|
||||
|
||||
The constructor function is called with the consecutive indices
|
||||
(0-based) of the vector elements.
|
||||
|
||||
> Example
|
||||
To create a vector containing the numbers 1 through 50:
|
||||
Vector.new 50 (ix -> ix + 1)
|
||||
|
||||
> Example
|
||||
To create a copy of the given vector (`my_vec`):
|
||||
Vector.new my_vec.length (ix -> my_vec.at ix)
|
||||
new : Number -> (Number -> Any) -> Vector
|
||||
new length constructor =
|
||||
arr = Array.new length
|
||||
0.upto length . each ix-> arr.set_at ix (constructor ix)
|
||||
Vector arr
|
||||
|
||||
## Creates a new vector of the given length, filling the elements with
|
||||
the provided constant.
|
||||
|
||||
> Example
|
||||
A vector containing 50 elements, each being the number `42`, can be
|
||||
created by:
|
||||
Vector.fill length=50 item=42
|
||||
fill : Number -> Any -> Vector
|
||||
fill length item =
|
||||
arr = Array.new length
|
||||
0.upto length . each ix-> arr.set_at ix item
|
||||
Vector arr
|
||||
|
||||
## Applies a function to each element of the vector, returning the vector of
|
||||
results.
|
||||
|
||||
> Example
|
||||
In the following example, we add `1` to each element of the vector:
|
||||
[1, 2, 3] . map +1
|
||||
The result of running the code above is:
|
||||
[2, 3, 4]
|
||||
map : (Any -> Any) -> Vector
|
||||
map function =
|
||||
arr = this.to_array
|
||||
new_arr = Array.new arr.length
|
||||
0.upto arr.length . each ix-> new_arr.set_at ix (function (arr.at ix))
|
||||
Vector new_arr
|
||||
|
||||
## Generates a human-readable text representation of the vector.
|
||||
to_text : Text
|
||||
to_text =
|
||||
arr = this.to_array
|
||||
if arr.length == 0 then "[]" else
|
||||
if arr.length == 1 then "[" + (arr.at 0 . to_text) + "]" else
|
||||
folder = str -> ix -> str + ", " + (arr.at ix).to_text
|
||||
tail_elems = 1.upto arr.length . fold "" folder
|
||||
"[" + (arr.at 0 . to_text) + tail_elems + "]"
|
@ -16,6 +16,7 @@ import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
|
||||
import org.enso.interpreter.runtime.callable.atom.Atom;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.MethodDoesNotExistException;
|
||||
import org.enso.interpreter.runtime.error.RuntimeError;
|
||||
|
||||
@ -157,6 +158,16 @@ public abstract class MethodResolverNode extends Node {
|
||||
return function;
|
||||
}
|
||||
|
||||
@Specialization(guards = "cachedSymbol == symbol")
|
||||
Function resolveArray(
|
||||
UnresolvedSymbol symbol,
|
||||
Array self,
|
||||
@Cached(value = "symbol", allowUncached = true) UnresolvedSymbol cachedSymbol,
|
||||
@Cached(value = "resolveMethodOnArray(cachedSymbol)", allowUncached = true)
|
||||
Function function) {
|
||||
return function;
|
||||
}
|
||||
|
||||
@Specialization(guards = {"cachedSymbol == symbol", "ctx.getEnvironment().isHostObject(target)"})
|
||||
Function resolveHost(
|
||||
UnresolvedSymbol symbol,
|
||||
@ -220,11 +231,18 @@ public abstract class MethodResolverNode extends Node {
|
||||
return ensureMethodExists(symbol.resolveFor(getBuiltins().any()), "Error", symbol);
|
||||
}
|
||||
|
||||
Function resolveMethodOnArray(UnresolvedSymbol symbol) {
|
||||
return ensureMethodExists(
|
||||
symbol.resolveFor(getBuiltins().array().constructor(), getBuiltins().any()),
|
||||
"Array",
|
||||
symbol);
|
||||
}
|
||||
|
||||
Function buildHostResolver(UnresolvedSymbol symbol, Context context) {
|
||||
if (symbol.getName().equals("new")) {
|
||||
return context.getBuiltins().getConstructorDispatch();
|
||||
} else {
|
||||
return context.getBuiltins().buildPolyglotMethodDispatch(symbol.getName());
|
||||
return context.getBuiltins().buildPolyglotMethodDispatch(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import com.oracle.truffle.api.nodes.ExplodeLoop;
|
||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||
import org.enso.interpreter.node.ExpressionNode;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@NodeInfo(shortName = "[]", description = "Creates a vector from given expressions.")
|
||||
public class SequenceLiteralNode extends ExpressionNode {
|
||||
@ -28,7 +28,7 @@ public class SequenceLiteralNode extends ExpressionNode {
|
||||
* Executes the node.
|
||||
*
|
||||
* @param frame the stack frame for execution.
|
||||
* @return a {@link Vector} containing the results of evaluating child expressions.
|
||||
* @return a {@link Array} containing the results of evaluating child expressions.
|
||||
*/
|
||||
@Override
|
||||
@ExplodeLoop
|
||||
@ -37,6 +37,6 @@ public class SequenceLiteralNode extends ExpressionNode {
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
itemValues[i] = items[i].executeGeneric(frame);
|
||||
}
|
||||
return new Vector(itemValues);
|
||||
return new Array(itemValues);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(type = "Array", name = "empty", description = "Creates an empty array.")
|
||||
public class EmptyNode extends Node {
|
||||
|
||||
Object execute(Object _this) {
|
||||
return new Array();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "at",
|
||||
description = "Gets an array element at the given index.")
|
||||
public class GetAtNode extends Node {
|
||||
|
||||
Object execute(Array _this, long index) {
|
||||
return _this.getItems()[(int) index];
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(type = "Array", name = "length", description = "Returns the length of an array.")
|
||||
public class LengthNode extends Node {
|
||||
|
||||
long execute(Array _this) {
|
||||
return _this.getItems().length;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "new_1",
|
||||
description = "Creates an array with one given element.")
|
||||
public class New1Node extends Node {
|
||||
Object execute(Object _this, Object item_1) {
|
||||
return new Array(item_1);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "new_2",
|
||||
description = "Creates an array with two given elements.")
|
||||
public class New2Node extends Node {
|
||||
|
||||
Object execute(Object _this, Object item_1, Object item_2) {
|
||||
return new Array(item_1, item_2);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "new_3",
|
||||
description = "Creates an array with three given elements.")
|
||||
public class New3Node extends Node {
|
||||
|
||||
Object execute(Object _this, Object item_1, Object item_2, Object item_3) {
|
||||
return new Array(item_1, item_2, item_3);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "new_4",
|
||||
description = "Creates an array with four given elements.")
|
||||
public class New4Node extends Node {
|
||||
|
||||
Object execute(Object _this, Object item_1, Object item_2, Object item_3, Object item_4) {
|
||||
return new Array(item_1, item_2, item_3, item_4);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "new",
|
||||
description = "Creates an uninitialized array of a given size.")
|
||||
public class NewNode extends Node {
|
||||
|
||||
Object execute(Object _this, long size) {
|
||||
return new Array(size);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "set_at",
|
||||
description = "Puts the given element in the given position in the array.")
|
||||
public class SetAtNode extends Node {
|
||||
|
||||
Object execute(Array _this, long index, Object value) {
|
||||
_this.getItems()[(int) index] = value;
|
||||
return _this;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.enso.interpreter.node.expression.builtin.array;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "to_array",
|
||||
description = "Identity on arrays, implemented for protocol completeness.")
|
||||
public class ToArrayNode extends Node {
|
||||
|
||||
Object execute(Object _this) {
|
||||
return _this;
|
||||
}
|
||||
}
|
@ -1,25 +1,15 @@
|
||||
package org.enso.interpreter.node.expression.builtin.interop.generic;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import com.oracle.truffle.api.interop.ArityException;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||
import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.Language;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.BuiltinRootNode;
|
||||
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.callable.function.FunctionSchema.CallStrategy;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.state.Stateful;
|
||||
import org.enso.interpreter.runtime.type.TypesGen;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
@ -30,7 +20,7 @@ public class ExecuteNode extends Node {
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
private final BranchProfile err = BranchProfile.create();
|
||||
|
||||
Object execute(Object _this, Object callable, Vector arguments) {
|
||||
Object execute(Object _this, Object callable, Array arguments) {
|
||||
try {
|
||||
return library.execute(callable, arguments.getItems());
|
||||
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
||||
|
@ -8,7 +8,7 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@BuiltinMethod(
|
||||
@ -21,7 +21,7 @@ public class InstantiateNode extends Node {
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
private final BranchProfile err = BranchProfile.create();
|
||||
|
||||
Object execute(Object _this, Object constructor, Vector arguments) {
|
||||
Object execute(Object _this, Object constructor, Array arguments) {
|
||||
try {
|
||||
return library.instantiate(constructor, arguments.getItems());
|
||||
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
||||
|
@ -5,7 +5,7 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@BuiltinMethod(
|
||||
@ -17,7 +17,7 @@ public class InvokeNode extends Node {
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
private final BranchProfile err = BranchProfile.create();
|
||||
|
||||
Object execute(Object _this, Object target, String name, Vector arguments) {
|
||||
Object execute(Object _this, Object target, String name, Array arguments) {
|
||||
try {
|
||||
return library.invokeMember(target, name, arguments.getItems());
|
||||
} catch (UnsupportedMessageException
|
||||
|
@ -54,7 +54,7 @@ public class ConstructorDispatchNode extends BuiltinRootNode {
|
||||
Object cons = args[0];
|
||||
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
||||
try {
|
||||
Object[] arguments = TypesGen.expectVector(args[1]).getItems();
|
||||
Object[] arguments = TypesGen.expectArray(args[1]).getItems();
|
||||
Object res = library.instantiate(cons, arguments);
|
||||
return new Stateful(state, res);
|
||||
} catch (UnsupportedMessageException
|
||||
|
@ -1,5 +1,9 @@
|
||||
package org.enso.interpreter.node.expression.builtin.interop.syntax;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.Bind;
|
||||
import com.oracle.truffle.api.dsl.ReportPolymorphism;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import com.oracle.truffle.api.interop.*;
|
||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||
@ -7,15 +11,19 @@ import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.Language;
|
||||
import org.enso.interpreter.node.callable.InvokeCallableNode;
|
||||
import org.enso.interpreter.node.expression.builtin.BuiltinRootNode;
|
||||
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
|
||||
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.state.Stateful;
|
||||
import org.enso.interpreter.runtime.type.TypesGen;
|
||||
|
||||
@NodeInfo(shortName = "<polyglot_dispatch>", description = "Invokes a polyglot method by name.")
|
||||
public class MethodDispatchNode extends BuiltinRootNode {
|
||||
private MethodDispatchNode(Language language) {
|
||||
@ReportPolymorphism
|
||||
public abstract class MethodDispatchNode extends BuiltinRootNode {
|
||||
MethodDispatchNode(Language language) {
|
||||
super(language);
|
||||
}
|
||||
|
||||
@ -23,6 +31,12 @@ public class MethodDispatchNode extends BuiltinRootNode {
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
private final BranchProfile err = BranchProfile.create();
|
||||
|
||||
private @Child InvokeCallableNode invokeCallableNode =
|
||||
InvokeCallableNode.build(
|
||||
new CallArgumentInfo[] {new CallArgumentInfo()},
|
||||
InvokeCallableNode.DefaultsExecutionMode.EXECUTE,
|
||||
InvokeCallableNode.ArgumentsExecutionMode.PRE_EXECUTED);
|
||||
|
||||
/**
|
||||
* Creates an instance of this node.
|
||||
*
|
||||
@ -30,7 +44,7 @@ public class MethodDispatchNode extends BuiltinRootNode {
|
||||
* @return a function wrapping this node
|
||||
*/
|
||||
public static MethodDispatchNode build(Language language) {
|
||||
return new MethodDispatchNode(language);
|
||||
return MethodDispatchNodeGen.create(language);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -39,16 +53,21 @@ public class MethodDispatchNode extends BuiltinRootNode {
|
||||
* @param frame current execution frame.
|
||||
* @return the result of converting input into a string.
|
||||
*/
|
||||
@Override
|
||||
public Stateful execute(VirtualFrame frame) {
|
||||
@Specialization(guards = "symbol == cachedSymbol")
|
||||
public Stateful run(
|
||||
VirtualFrame frame,
|
||||
@Bind("getSymbol(frame)") UnresolvedSymbol symbol,
|
||||
@Cached("symbol") UnresolvedSymbol cachedSymbol,
|
||||
@Cached("buildToArray(cachedSymbol)") UnresolvedSymbol toArray) {
|
||||
Object[] args = Function.ArgumentsHelper.getPositionalArguments(frame.getArguments());
|
||||
Object callable = args[0];
|
||||
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
||||
Object arguments = args[2];
|
||||
Stateful casted = invokeCallableNode.execute(toArray, frame, state, new Object[] {arguments});
|
||||
try {
|
||||
String method = TypesGen.expectString(args[1]);
|
||||
Object[] arguments = TypesGen.expectVector(args[2]).getItems();
|
||||
Object res = library.invokeMember(callable, method, arguments);
|
||||
return new Stateful(state, res);
|
||||
Object[] castedArgs = TypesGen.expectArray(casted.getValue()).getItems();
|
||||
Object res = library.invokeMember(callable, symbol.getName(), castedArgs);
|
||||
return new Stateful(casted.getState(), res);
|
||||
} catch (UnsupportedMessageException
|
||||
| ArityException
|
||||
| UnsupportedTypeException
|
||||
@ -59,6 +78,15 @@ public class MethodDispatchNode extends BuiltinRootNode {
|
||||
}
|
||||
}
|
||||
|
||||
UnresolvedSymbol buildToArray(UnresolvedSymbol originalSymbol) {
|
||||
return UnresolvedSymbol.build("to_array", originalSymbol.getScope());
|
||||
}
|
||||
|
||||
UnresolvedSymbol getSymbol(VirtualFrame frame) {
|
||||
return TypesGen.asUnresolvedSymbol(
|
||||
Function.ArgumentsHelper.getPositionalArguments(frame.getArguments())[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a language-specific name for this node.
|
||||
*
|
||||
|
@ -8,7 +8,7 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.Language;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
import java.io.*;
|
||||
@ -26,7 +26,7 @@ public abstract class CreateProcessNode extends Node {
|
||||
abstract Object execute(
|
||||
Object _this,
|
||||
String command,
|
||||
Vector arguments,
|
||||
Array arguments,
|
||||
String input,
|
||||
boolean redirectIn,
|
||||
boolean redirectOut,
|
||||
@ -37,15 +37,15 @@ public abstract class CreateProcessNode extends Node {
|
||||
Object doCreate(
|
||||
Object _this,
|
||||
String command,
|
||||
Vector arguments,
|
||||
Array arguments,
|
||||
String input,
|
||||
boolean redirectIn,
|
||||
boolean redirectOut,
|
||||
boolean redirectErr,
|
||||
@CachedContext(Language.class) Context ctx) {
|
||||
String[] cmd = new String[(int) arguments.getArraySize() + 1];
|
||||
String[] cmd = new String[(int) arguments.getItems().length + 1];
|
||||
cmd[0] = command;
|
||||
System.arraycopy(arguments.getItems(), 0, cmd, 1, (int) arguments.getArraySize());
|
||||
System.arraycopy(arguments.getItems(), 0, cmd, 1, (int) arguments.getItems().length);
|
||||
TruffleProcessBuilder pb = ctx.getEnvironment().newProcessBuilder(cmd);
|
||||
|
||||
try {
|
||||
|
@ -24,7 +24,7 @@ import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.callable.CallerInfo;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.scope.LocalScope;
|
||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
import org.enso.interpreter.runtime.type.Types;
|
||||
@ -454,7 +454,7 @@ public class Module implements TruffleObject {
|
||||
*/
|
||||
@ExportMessage
|
||||
Object getMembers(boolean includeInternal) {
|
||||
return new Vector(
|
||||
return new Array(
|
||||
MethodNames.Module.GET_METHOD,
|
||||
MethodNames.Module.GET_CONSTRUCTOR,
|
||||
MethodNames.Module.REPARSE,
|
||||
|
@ -0,0 +1,37 @@
|
||||
package org.enso.interpreter.runtime.builtin;
|
||||
|
||||
import org.enso.interpreter.Language;
|
||||
import org.enso.interpreter.node.expression.builtin.array.*;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
|
||||
/** Container for builtin array-related types and functions. */
|
||||
public class Array {
|
||||
private final AtomConstructor array;
|
||||
|
||||
/**
|
||||
* Creates a new instance of this class, registering all relevant bindings in the provided scope.
|
||||
*
|
||||
* @param language the current language instance.
|
||||
* @param scope the scope for builtin methods.
|
||||
*/
|
||||
public Array(Language language, ModuleScope scope) {
|
||||
array = new AtomConstructor("Array", scope).initializeFields();
|
||||
scope.registerConstructor(array);
|
||||
scope.registerMethod(array, "empty", EmptyMethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "new", NewMethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "new_1", New1MethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "new_2", New2MethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "new_3", New3MethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "new_4", New4MethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "length", LengthMethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "to_array", ToArrayMethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "at", GetAtMethodGen.makeFunction(language));
|
||||
scope.registerMethod(array, "set_at", SetAtMethodGen.makeFunction(language));
|
||||
}
|
||||
|
||||
/** @return the Array constructor. */
|
||||
public AtomConstructor constructor() {
|
||||
return array;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import org.enso.interpreter.node.expression.builtin.thread.WithInterruptHandlerM
|
||||
import org.enso.interpreter.node.expression.builtin.unsafe.SetAtomFieldMethodGen;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.Module;
|
||||
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
|
||||
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
|
||||
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
@ -52,6 +53,7 @@ public class Builtins {
|
||||
private final Error error;
|
||||
private final Bool bool;
|
||||
private final System system;
|
||||
private final Array array;
|
||||
|
||||
private final RootCallTarget interopDispatchRoot;
|
||||
private final FunctionSchema interopDispatchSchema;
|
||||
@ -72,6 +74,7 @@ public class Builtins {
|
||||
number = new AtomConstructor("Number", scope).initializeFields();
|
||||
bool = new Bool(language, scope);
|
||||
error = new Error(language, scope);
|
||||
array = new Array(language, scope);
|
||||
function = new AtomConstructor("Function", scope).initializeFields();
|
||||
text = new AtomConstructor("Text", scope).initializeFields();
|
||||
debug = new AtomConstructor("Debug", scope).initializeFields();
|
||||
@ -258,6 +261,10 @@ public class Builtins {
|
||||
return system;
|
||||
}
|
||||
|
||||
/** @return the container for array-related builtins. */
|
||||
public Array array() {
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the builtin module scope.
|
||||
@ -275,10 +282,10 @@ public class Builtins {
|
||||
/**
|
||||
* Builds a function dispatching to a polyglot method call.
|
||||
*
|
||||
* @param method the name of the method this function will dispatch to.
|
||||
* @param method the name and scope of the method this function will dispatch to.
|
||||
* @return a function calling {@code method} with given arguments.
|
||||
*/
|
||||
public Function buildPolyglotMethodDispatch(String method) {
|
||||
public Function buildPolyglotMethodDispatch(UnresolvedSymbol method) {
|
||||
Object[] preAppliedArr = new Object[] {null, method, null};
|
||||
return new Function(interopDispatchRoot, null, interopDispatchSchema, preAppliedArr, null);
|
||||
}
|
||||
|
@ -33,15 +33,17 @@ public class UnresolvedSymbol implements TruffleObject {
|
||||
/**
|
||||
* Gets the symbol name.
|
||||
*
|
||||
* <p>All names for dynamic symbols are interned, making it safe to compare symbol names using the
|
||||
* standard {@code ==} equality operator.
|
||||
*
|
||||
* @return the name of this symbol
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** @return the scope this symbol was used in. */
|
||||
public ModuleScope getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the symbol for a given hierarchy of constructors.
|
||||
*
|
||||
|
@ -26,7 +26,7 @@ import org.enso.interpreter.runtime.callable.CallerInfo;
|
||||
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
|
||||
import org.enso.interpreter.runtime.callable.argument.Thunk;
|
||||
import org.enso.interpreter.runtime.state.data.EmptyMap;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.type.Types;
|
||||
import org.enso.polyglot.MethodNames;
|
||||
|
||||
@ -272,7 +272,7 @@ public final class Function implements TruffleObject {
|
||||
*/
|
||||
@ExportMessage
|
||||
Object getMembers(boolean includeInternal) {
|
||||
return new Vector(MethodNames.Function.EQUALS);
|
||||
return new Array(MethodNames.Function.EQUALS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,27 +1,35 @@
|
||||
package org.enso.interpreter.runtime.data;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
|
||||
/** An immutable array-like collection. */
|
||||
/** A primitve boxed array type for use in the runtime. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class Vector implements TruffleObject {
|
||||
private final @CompilerDirectives.CompilationFinal(dimensions = 1) Object[] items;
|
||||
public class Array implements TruffleObject {
|
||||
private final Object[] items;
|
||||
|
||||
/**
|
||||
* Creates a new Vector
|
||||
* Creates a new array
|
||||
*
|
||||
* @param items the element values
|
||||
*/
|
||||
public Vector(Object... items) {
|
||||
public Array(Object... items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/** @return the elements of this vector as an array. */
|
||||
/**
|
||||
* Creates an uninitialized array of the given size.
|
||||
*
|
||||
* @param size the size of the created array.
|
||||
*/
|
||||
public Array(long size) {
|
||||
this.items = new Object[(int) size];
|
||||
}
|
||||
|
||||
/** @return the elements of this array as a java array. */
|
||||
public Object[] getItems() {
|
||||
return items;
|
||||
}
|
||||
@ -57,7 +65,7 @@ public class Vector implements TruffleObject {
|
||||
* @return
|
||||
*/
|
||||
@ExportMessage
|
||||
public long getArraySize() {
|
||||
long getArraySize() {
|
||||
return items.length;
|
||||
}
|
||||
|
||||
@ -68,7 +76,22 @@ public class Vector implements TruffleObject {
|
||||
* @return {@code true} if the index is valid, {@code false} otherwise.
|
||||
*/
|
||||
@ExportMessage
|
||||
public boolean isArrayElementReadable(long index) {
|
||||
boolean isArrayElementReadable(long index) {
|
||||
return index < getArraySize() && index >= 0;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
void writeArrayElement(long index, Object value) {
|
||||
items[(int) index] = value;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
boolean isArrayElementModifiable(long index) {
|
||||
return isArrayElementReadable(index);
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
boolean isArrayElementInsertable(long index) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ import org.enso.interpreter.Language;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.Module;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.type.Types;
|
||||
import org.enso.pkg.QualifiedName;
|
||||
import org.enso.pkg.QualifiedName$;
|
||||
@ -130,8 +130,8 @@ public class TopLevelScope implements TruffleObject {
|
||||
* @return a collection of all the exported members.
|
||||
*/
|
||||
@ExportMessage
|
||||
Vector getMembers(boolean includeInternal) {
|
||||
return new Vector(
|
||||
Array getMembers(boolean includeInternal) {
|
||||
return new Array(
|
||||
MethodNames.TopScope.GET_MODULE,
|
||||
MethodNames.TopScope.CREATE_MODULE,
|
||||
MethodNames.TopScope.REGISTER_MODULE,
|
||||
|
@ -5,15 +5,14 @@ import com.oracle.truffle.api.dsl.ImplicitCast;
|
||||
import com.oracle.truffle.api.dsl.TypeSystem;
|
||||
import com.oracle.truffle.api.interop.ArityException;
|
||||
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
|
||||
import org.enso.interpreter.runtime.callable.argument.Thunk;
|
||||
import org.enso.interpreter.runtime.callable.atom.Atom;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.RuntimeError;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* This class defines the interpreter-level type system for Enso.
|
||||
*
|
||||
@ -33,7 +32,8 @@ import java.util.Optional;
|
||||
AtomConstructor.class,
|
||||
Thunk.class,
|
||||
RuntimeError.class,
|
||||
Vector.class
|
||||
UnresolvedSymbol.class,
|
||||
Array.class
|
||||
})
|
||||
public class Types {
|
||||
|
||||
@ -118,8 +118,8 @@ public class Types {
|
||||
return "Thunk";
|
||||
} else if (TypesGen.isRuntimeError(value)) {
|
||||
return "Error " + TypesGen.asRuntimeError(value).getPayload().toString();
|
||||
} else if (TypesGen.isVector(value)) {
|
||||
return "Vector";
|
||||
} else if (TypesGen.isArray(value)) {
|
||||
return "Array";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ class Passes(passes: Option[List[PassGroup]] = None) {
|
||||
TypeSignatures,
|
||||
AliasAnalysis,
|
||||
UppercaseNames,
|
||||
VectorLiterals,
|
||||
AliasAnalysis,
|
||||
LambdaConsolidate,
|
||||
AliasAnalysis,
|
||||
|
@ -1136,7 +1136,7 @@ class IrToTruffle(
|
||||
argumentExpression.setTail(argExpressionIsTail)
|
||||
|
||||
val displayName =
|
||||
s"argument<${name.getOrElse(String.valueOf(position))}>"
|
||||
s"argument<${name.map(_.name).getOrElse(String.valueOf(position))}>"
|
||||
|
||||
val section = value.location
|
||||
.map(loc => source.createSection(loc.start, loc.end))
|
||||
|
@ -5302,6 +5302,12 @@ object IR {
|
||||
def explain(originalName: IR.Name): String
|
||||
}
|
||||
|
||||
case object UnresolvedSequenceMacro extends Reason {
|
||||
override def explain(originalName: Name): String =
|
||||
"No definition for the sequence macro could be found. Try" +
|
||||
" importing the default definition from the Base.Vector module."
|
||||
}
|
||||
|
||||
/**
|
||||
* An error coming from an unexpected occurence of a polyglot symbol.
|
||||
*
|
||||
@ -5310,7 +5316,7 @@ object IR {
|
||||
*/
|
||||
case class UnexpectedPolyglot(context: String) extends Reason {
|
||||
override def explain(originalName: Name): String =
|
||||
s"The name ${originalName.name} resolved to a polyglot symbol," +
|
||||
s"The name ${originalName.name} resolved to a polyglot symbol, " +
|
||||
s"but polyglot symbols are not allowed in $context."
|
||||
}
|
||||
|
||||
@ -5322,7 +5328,7 @@ object IR {
|
||||
*/
|
||||
case class UnexpectedMethod(context: String) extends Reason {
|
||||
override def explain(originalName: Name): String =
|
||||
s"The name ${originalName.name} resolved to a method," +
|
||||
s"The name ${originalName.name} resolved to a method, " +
|
||||
s"but methods are not allowed in $context."
|
||||
}
|
||||
|
||||
|
@ -57,14 +57,13 @@ case class BindingsMap(
|
||||
}
|
||||
|
||||
private def findLocalCandidates(name: String): List[ResolvedName] = {
|
||||
if (currentModule.getName.item == name) {
|
||||
val conses = findConstructorCandidates(name)
|
||||
val polyglot = findPolyglotCandidates(name)
|
||||
val methods = findMethodCandidates(name)
|
||||
val all = conses ++ polyglot ++ methods
|
||||
if (all.isEmpty && currentModule.getName.item == name) {
|
||||
List(ResolvedModule(currentModule))
|
||||
} else {
|
||||
val conses = findConstructorCandidates(name)
|
||||
val polyglot = findPolyglotCandidates(name)
|
||||
val methods = findMethodCandidates(name)
|
||||
conses ++ polyglot ++ methods
|
||||
}
|
||||
} else { all }
|
||||
}
|
||||
|
||||
private def findQualifiedImportCandidates(
|
||||
|
@ -0,0 +1,108 @@
|
||||
package org.enso.compiler.pass.resolve
|
||||
|
||||
import org.enso.compiler.context.{InlineContext, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.core.ir.MetadataStorage.ToPair
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.pass.IRPass
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
|
||||
case object VectorLiterals extends IRPass {
|
||||
|
||||
/** The type of the metadata object that the pass writes to the IR. */
|
||||
override type Metadata = IRPass.Metadata.Empty
|
||||
|
||||
/** The type of configuration for the pass. */
|
||||
override type Config = IRPass.Configuration.Default
|
||||
|
||||
/** The passes that this pass depends _directly_ on to run. */
|
||||
override val precursorPasses: Seq[IRPass] = Seq(UppercaseNames)
|
||||
|
||||
/** The passes that are invalidated by running this pass. */
|
||||
override val invalidatedPasses: Seq[IRPass] = Seq()
|
||||
|
||||
/** Executes the pass on the provided `ir`, and returns a possibly transformed
|
||||
* or annotated version of `ir`.
|
||||
*
|
||||
* @param ir the Enso IR to process
|
||||
* @param moduleContext a context object that contains the information needed
|
||||
* to process a module
|
||||
* @return `ir`, possibly having made transformations or annotations to that
|
||||
* IR.
|
||||
*/
|
||||
override def runModule(
|
||||
ir: IR.Module,
|
||||
moduleContext: ModuleContext
|
||||
): IR.Module = {
|
||||
val bindings = ir.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"no bindings analysis on the current module"
|
||||
)
|
||||
val vec = vectorCons(bindings)
|
||||
ir.mapExpressions(doExpression(_, vec))
|
||||
}
|
||||
|
||||
/** Executes the pass on the provided `ir`, and returns a possibly transformed
|
||||
* or annotated version of `ir` in an inline context.
|
||||
*
|
||||
* @param ir the Enso IR to process
|
||||
* @param inlineContext a context object that contains the information needed
|
||||
* for inline evaluation
|
||||
* @return `ir`, possibly having made transformations or annotations to that
|
||||
* IR.
|
||||
*/
|
||||
override def runExpression(
|
||||
ir: IR.Expression,
|
||||
inlineContext: InlineContext
|
||||
): IR.Expression = {
|
||||
val bindings = inlineContext.module.getIr.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"no bindings analysis on the current module"
|
||||
)
|
||||
val vec = vectorCons(bindings)
|
||||
doExpression(ir, vec)
|
||||
}
|
||||
|
||||
private def vectorCons(bindings: BindingsMap): IR.Expression = {
|
||||
val module = bindings.resolvedImports
|
||||
.flatMap(imp =>
|
||||
imp.module :: imp.module.getIr
|
||||
.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"no binding analyis on an imported module"
|
||||
)
|
||||
.resolvedExports
|
||||
.map(_.module)
|
||||
)
|
||||
.find(_.getName.toString == "Base.Vector")
|
||||
val name = IR.Name.Literal("<Sequence Macro>", isReferent = true, None)
|
||||
module
|
||||
.map { module =>
|
||||
val withRes = name.updateMetadata(
|
||||
UppercaseNames -->> BindingsMap.Resolution(
|
||||
BindingsMap
|
||||
.ResolvedConstructor(module, BindingsMap.Cons("Vector", 1))
|
||||
)
|
||||
)
|
||||
withRes
|
||||
}
|
||||
.getOrElse {
|
||||
IR.Error.Resolution(name, IR.Error.Resolution.UnresolvedSequenceMacro)
|
||||
}
|
||||
}
|
||||
|
||||
private def doExpression(
|
||||
ir: IR.Expression,
|
||||
vec: IR.Expression
|
||||
): IR.Expression =
|
||||
ir.transformExpressions {
|
||||
case seq: IR.Application.Literal.Sequence =>
|
||||
val trans = seq.mapExpressions(doExpression(_, vec))
|
||||
IR.Application.Prefix(
|
||||
vec,
|
||||
List(IR.CallArgument.Specified(None, trans, None, None)),
|
||||
false,
|
||||
None
|
||||
)
|
||||
}
|
||||
}
|
@ -3,4 +3,4 @@ from TestNonImportedOverloads.Util import all
|
||||
|
||||
X.method = 10
|
||||
|
||||
Main.main = Unit.util (X 1)
|
||||
main = Unit.util (X 1)
|
||||
|
@ -5,4 +5,4 @@ type X a
|
||||
|
||||
X.method = 10
|
||||
|
||||
Main.main = Unit.util (X 1)
|
||||
main = Unit.util (X 1)
|
||||
|
@ -1,3 +1,3 @@
|
||||
from TestSimpleImports.Atom import all
|
||||
|
||||
Main.main = (X 1).method
|
||||
main = (X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
from Test_Hiding_Error.Atom import all hiding X
|
||||
|
||||
Main.main = (X 1).method
|
||||
main = (X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
from Test_Hiding_Success.Atom import all hiding Y
|
||||
|
||||
Main.main = (X 1).method
|
||||
main = (X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Test_Qualified_Error.Atom
|
||||
|
||||
Main.main = (X 1).method
|
||||
main = (X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Test_Rename.Atom as Def
|
||||
|
||||
Main.main = (Def.X 1).method
|
||||
main = (Def.X 1).method
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Test_Rename_Error.Atom as Def
|
||||
|
||||
Main.main = (Atom.X 1).method
|
||||
main = (Atom.X 1).method
|
||||
|
@ -856,21 +856,28 @@ class DataflowAnalysisTest extends CompilerTest {
|
||||
|
||||
val depInfo = ir.getMetadata(DataflowAnalysis).get
|
||||
|
||||
val vector = ir.body
|
||||
val callArg = ir.body
|
||||
.asInstanceOf[IR.Application.Prefix]
|
||||
.arguments(0)
|
||||
val vector = callArg.value
|
||||
.asInstanceOf[IR.Application.Literal.Sequence]
|
||||
|
||||
val xDefId = mkStaticDep(ir.arguments(0).getId)
|
||||
val xUseId = mkStaticDep(vector.items(0).getId)
|
||||
val yId = mkStaticDep(vector.items(1).getId)
|
||||
val litId = mkStaticDep(vector.items(2).getId)
|
||||
val vecId = mkStaticDep(vector.getId)
|
||||
val lamId = mkStaticDep(ir.getId)
|
||||
val xDefId = mkStaticDep(ir.arguments(0).getId)
|
||||
val xUseId = mkStaticDep(vector.items(0).getId)
|
||||
val yId = mkStaticDep(vector.items(1).getId)
|
||||
val litId = mkStaticDep(vector.items(2).getId)
|
||||
val vecId = mkStaticDep(vector.getId)
|
||||
val callArgId = mkStaticDep(callArg.getId)
|
||||
val appId = mkStaticDep(ir.body.getId)
|
||||
val lamId = mkStaticDep(ir.getId)
|
||||
|
||||
depInfo.getDirect(xDefId) shouldEqual Some(Set(xUseId))
|
||||
depInfo.getDirect(xUseId) shouldEqual Some(Set(vecId))
|
||||
depInfo.getDirect(yId) shouldEqual Some(Set(vecId))
|
||||
depInfo.getDirect(litId) shouldEqual Some(Set(vecId))
|
||||
depInfo.getDirect(vecId) shouldEqual Some(Set(lamId))
|
||||
depInfo.getDirect(vecId) shouldEqual Some(Set(callArgId))
|
||||
depInfo.getDirect(callArgId) shouldEqual Some(Set(appId))
|
||||
depInfo.getDirect(appId) shouldEqual Some(Set(lamId))
|
||||
}
|
||||
|
||||
"work properly for typeset literals" in {
|
||||
|
@ -150,6 +150,9 @@ class DemandAnalysisTest extends CompilerTest {
|
||||
val vec = ir
|
||||
.asInstanceOf[IR.Function.Lambda]
|
||||
.body
|
||||
.asInstanceOf[IR.Application.Prefix]
|
||||
.arguments(0)
|
||||
.value
|
||||
.asInstanceOf[IR.Application.Literal.Sequence]
|
||||
|
||||
vec.items(0) shouldBe an[IR.Application.Force]
|
||||
|
@ -0,0 +1,102 @@
|
||||
package org.enso.compiler.test.pass.resolve
|
||||
|
||||
import org.enso.compiler.Passes
|
||||
import org.enso.compiler.context.{FreshNameSupply, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.pass.PassConfiguration.ToPair
|
||||
import org.enso.compiler.pass.analyse.AliasAnalysis
|
||||
import org.enso.compiler.pass.optimise.ApplicationSaturation
|
||||
import org.enso.compiler.pass.resolve.VectorLiterals
|
||||
import org.enso.compiler.pass.{PassConfiguration, PassGroup, PassManager}
|
||||
import org.enso.compiler.test.CompilerTest
|
||||
|
||||
class VectorLiteralsTest extends CompilerTest {
|
||||
|
||||
// === Test Setup ===========================================================
|
||||
|
||||
def mkModuleContext: ModuleContext =
|
||||
buildModuleContext(
|
||||
freshNameSupply = Some(new FreshNameSupply)
|
||||
)
|
||||
|
||||
val passes = new Passes
|
||||
|
||||
val precursorPasses: PassGroup =
|
||||
passes.getPrecursors(VectorLiterals).get
|
||||
|
||||
val passConfiguration: PassConfiguration = PassConfiguration(
|
||||
AliasAnalysis -->> AliasAnalysis.Configuration(),
|
||||
ApplicationSaturation -->> ApplicationSaturation.Configuration()
|
||||
)
|
||||
|
||||
implicit val passManager: PassManager =
|
||||
new PassManager(List(precursorPasses), passConfiguration)
|
||||
|
||||
/** Adds an extension method to analyse an Enso module.
|
||||
*
|
||||
* @param ir the ir to analyse
|
||||
*/
|
||||
implicit class AnalyseModule(ir: IR.Module) {
|
||||
|
||||
/** Performs tail call analysis on [[ir]].
|
||||
*
|
||||
* @param context the module context in which analysis takes place
|
||||
* @return [[ir]], with tail call analysis metadata attached
|
||||
*/
|
||||
def analyse(implicit context: ModuleContext) = {
|
||||
VectorLiterals.runModule(ir, context)
|
||||
}
|
||||
}
|
||||
|
||||
// === The Tests ============================================================
|
||||
|
||||
"Pattern resolution" should {
|
||||
implicit val ctx: ModuleContext = mkModuleContext
|
||||
|
||||
val ir =
|
||||
"""
|
||||
|foo (x = [1, 2, 3]) =
|
||||
| foo = ["foo", bar, [1,2,3]]
|
||||
| x
|
||||
|
|
||||
|""".stripMargin.preprocessModule.analyse
|
||||
|
||||
"transform vector literals into applications" in {
|
||||
val fun = ir
|
||||
.bindings(0)
|
||||
.asInstanceOf[IR.Module.Scope.Definition.Method.Explicit]
|
||||
.body
|
||||
.asInstanceOf[IR.Function.Lambda]
|
||||
|
||||
val arg = fun.arguments(1).defaultValue.get
|
||||
arg shouldBe an[IR.Application.Prefix]
|
||||
arg
|
||||
.asInstanceOf[IR.Application.Prefix]
|
||||
.arguments(0)
|
||||
.value shouldBe an[IR.Application.Literal.Sequence]
|
||||
|
||||
val bodyLiteral = fun.body
|
||||
.asInstanceOf[IR.Expression.Block]
|
||||
.expressions(0)
|
||||
.asInstanceOf[IR.Expression.Binding]
|
||||
.expression
|
||||
|
||||
bodyLiteral shouldBe an[IR.Application.Prefix]
|
||||
|
||||
val outerVec =
|
||||
bodyLiteral.asInstanceOf[IR.Application.Prefix].arguments(0).value
|
||||
|
||||
outerVec shouldBe an[IR.Application.Literal.Sequence]
|
||||
|
||||
val innerLiteral =
|
||||
outerVec.asInstanceOf[IR.Application.Literal.Sequence].items(2)
|
||||
|
||||
innerLiteral shouldBe an[IR.Application.Prefix]
|
||||
|
||||
innerLiteral
|
||||
.asInstanceOf[IR.Application.Prefix]
|
||||
.arguments(0)
|
||||
.value shouldBe an[IR.Application.Literal.Sequence]
|
||||
}
|
||||
}
|
||||
}
|
@ -1197,10 +1197,10 @@ class RuntimeServerTest
|
||||
val idMain = metadata.addItem(32, 35)
|
||||
val idMainA = metadata.addItem(41, 8)
|
||||
val idMainP = metadata.addItem(54, 12)
|
||||
val idPie = metadata.addItem(71 + 8, 1)
|
||||
val idUwu = metadata.addItem(84 + 8, 1)
|
||||
val idHie = metadata.addItem(97 + 8, 6)
|
||||
val idXxx = metadata.addItem(117 + 8, 1)
|
||||
val idPie = metadata.addItem(66 + 8, 1)
|
||||
val idUwu = metadata.addItem(74 + 8, 1)
|
||||
val idHie = metadata.addItem(82 + 8, 6)
|
||||
val idXxx = metadata.addItem(102 + 8, 1)
|
||||
val code =
|
||||
"""from Builtins import all
|
||||
|
|
||||
@ -1208,9 +1208,9 @@ class RuntimeServerTest
|
||||
| a = 123 + 21
|
||||
| IO.println a
|
||||
|
|
||||
|Main.pie = 3
|
||||
|Main.uwu = 7
|
||||
|Main.hie = "hie!"
|
||||
|pie = 3
|
||||
|uwu = 7
|
||||
|hie = "hie!"
|
||||
|Number.x y = y
|
||||
|""".stripMargin.linesIterator.mkString("\n")
|
||||
val contents = metadata.appendToCode(code)
|
||||
@ -1399,7 +1399,7 @@ class RuntimeServerTest
|
||||
Seq(
|
||||
TextEdit(
|
||||
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
||||
"Main.pie"
|
||||
"here.pie"
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -1430,7 +1430,7 @@ class RuntimeServerTest
|
||||
Seq(
|
||||
TextEdit(
|
||||
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
||||
"Main.uwu"
|
||||
"here.uwu"
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -1461,7 +1461,7 @@ class RuntimeServerTest
|
||||
Seq(
|
||||
TextEdit(
|
||||
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
||||
"Main.hie"
|
||||
"here.hie"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.enso.interpreter.test.semantic
|
||||
import org.enso.interpreter.node.callable.function.CreateFunctionNode
|
||||
import org.enso.interpreter.node.callable.thunk.ForceNode
|
||||
import org.enso.interpreter.node.callable.{ApplicationNode, SequenceLiteralNode}
|
||||
import org.enso.interpreter.node.callable.ApplicationNode
|
||||
import org.enso.interpreter.node.controlflow.CaseNode
|
||||
import org.enso.interpreter.node.expression.literal.IntegerLiteralNode
|
||||
import org.enso.interpreter.node.scope.{AssignmentNode, ReadLocalVariableNode}
|
||||
@ -186,23 +186,6 @@ class CodeLocationsTest extends InterpreterTest {
|
||||
()
|
||||
}
|
||||
|
||||
"be correct for vector literals" in
|
||||
withLocationsInstrumenter { instrumenter =>
|
||||
val code = "main = [11, 2 + 2, 31 * 42, [1,2,3] ]"
|
||||
instrumenter.assertNodeExists( // outer list
|
||||
7,
|
||||
30,
|
||||
classOf[SequenceLiteralNode]
|
||||
)
|
||||
instrumenter.assertNodeExists( // inner list
|
||||
28,
|
||||
7,
|
||||
classOf[SequenceLiteralNode]
|
||||
)
|
||||
instrumenter.assertNodeExists(19, 7, classOf[ApplicationNode]) // 31 * 42
|
||||
eval(code)
|
||||
}
|
||||
|
||||
"be correct for negated literals" in
|
||||
withLocationsInstrumenter { instrumenter =>
|
||||
val code = "main = (-1)"
|
||||
|
@ -14,8 +14,9 @@ class JavaInteropTest extends InterpreterTest {
|
||||
val code =
|
||||
"""
|
||||
|polyglot java import org.enso.example.TestClass
|
||||
|from Builtins import all
|
||||
|
|
||||
|main = TestClass.add [1, 2]
|
||||
|main = TestClass.add (Array.new_2 1 2)
|
||||
|""".stripMargin
|
||||
|
||||
eval(code) shouldEqual 3
|
||||
@ -25,10 +26,11 @@ class JavaInteropTest extends InterpreterTest {
|
||||
val code =
|
||||
"""
|
||||
|polyglot java import org.enso.example.TestClass
|
||||
|from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| instance = TestClass.new [x -> x * 2]
|
||||
| instance.callFunctionAndIncrement [10]
|
||||
| instance = TestClass.new (Array.new_1 (x -> x * 2))
|
||||
| instance.callFunctionAndIncrement (Array.new_1 10)
|
||||
|""".stripMargin
|
||||
eval(code) shouldEqual 21
|
||||
}
|
||||
|
@ -139,23 +139,6 @@ class LambdaShorthandArgsTest extends InterpreterTest {
|
||||
eval(code) shouldEqual 15
|
||||
}
|
||||
|
||||
"work properly with vector literals" in {
|
||||
val code =
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| fun = [1, _, (1 + 2), _]
|
||||
| vec = fun 2 4
|
||||
| IO.println (Polyglot.get_array_element vec 0)
|
||||
| IO.println (Polyglot.get_array_element vec 1)
|
||||
| IO.println (Polyglot.get_array_element vec 2)
|
||||
| IO.println (Polyglot.get_array_element vec 3)
|
||||
|
|
||||
|""".stripMargin
|
||||
eval(code)
|
||||
consumeOut shouldEqual List("1", "2", "3", "4")
|
||||
}
|
||||
|
||||
"work properly when used with dot notation" in {
|
||||
val code =
|
||||
"""
|
||||
|
@ -257,16 +257,5 @@ class NamedArgumentsTest extends InterpreterTest {
|
||||
|
||||
eval(code) shouldEqual 10
|
||||
}
|
||||
|
||||
"be assignable from Vectors" in {
|
||||
val code =
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| lam = (x=[1,3]) -> y -> y + Polyglot.get_array_element x 0 + Polyglot.get_array_element x 1
|
||||
| lam y=10
|
||||
|""".stripMargin
|
||||
eval(code) shouldEqual 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
|main =
|
||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||
| method = Polyglot.get_member class "add"
|
||||
| Polyglot.execute method [1, 2]
|
||||
| Polyglot.execute method (Array.new_2 1 2)
|
||||
|""".stripMargin
|
||||
|
||||
eval(code) shouldEqual 3
|
||||
@ -28,8 +28,8 @@ class PolyglotTest extends InterpreterTest {
|
||||
|
|
||||
|main =
|
||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||
| instance = Polyglot.new class [x -> x * 2]
|
||||
| Polyglot.invoke instance "callFunctionAndIncrement" [10]
|
||||
| instance = Polyglot.new class (Array.new_1 (x -> x * 2))
|
||||
| Polyglot.invoke instance "callFunctionAndIncrement" (Array.new_1 10)
|
||||
|""".stripMargin
|
||||
eval(code) shouldEqual 21
|
||||
}
|
||||
@ -40,7 +40,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
|
|
||||
|main =
|
||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||
| instance = Polyglot.new class []
|
||||
| instance = Polyglot.new class Array.empty
|
||||
| members = Polyglot.get_members instance
|
||||
| IO.println (Polyglot.get_array_size members)
|
||||
| IO.println (Polyglot.get_array_element members 0)
|
||||
|
@ -1,27 +0,0 @@
|
||||
package org.enso.interpreter.test.semantic
|
||||
|
||||
import org.enso.interpreter.test.{InterpreterTest, InterpreterContext}
|
||||
|
||||
class SequenceLiteralsTest extends InterpreterTest {
|
||||
override def subject: String = "Vector Literals"
|
||||
|
||||
override def specify(
|
||||
implicit interpreterContext: InterpreterContext
|
||||
): Unit = {
|
||||
"create collections, with fields accessible through the Polyglot API" in {
|
||||
val code =
|
||||
"""from Builtins import all
|
||||
|
|
||||
|type My x y
|
||||
|
|
||||
|main =
|
||||
| vec = [1, "abc", My 1 2]
|
||||
| IO.println (Polyglot.get_array_element vec 0)
|
||||
| IO.println (Polyglot.get_array_element vec 1)
|
||||
| IO.println (Polyglot.get_array_element vec 2)
|
||||
|""".stripMargin
|
||||
eval(code)
|
||||
consumeOut shouldEqual List("1", "abc", "My 1 2")
|
||||
}
|
||||
}
|
||||
}
|
@ -108,20 +108,5 @@ class SuspendedArgumentsTest extends InterpreterTest {
|
||||
|
||||
eval(code) shouldEqual 1
|
||||
}
|
||||
|
||||
"work with vector literals" in {
|
||||
val code =
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| foo = ~x -> [x]
|
||||
| block =
|
||||
| IO.println "foo"
|
||||
| 5
|
||||
| Polyglot.get_array_element (foo block) 0
|
||||
|""".stripMargin
|
||||
eval(code) shouldEqual 5
|
||||
consumeOut shouldEqual List("foo")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "echo" [] "" False False False
|
||||
| result = System.create_process "echo" Array.empty "" False False False
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
eval(code) shouldEqual 0
|
||||
@ -32,7 +32,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"return error when creating nonexistent command" in {
|
||||
val code =
|
||||
"""from Builtins import all
|
||||
|main = System.create_process "nonexistentcommandxyz" [] "" False False False
|
||||
|main = System.create_process "nonexistentcommandxyz" Array.empty "" False False False
|
||||
|""".stripMargin
|
||||
|
||||
val error = the[InterpreterException] thrownBy eval(code)
|
||||
@ -46,7 +46,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "ls" ["--gibberish"] "" False False False
|
||||
| result = System.create_process "ls" (Array.new_1 "--gibberish") "" False False False
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -60,7 +60,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "read line; echo $line"] "" True True True
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "read line; echo $line") "" True True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -75,7 +75,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::ReadLine()"] "" True True True
|
||||
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::ReadLine()") "" True True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -91,7 +91,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "wc -c"] "" True True True
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "wc -c") "" True True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -106,7 +106,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "echo" ["42"] "" True True True
|
||||
| result = System.create_process "echo" (Array.new_1 "42") "" True True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -121,7 +121,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "echo" ["9"] "" True True True
|
||||
| result = System.create_process "echo" (Array.new_1 "9") "" True True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -135,7 +135,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "read line; printf $line"] "hello" False False False
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "read line; printf $line") "hello" False False False
|
||||
| result.stdout
|
||||
|""".stripMargin
|
||||
|
||||
@ -149,7 +149,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::ReadLine()"] "hello" False False False
|
||||
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::ReadLine()") "hello" False False False
|
||||
| result.stdout
|
||||
|""".stripMargin
|
||||
|
||||
@ -163,7 +163,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "echo" ["foobar"] "" False True True
|
||||
| result = System.create_process "echo" (Array.new_1 "foobar") "" False True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -177,7 +177,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "printf '%b' '\\x01\\x0F\\x10'"] "" False True True
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "printf '%b' '\\x01\\x0F\\x10'") "" False True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -191,7 +191,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "echo" ["foobar"] "" False False False
|
||||
| result = System.create_process "echo" (Array.new_1 "foobar") "" False False False
|
||||
| result.stdout
|
||||
|""".stripMargin
|
||||
|
||||
@ -205,7 +205,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "printf err 1>&2"] "" False True True
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "printf err 1>&2") "" False True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -219,7 +219,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::Error.WriteLine('err')"] "" False True True
|
||||
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::Error.WriteLine('err')") "" False True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -233,7 +233,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "printf '%b' '\\xCA\\xFE\\xBA\\xBE' 1>&2"] "" False True True
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "printf '%b' '\\xCA\\xFE\\xBA\\xBE' 1>&2") "" False True True
|
||||
| result.exit_code
|
||||
|""".stripMargin
|
||||
|
||||
@ -247,7 +247,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "bash" ["-c", "printf err 1>&2"] "" False False False
|
||||
| result = System.create_process "bash" (Array.new_2 "-c" "printf err 1>&2") "" False False False
|
||||
| result.stderr
|
||||
|""".stripMargin
|
||||
|
||||
@ -261,7 +261,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
||||
"""from Builtins import all
|
||||
|
|
||||
|main =
|
||||
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::Error.WriteLine('err')"] "" False False False
|
||||
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::Error.WriteLine('err')") "" False False False
|
||||
| result.stderr
|
||||
|""".stripMargin
|
||||
|
||||
|
19
test/Benchmarks/src/Collections.enso
Normal file
19
test/Benchmarks/src/Collections.enso
Normal file
@ -0,0 +1,19 @@
|
||||
from Base import all
|
||||
import Base.Bench_Utils
|
||||
|
||||
gen_list len = 0.upto len . fold Nil (l -> i -> Cons i+1 l)
|
||||
|
||||
sum_vec vec =
|
||||
arr = vec.to_array
|
||||
len = vec.length
|
||||
sumator = acc -> idx ->
|
||||
if idx == len then acc else sumator (acc + arr.at idx) idx+1
|
||||
res = sumator 0 0
|
||||
res
|
||||
|
||||
main =
|
||||
mil = 1000000
|
||||
list = here.gen_list mil
|
||||
vec = Vector.new mil (ix -> ix + 1)
|
||||
Bench_Utils.measure (vec.fold 0 (+)) "vector fold" 1000 10
|
||||
Bench_Utils.measure (list.fold 0 (+)) "list fold" 1000 10
|
@ -1,5 +1,7 @@
|
||||
import Base.Bench_Utils
|
||||
import Base.List
|
||||
from Base import all
|
||||
|
||||
polyglot java import java.lang.Long
|
||||
|
||||
type Counter
|
||||
type Sum
|
||||
@ -10,6 +12,12 @@ sum_tco = sum_to ->
|
||||
res = summator 0 sum_to
|
||||
res
|
||||
|
||||
sum_tco_java = sum_to ->
|
||||
summator = acc -> current ->
|
||||
if current == 0 then acc else summator (Long.sum [acc, current]) (current - 1)
|
||||
res = summator 0 sum_to
|
||||
res
|
||||
|
||||
sum_co_state_body =
|
||||
n = State.get Counter
|
||||
acc = State.get Sum
|
||||
@ -34,6 +42,8 @@ main =
|
||||
hundred_mil = 100000000
|
||||
IO.println "Measuring SumTCO"
|
||||
Bench_Utils.measure (here.sum_tco hundred_mil) "sum_tco" 100 10
|
||||
IO.println "Measuring SumTCO Java"
|
||||
Bench_Utils.measure (here.sum_tco_java hundred_mil) "sum_tco" 100 10
|
||||
IO.println "Measuring State"
|
||||
Bench_Utils.measure (here.sum_state hundred_mil) "sum_state" 100 10
|
||||
IO.println "Measuring Co-State"
|
||||
|
8
test/Test/src/Java_Interop/Spec.enso
Normal file
8
test/Test/src/Java_Interop/Spec.enso
Normal file
@ -0,0 +1,8 @@
|
||||
from Base import all
|
||||
import Base.Test
|
||||
|
||||
polyglot java import java.lang.Long
|
||||
|
||||
spec = describe "Java FFI" <|
|
||||
it "should call methods imported from Java" <|
|
||||
Long.sum [1, 2] . should_equal 3
|
@ -5,6 +5,8 @@ import Test.Import_Loop_Spec
|
||||
import Test.Deep_Export_Spec
|
||||
import Test.Names_Spec
|
||||
import Test.Process_Spec
|
||||
import Test.Java_Interop.Spec as Java_Spec
|
||||
import Test.Vector.Spec as Vector_Spec
|
||||
|
||||
main = Test.Suite.runMain <|
|
||||
List_Spec.spec
|
||||
@ -13,3 +15,5 @@ main = Test.Suite.runMain <|
|
||||
Names_Spec.spec
|
||||
Deep_Export_Spec.spec
|
||||
Process_Spec.spec
|
||||
Java_Spec.spec
|
||||
Vector_Spec.spec
|
||||
|
@ -1,3 +1,4 @@
|
||||
from Base import all
|
||||
import Base.Process
|
||||
from Base.Process.Exit_Code import Exit_Success, Exit_Failure
|
||||
import Base.System.Platform
|
||||
|
22
test/Test/src/Vector/Spec.enso
Normal file
22
test/Test/src/Vector/Spec.enso
Normal file
@ -0,0 +1,22 @@
|
||||
from Base import all
|
||||
import Base.Test
|
||||
|
||||
spec = describe "Vectors" <|
|
||||
it "should allow accessing elements" <|
|
||||
[1,2,3].at 2 . should_equal 3
|
||||
it "should have a well-defined length" <|
|
||||
[1,2,3].length . should_equal 3
|
||||
it "should allow folding an operator over its elements" <|
|
||||
[1,2,3].fold 0 (+) . should_equal 6
|
||||
it "should allow vector creation with a programmatic constructor" <|
|
||||
Vector.new 100 (ix -> ix + 1) . fold 0 (+) . should_equal 5050
|
||||
it "should have a well-defined text conversion" <|
|
||||
[].to_text.should_equal "[]"
|
||||
[1,2,3].to_text.should_equal "[1, 2, 3]"
|
||||
[Unit].to_text.should_equal "[Unit]"
|
||||
it "should allow mapping an operation, returning a new vector" <|
|
||||
vec = [1, 2, 3, 4]
|
||||
mapped = vec.map x-> x * x
|
||||
vec.to_text.should_equal "[1, 2, 3, 4]"
|
||||
mapped.to_text.should_equal "[1, 4, 9, 16]"
|
||||
|
Loading…
Reference in New Issue
Block a user