mirror of
https://github.com/enso-org/enso.git
synced 2025-01-03 14:04: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 ->
|
reverse_list = list ->
|
||||||
go = list -> acc -> case list of
|
go = list -> acc -> case list of
|
||||||
Cons h t -> go t (Cons h acc)
|
Cons h t -> go t (Cons h acc)
|
||||||
@ -24,6 +26,11 @@ Number.times = act ->
|
|||||||
res = here.reverse_list (go Nil this)
|
res = here.reverse_list (go Nil this)
|
||||||
res
|
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 ->
|
measure = ~act -> label -> iter_size -> num_iters ->
|
||||||
single_call = _ ->
|
single_call = _ ->
|
||||||
x1 = System.nano_time
|
x1 = System.nano_time
|
||||||
@ -34,5 +41,6 @@ measure = ~act -> label -> iter_size -> num_iters ->
|
|||||||
act_it_num = num_iters - it_num
|
act_it_num = num_iters - it_num
|
||||||
res = iter_size.times single_call
|
res = iter_size.times single_call
|
||||||
avg = here.avg_list res
|
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
|
num_iters.times iteration
|
||||||
|
@ -72,9 +72,12 @@ type List
|
|||||||
list:
|
list:
|
||||||
(Cons 0 <| Cons 1 <| Cons 2 <| Nil) . fold 0 (+)
|
(Cons 0 <| Cons 1 <| Cons 2 <| Nil) . fold 0 (+)
|
||||||
fold : Any -> (Any -> Any -> Any) -> Any
|
fold : Any -> (Any -> Any -> Any) -> Any
|
||||||
fold init f = case this of
|
fold init f =
|
||||||
Nil -> init
|
go acc list = case list of
|
||||||
Cons h t -> t.fold (f init h) f
|
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
|
## Reverses the list, returning a list with the same elements, but in the
|
||||||
opposite order.
|
opposite order.
|
||||||
|
@ -1,6 +1,46 @@
|
|||||||
import Base.List
|
import Base.List
|
||||||
import Builtins
|
import Base.Vector
|
||||||
|
from Builtins import Number, Unit
|
||||||
|
|
||||||
from Builtins export all
|
from Builtins export all
|
||||||
|
|
||||||
from Base.List export Nil, Cons
|
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
|
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.
|
## The builder object that is used to create operating system processes.
|
||||||
type Process_Builder command arguments stdin
|
type Process_Builder command arguments stdin
|
||||||
@ -16,7 +17,7 @@ type Process_Result exit_code stdout stderr
|
|||||||
8
|
8
|
||||||
Process.execute : String -> Exit_Code
|
Process.execute : String -> Exit_Code
|
||||||
Process.execute command =
|
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
|
Exit_Code.from_number result.exit_code
|
||||||
|
|
||||||
## Call a command with a list of arguments.
|
## Call a command with a list of arguments.
|
||||||
@ -28,7 +29,7 @@ Process.execute command =
|
|||||||
Hello!
|
Hello!
|
||||||
Process.run_command : String -> Vector -> Exit_Code
|
Process.run_command : String -> Vector -> Exit_Code
|
||||||
Process.run_command command arguments =
|
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
|
Exit_Code.from_number result.exit_code
|
||||||
|
|
||||||
## Create a process using a builder returning the result of execution.
|
## 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_Result Exit_Success "test" ""
|
||||||
Process.create : Process_Builder -> Process_Result
|
Process.create : Process_Builder -> Process_Result
|
||||||
Process.create b =
|
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
|
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.Atom;
|
||||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||||
import org.enso.interpreter.runtime.callable.function.Function;
|
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.MethodDoesNotExistException;
|
||||||
import org.enso.interpreter.runtime.error.RuntimeError;
|
import org.enso.interpreter.runtime.error.RuntimeError;
|
||||||
|
|
||||||
@ -157,6 +158,16 @@ public abstract class MethodResolverNode extends Node {
|
|||||||
return function;
|
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)"})
|
@Specialization(guards = {"cachedSymbol == symbol", "ctx.getEnvironment().isHostObject(target)"})
|
||||||
Function resolveHost(
|
Function resolveHost(
|
||||||
UnresolvedSymbol symbol,
|
UnresolvedSymbol symbol,
|
||||||
@ -220,11 +231,18 @@ public abstract class MethodResolverNode extends Node {
|
|||||||
return ensureMethodExists(symbol.resolveFor(getBuiltins().any()), "Error", symbol);
|
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) {
|
Function buildHostResolver(UnresolvedSymbol symbol, Context context) {
|
||||||
if (symbol.getName().equals("new")) {
|
if (symbol.getName().equals("new")) {
|
||||||
return context.getBuiltins().getConstructorDispatch();
|
return context.getBuiltins().getConstructorDispatch();
|
||||||
} else {
|
} 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.ExplodeLoop;
|
||||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||||
import org.enso.interpreter.node.ExpressionNode;
|
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.")
|
@NodeInfo(shortName = "[]", description = "Creates a vector from given expressions.")
|
||||||
public class SequenceLiteralNode extends ExpressionNode {
|
public class SequenceLiteralNode extends ExpressionNode {
|
||||||
@ -28,7 +28,7 @@ public class SequenceLiteralNode extends ExpressionNode {
|
|||||||
* Executes the node.
|
* Executes the node.
|
||||||
*
|
*
|
||||||
* @param frame the stack frame for execution.
|
* @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
|
@Override
|
||||||
@ExplodeLoop
|
@ExplodeLoop
|
||||||
@ -37,6 +37,6 @@ public class SequenceLiteralNode extends ExpressionNode {
|
|||||||
for (int i = 0; i < items.length; i++) {
|
for (int i = 0; i < items.length; i++) {
|
||||||
itemValues[i] = items[i].executeGeneric(frame);
|
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;
|
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.ArityException;
|
||||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||||
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
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 com.oracle.truffle.api.profiles.BranchProfile;
|
||||||
import org.enso.interpreter.Constants;
|
import org.enso.interpreter.Constants;
|
||||||
import org.enso.interpreter.Language;
|
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.BuiltinRootNode;
|
import org.enso.interpreter.runtime.data.Array;
|
||||||
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.error.PanicException;
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
import org.enso.interpreter.runtime.state.Stateful;
|
|
||||||
import org.enso.interpreter.runtime.type.TypesGen;
|
|
||||||
|
|
||||||
@BuiltinMethod(
|
@BuiltinMethod(
|
||||||
type = "Polyglot",
|
type = "Polyglot",
|
||||||
@ -30,7 +20,7 @@ public class ExecuteNode extends Node {
|
|||||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||||
private final BranchProfile err = BranchProfile.create();
|
private final BranchProfile err = BranchProfile.create();
|
||||||
|
|
||||||
Object execute(Object _this, Object callable, Vector arguments) {
|
Object execute(Object _this, Object callable, Array arguments) {
|
||||||
try {
|
try {
|
||||||
return library.execute(callable, arguments.getItems());
|
return library.execute(callable, arguments.getItems());
|
||||||
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
||||||
|
@ -8,7 +8,7 @@ import com.oracle.truffle.api.nodes.Node;
|
|||||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||||
import org.enso.interpreter.Constants;
|
import org.enso.interpreter.Constants;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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;
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
|
|
||||||
@BuiltinMethod(
|
@BuiltinMethod(
|
||||||
@ -21,7 +21,7 @@ public class InstantiateNode extends Node {
|
|||||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||||
private final BranchProfile err = BranchProfile.create();
|
private final BranchProfile err = BranchProfile.create();
|
||||||
|
|
||||||
Object execute(Object _this, Object constructor, Vector arguments) {
|
Object execute(Object _this, Object constructor, Array arguments) {
|
||||||
try {
|
try {
|
||||||
return library.instantiate(constructor, arguments.getItems());
|
return library.instantiate(constructor, arguments.getItems());
|
||||||
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
||||||
|
@ -5,7 +5,7 @@ import com.oracle.truffle.api.nodes.Node;
|
|||||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||||
import org.enso.interpreter.Constants;
|
import org.enso.interpreter.Constants;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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;
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
|
|
||||||
@BuiltinMethod(
|
@BuiltinMethod(
|
||||||
@ -17,7 +17,7 @@ public class InvokeNode extends Node {
|
|||||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||||
private final BranchProfile err = BranchProfile.create();
|
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 {
|
try {
|
||||||
return library.invokeMember(target, name, arguments.getItems());
|
return library.invokeMember(target, name, arguments.getItems());
|
||||||
} catch (UnsupportedMessageException
|
} catch (UnsupportedMessageException
|
||||||
|
@ -54,7 +54,7 @@ public class ConstructorDispatchNode extends BuiltinRootNode {
|
|||||||
Object cons = args[0];
|
Object cons = args[0];
|
||||||
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
||||||
try {
|
try {
|
||||||
Object[] arguments = TypesGen.expectVector(args[1]).getItems();
|
Object[] arguments = TypesGen.expectArray(args[1]).getItems();
|
||||||
Object res = library.instantiate(cons, arguments);
|
Object res = library.instantiate(cons, arguments);
|
||||||
return new Stateful(state, res);
|
return new Stateful(state, res);
|
||||||
} catch (UnsupportedMessageException
|
} catch (UnsupportedMessageException
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package org.enso.interpreter.node.expression.builtin.interop.syntax;
|
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.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.interop.*;
|
import com.oracle.truffle.api.interop.*;
|
||||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
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 com.oracle.truffle.api.profiles.BranchProfile;
|
||||||
import org.enso.interpreter.Constants;
|
import org.enso.interpreter.Constants;
|
||||||
import org.enso.interpreter.Language;
|
import org.enso.interpreter.Language;
|
||||||
|
import org.enso.interpreter.node.callable.InvokeCallableNode;
|
||||||
import org.enso.interpreter.node.expression.builtin.BuiltinRootNode;
|
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.callable.function.Function;
|
||||||
import org.enso.interpreter.runtime.error.PanicException;
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
import org.enso.interpreter.runtime.state.Stateful;
|
import org.enso.interpreter.runtime.state.Stateful;
|
||||||
import org.enso.interpreter.runtime.type.TypesGen;
|
import org.enso.interpreter.runtime.type.TypesGen;
|
||||||
|
|
||||||
@NodeInfo(shortName = "<polyglot_dispatch>", description = "Invokes a polyglot method by name.")
|
@NodeInfo(shortName = "<polyglot_dispatch>", description = "Invokes a polyglot method by name.")
|
||||||
public class MethodDispatchNode extends BuiltinRootNode {
|
@ReportPolymorphism
|
||||||
private MethodDispatchNode(Language language) {
|
public abstract class MethodDispatchNode extends BuiltinRootNode {
|
||||||
|
MethodDispatchNode(Language language) {
|
||||||
super(language);
|
super(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +31,12 @@ public class MethodDispatchNode extends BuiltinRootNode {
|
|||||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||||
private final BranchProfile err = BranchProfile.create();
|
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.
|
* Creates an instance of this node.
|
||||||
*
|
*
|
||||||
@ -30,7 +44,7 @@ public class MethodDispatchNode extends BuiltinRootNode {
|
|||||||
* @return a function wrapping this node
|
* @return a function wrapping this node
|
||||||
*/
|
*/
|
||||||
public static MethodDispatchNode build(Language language) {
|
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.
|
* @param frame current execution frame.
|
||||||
* @return the result of converting input into a string.
|
* @return the result of converting input into a string.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Specialization(guards = "symbol == cachedSymbol")
|
||||||
public Stateful execute(VirtualFrame frame) {
|
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[] args = Function.ArgumentsHelper.getPositionalArguments(frame.getArguments());
|
||||||
Object callable = args[0];
|
Object callable = args[0];
|
||||||
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
||||||
|
Object arguments = args[2];
|
||||||
|
Stateful casted = invokeCallableNode.execute(toArray, frame, state, new Object[] {arguments});
|
||||||
try {
|
try {
|
||||||
String method = TypesGen.expectString(args[1]);
|
Object[] castedArgs = TypesGen.expectArray(casted.getValue()).getItems();
|
||||||
Object[] arguments = TypesGen.expectVector(args[2]).getItems();
|
Object res = library.invokeMember(callable, symbol.getName(), castedArgs);
|
||||||
Object res = library.invokeMember(callable, method, arguments);
|
return new Stateful(casted.getState(), res);
|
||||||
return new Stateful(state, res);
|
|
||||||
} catch (UnsupportedMessageException
|
} catch (UnsupportedMessageException
|
||||||
| ArityException
|
| ArityException
|
||||||
| UnsupportedTypeException
|
| 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.
|
* 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.Language;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.runtime.Context;
|
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 org.enso.interpreter.runtime.error.PanicException;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -26,7 +26,7 @@ public abstract class CreateProcessNode extends Node {
|
|||||||
abstract Object execute(
|
abstract Object execute(
|
||||||
Object _this,
|
Object _this,
|
||||||
String command,
|
String command,
|
||||||
Vector arguments,
|
Array arguments,
|
||||||
String input,
|
String input,
|
||||||
boolean redirectIn,
|
boolean redirectIn,
|
||||||
boolean redirectOut,
|
boolean redirectOut,
|
||||||
@ -37,15 +37,15 @@ public abstract class CreateProcessNode extends Node {
|
|||||||
Object doCreate(
|
Object doCreate(
|
||||||
Object _this,
|
Object _this,
|
||||||
String command,
|
String command,
|
||||||
Vector arguments,
|
Array arguments,
|
||||||
String input,
|
String input,
|
||||||
boolean redirectIn,
|
boolean redirectIn,
|
||||||
boolean redirectOut,
|
boolean redirectOut,
|
||||||
boolean redirectErr,
|
boolean redirectErr,
|
||||||
@CachedContext(Language.class) Context ctx) {
|
@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;
|
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);
|
TruffleProcessBuilder pb = ctx.getEnvironment().newProcessBuilder(cmd);
|
||||||
|
|
||||||
try {
|
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.CallerInfo;
|
||||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||||
import org.enso.interpreter.runtime.callable.function.Function;
|
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.LocalScope;
|
||||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||||
import org.enso.interpreter.runtime.type.Types;
|
import org.enso.interpreter.runtime.type.Types;
|
||||||
@ -454,7 +454,7 @@ public class Module implements TruffleObject {
|
|||||||
*/
|
*/
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
Object getMembers(boolean includeInternal) {
|
Object getMembers(boolean includeInternal) {
|
||||||
return new Vector(
|
return new Array(
|
||||||
MethodNames.Module.GET_METHOD,
|
MethodNames.Module.GET_METHOD,
|
||||||
MethodNames.Module.GET_CONSTRUCTOR,
|
MethodNames.Module.GET_CONSTRUCTOR,
|
||||||
MethodNames.Module.REPARSE,
|
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.node.expression.builtin.unsafe.SetAtomFieldMethodGen;
|
||||||
import org.enso.interpreter.runtime.Context;
|
import org.enso.interpreter.runtime.Context;
|
||||||
import org.enso.interpreter.runtime.Module;
|
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.ArgumentDefinition;
|
||||||
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
||||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||||
@ -52,6 +53,7 @@ public class Builtins {
|
|||||||
private final Error error;
|
private final Error error;
|
||||||
private final Bool bool;
|
private final Bool bool;
|
||||||
private final System system;
|
private final System system;
|
||||||
|
private final Array array;
|
||||||
|
|
||||||
private final RootCallTarget interopDispatchRoot;
|
private final RootCallTarget interopDispatchRoot;
|
||||||
private final FunctionSchema interopDispatchSchema;
|
private final FunctionSchema interopDispatchSchema;
|
||||||
@ -72,6 +74,7 @@ public class Builtins {
|
|||||||
number = new AtomConstructor("Number", scope).initializeFields();
|
number = new AtomConstructor("Number", scope).initializeFields();
|
||||||
bool = new Bool(language, scope);
|
bool = new Bool(language, scope);
|
||||||
error = new Error(language, scope);
|
error = new Error(language, scope);
|
||||||
|
array = new Array(language, scope);
|
||||||
function = new AtomConstructor("Function", scope).initializeFields();
|
function = new AtomConstructor("Function", scope).initializeFields();
|
||||||
text = new AtomConstructor("Text", scope).initializeFields();
|
text = new AtomConstructor("Text", scope).initializeFields();
|
||||||
debug = new AtomConstructor("Debug", scope).initializeFields();
|
debug = new AtomConstructor("Debug", scope).initializeFields();
|
||||||
@ -258,6 +261,10 @@ public class Builtins {
|
|||||||
return system;
|
return system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the container for array-related builtins. */
|
||||||
|
public Array array() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the builtin module scope.
|
* Returns the builtin module scope.
|
||||||
@ -275,10 +282,10 @@ public class Builtins {
|
|||||||
/**
|
/**
|
||||||
* Builds a function dispatching to a polyglot method call.
|
* 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.
|
* @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};
|
Object[] preAppliedArr = new Object[] {null, method, null};
|
||||||
return new Function(interopDispatchRoot, null, interopDispatchSchema, preAppliedArr, null);
|
return new Function(interopDispatchRoot, null, interopDispatchSchema, preAppliedArr, null);
|
||||||
}
|
}
|
||||||
|
@ -33,15 +33,17 @@ public class UnresolvedSymbol implements TruffleObject {
|
|||||||
/**
|
/**
|
||||||
* Gets the symbol name.
|
* 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
|
* @return the name of this symbol
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the scope this symbol was used in. */
|
||||||
|
public ModuleScope getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the symbol for a given hierarchy of constructors.
|
* 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.ArgumentDefinition;
|
||||||
import org.enso.interpreter.runtime.callable.argument.Thunk;
|
import org.enso.interpreter.runtime.callable.argument.Thunk;
|
||||||
import org.enso.interpreter.runtime.state.data.EmptyMap;
|
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.interpreter.runtime.type.Types;
|
||||||
import org.enso.polyglot.MethodNames;
|
import org.enso.polyglot.MethodNames;
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ public final class Function implements TruffleObject {
|
|||||||
*/
|
*/
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
Object getMembers(boolean includeInternal) {
|
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;
|
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.InteropLibrary;
|
||||||
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
||||||
import com.oracle.truffle.api.interop.TruffleObject;
|
import com.oracle.truffle.api.interop.TruffleObject;
|
||||||
import com.oracle.truffle.api.library.ExportLibrary;
|
import com.oracle.truffle.api.library.ExportLibrary;
|
||||||
import com.oracle.truffle.api.library.ExportMessage;
|
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)
|
@ExportLibrary(InteropLibrary.class)
|
||||||
public class Vector implements TruffleObject {
|
public class Array implements TruffleObject {
|
||||||
private final @CompilerDirectives.CompilationFinal(dimensions = 1) Object[] items;
|
private final Object[] items;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Vector
|
* Creates a new array
|
||||||
*
|
*
|
||||||
* @param items the element values
|
* @param items the element values
|
||||||
*/
|
*/
|
||||||
public Vector(Object... items) {
|
public Array(Object... items) {
|
||||||
this.items = 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() {
|
public Object[] getItems() {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
@ -57,7 +65,7 @@ public class Vector implements TruffleObject {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
public long getArraySize() {
|
long getArraySize() {
|
||||||
return items.length;
|
return items.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +76,22 @@ public class Vector implements TruffleObject {
|
|||||||
* @return {@code true} if the index is valid, {@code false} otherwise.
|
* @return {@code true} if the index is valid, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
public boolean isArrayElementReadable(long index) {
|
boolean isArrayElementReadable(long index) {
|
||||||
return index < getArraySize() && index >= 0;
|
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.Context;
|
||||||
import org.enso.interpreter.runtime.Module;
|
import org.enso.interpreter.runtime.Module;
|
||||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
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.interpreter.runtime.type.Types;
|
||||||
import org.enso.pkg.QualifiedName;
|
import org.enso.pkg.QualifiedName;
|
||||||
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.
|
* @return a collection of all the exported members.
|
||||||
*/
|
*/
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
Vector getMembers(boolean includeInternal) {
|
Array getMembers(boolean includeInternal) {
|
||||||
return new Vector(
|
return new Array(
|
||||||
MethodNames.TopScope.GET_MODULE,
|
MethodNames.TopScope.GET_MODULE,
|
||||||
MethodNames.TopScope.CREATE_MODULE,
|
MethodNames.TopScope.CREATE_MODULE,
|
||||||
MethodNames.TopScope.REGISTER_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.dsl.TypeSystem;
|
||||||
import com.oracle.truffle.api.interop.ArityException;
|
import com.oracle.truffle.api.interop.ArityException;
|
||||||
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
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.argument.Thunk;
|
||||||
import org.enso.interpreter.runtime.callable.atom.Atom;
|
import org.enso.interpreter.runtime.callable.atom.Atom;
|
||||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||||
import org.enso.interpreter.runtime.callable.function.Function;
|
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 org.enso.interpreter.runtime.error.RuntimeError;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class defines the interpreter-level type system for Enso.
|
* This class defines the interpreter-level type system for Enso.
|
||||||
*
|
*
|
||||||
@ -33,7 +32,8 @@ import java.util.Optional;
|
|||||||
AtomConstructor.class,
|
AtomConstructor.class,
|
||||||
Thunk.class,
|
Thunk.class,
|
||||||
RuntimeError.class,
|
RuntimeError.class,
|
||||||
Vector.class
|
UnresolvedSymbol.class,
|
||||||
|
Array.class
|
||||||
})
|
})
|
||||||
public class Types {
|
public class Types {
|
||||||
|
|
||||||
@ -118,8 +118,8 @@ public class Types {
|
|||||||
return "Thunk";
|
return "Thunk";
|
||||||
} else if (TypesGen.isRuntimeError(value)) {
|
} else if (TypesGen.isRuntimeError(value)) {
|
||||||
return "Error " + TypesGen.asRuntimeError(value).getPayload().toString();
|
return "Error " + TypesGen.asRuntimeError(value).getPayload().toString();
|
||||||
} else if (TypesGen.isVector(value)) {
|
} else if (TypesGen.isArray(value)) {
|
||||||
return "Vector";
|
return "Array";
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ class Passes(passes: Option[List[PassGroup]] = None) {
|
|||||||
TypeSignatures,
|
TypeSignatures,
|
||||||
AliasAnalysis,
|
AliasAnalysis,
|
||||||
UppercaseNames,
|
UppercaseNames,
|
||||||
|
VectorLiterals,
|
||||||
AliasAnalysis,
|
AliasAnalysis,
|
||||||
LambdaConsolidate,
|
LambdaConsolidate,
|
||||||
AliasAnalysis,
|
AliasAnalysis,
|
||||||
|
@ -1136,7 +1136,7 @@ class IrToTruffle(
|
|||||||
argumentExpression.setTail(argExpressionIsTail)
|
argumentExpression.setTail(argExpressionIsTail)
|
||||||
|
|
||||||
val displayName =
|
val displayName =
|
||||||
s"argument<${name.getOrElse(String.valueOf(position))}>"
|
s"argument<${name.map(_.name).getOrElse(String.valueOf(position))}>"
|
||||||
|
|
||||||
val section = value.location
|
val section = value.location
|
||||||
.map(loc => source.createSection(loc.start, loc.end))
|
.map(loc => source.createSection(loc.start, loc.end))
|
||||||
|
@ -5302,6 +5302,12 @@ object IR {
|
|||||||
def explain(originalName: IR.Name): String
|
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.
|
* An error coming from an unexpected occurence of a polyglot symbol.
|
||||||
*
|
*
|
||||||
|
@ -57,14 +57,13 @@ case class BindingsMap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def findLocalCandidates(name: String): List[ResolvedName] = {
|
private def findLocalCandidates(name: String): List[ResolvedName] = {
|
||||||
if (currentModule.getName.item == name) {
|
|
||||||
List(ResolvedModule(currentModule))
|
|
||||||
} else {
|
|
||||||
val conses = findConstructorCandidates(name)
|
val conses = findConstructorCandidates(name)
|
||||||
val polyglot = findPolyglotCandidates(name)
|
val polyglot = findPolyglotCandidates(name)
|
||||||
val methods = findMethodCandidates(name)
|
val methods = findMethodCandidates(name)
|
||||||
conses ++ polyglot ++ methods
|
val all = conses ++ polyglot ++ methods
|
||||||
}
|
if (all.isEmpty && currentModule.getName.item == name) {
|
||||||
|
List(ResolvedModule(currentModule))
|
||||||
|
} else { all }
|
||||||
}
|
}
|
||||||
|
|
||||||
private def findQualifiedImportCandidates(
|
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
|
X.method = 10
|
||||||
|
|
||||||
Main.main = Unit.util (X 1)
|
main = Unit.util (X 1)
|
||||||
|
@ -5,4 +5,4 @@ type X a
|
|||||||
|
|
||||||
X.method = 10
|
X.method = 10
|
||||||
|
|
||||||
Main.main = Unit.util (X 1)
|
main = Unit.util (X 1)
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from TestSimpleImports.Atom import all
|
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
|
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
|
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
|
import Test_Qualified_Error.Atom
|
||||||
|
|
||||||
Main.main = (X 1).method
|
main = (X 1).method
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
import Test_Rename.Atom as Def
|
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
|
import Test_Rename_Error.Atom as Def
|
||||||
|
|
||||||
Main.main = (Atom.X 1).method
|
main = (Atom.X 1).method
|
||||||
|
@ -856,7 +856,10 @@ class DataflowAnalysisTest extends CompilerTest {
|
|||||||
|
|
||||||
val depInfo = ir.getMetadata(DataflowAnalysis).get
|
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]
|
.asInstanceOf[IR.Application.Literal.Sequence]
|
||||||
|
|
||||||
val xDefId = mkStaticDep(ir.arguments(0).getId)
|
val xDefId = mkStaticDep(ir.arguments(0).getId)
|
||||||
@ -864,13 +867,17 @@ class DataflowAnalysisTest extends CompilerTest {
|
|||||||
val yId = mkStaticDep(vector.items(1).getId)
|
val yId = mkStaticDep(vector.items(1).getId)
|
||||||
val litId = mkStaticDep(vector.items(2).getId)
|
val litId = mkStaticDep(vector.items(2).getId)
|
||||||
val vecId = mkStaticDep(vector.getId)
|
val vecId = mkStaticDep(vector.getId)
|
||||||
|
val callArgId = mkStaticDep(callArg.getId)
|
||||||
|
val appId = mkStaticDep(ir.body.getId)
|
||||||
val lamId = mkStaticDep(ir.getId)
|
val lamId = mkStaticDep(ir.getId)
|
||||||
|
|
||||||
depInfo.getDirect(xDefId) shouldEqual Some(Set(xUseId))
|
depInfo.getDirect(xDefId) shouldEqual Some(Set(xUseId))
|
||||||
depInfo.getDirect(xUseId) shouldEqual Some(Set(vecId))
|
depInfo.getDirect(xUseId) shouldEqual Some(Set(vecId))
|
||||||
depInfo.getDirect(yId) shouldEqual Some(Set(vecId))
|
depInfo.getDirect(yId) shouldEqual Some(Set(vecId))
|
||||||
depInfo.getDirect(litId) 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 {
|
"work properly for typeset literals" in {
|
||||||
|
@ -150,6 +150,9 @@ class DemandAnalysisTest extends CompilerTest {
|
|||||||
val vec = ir
|
val vec = ir
|
||||||
.asInstanceOf[IR.Function.Lambda]
|
.asInstanceOf[IR.Function.Lambda]
|
||||||
.body
|
.body
|
||||||
|
.asInstanceOf[IR.Application.Prefix]
|
||||||
|
.arguments(0)
|
||||||
|
.value
|
||||||
.asInstanceOf[IR.Application.Literal.Sequence]
|
.asInstanceOf[IR.Application.Literal.Sequence]
|
||||||
|
|
||||||
vec.items(0) shouldBe an[IR.Application.Force]
|
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 idMain = metadata.addItem(32, 35)
|
||||||
val idMainA = metadata.addItem(41, 8)
|
val idMainA = metadata.addItem(41, 8)
|
||||||
val idMainP = metadata.addItem(54, 12)
|
val idMainP = metadata.addItem(54, 12)
|
||||||
val idPie = metadata.addItem(71 + 8, 1)
|
val idPie = metadata.addItem(66 + 8, 1)
|
||||||
val idUwu = metadata.addItem(84 + 8, 1)
|
val idUwu = metadata.addItem(74 + 8, 1)
|
||||||
val idHie = metadata.addItem(97 + 8, 6)
|
val idHie = metadata.addItem(82 + 8, 6)
|
||||||
val idXxx = metadata.addItem(117 + 8, 1)
|
val idXxx = metadata.addItem(102 + 8, 1)
|
||||||
val code =
|
val code =
|
||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
@ -1208,9 +1208,9 @@ class RuntimeServerTest
|
|||||||
| a = 123 + 21
|
| a = 123 + 21
|
||||||
| IO.println a
|
| IO.println a
|
||||||
|
|
|
|
||||||
|Main.pie = 3
|
|pie = 3
|
||||||
|Main.uwu = 7
|
|uwu = 7
|
||||||
|Main.hie = "hie!"
|
|hie = "hie!"
|
||||||
|Number.x y = y
|
|Number.x y = y
|
||||||
|""".stripMargin.linesIterator.mkString("\n")
|
|""".stripMargin.linesIterator.mkString("\n")
|
||||||
val contents = metadata.appendToCode(code)
|
val contents = metadata.appendToCode(code)
|
||||||
@ -1399,7 +1399,7 @@ class RuntimeServerTest
|
|||||||
Seq(
|
Seq(
|
||||||
TextEdit(
|
TextEdit(
|
||||||
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
||||||
"Main.pie"
|
"here.pie"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -1430,7 +1430,7 @@ class RuntimeServerTest
|
|||||||
Seq(
|
Seq(
|
||||||
TextEdit(
|
TextEdit(
|
||||||
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
||||||
"Main.uwu"
|
"here.uwu"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -1461,7 +1461,7 @@ class RuntimeServerTest
|
|||||||
Seq(
|
Seq(
|
||||||
TextEdit(
|
TextEdit(
|
||||||
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
model.Range(model.Position(3, 8), model.Position(3, 16)),
|
||||||
"Main.hie"
|
"here.hie"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package org.enso.interpreter.test.semantic
|
package org.enso.interpreter.test.semantic
|
||||||
import org.enso.interpreter.node.callable.function.CreateFunctionNode
|
import org.enso.interpreter.node.callable.function.CreateFunctionNode
|
||||||
import org.enso.interpreter.node.callable.thunk.ForceNode
|
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.controlflow.CaseNode
|
||||||
import org.enso.interpreter.node.expression.literal.IntegerLiteralNode
|
import org.enso.interpreter.node.expression.literal.IntegerLiteralNode
|
||||||
import org.enso.interpreter.node.scope.{AssignmentNode, ReadLocalVariableNode}
|
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
|
"be correct for negated literals" in
|
||||||
withLocationsInstrumenter { instrumenter =>
|
withLocationsInstrumenter { instrumenter =>
|
||||||
val code = "main = (-1)"
|
val code = "main = (-1)"
|
||||||
|
@ -14,8 +14,9 @@ class JavaInteropTest extends InterpreterTest {
|
|||||||
val code =
|
val code =
|
||||||
"""
|
"""
|
||||||
|polyglot java import org.enso.example.TestClass
|
|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
|
|""".stripMargin
|
||||||
|
|
||||||
eval(code) shouldEqual 3
|
eval(code) shouldEqual 3
|
||||||
@ -25,10 +26,11 @@ class JavaInteropTest extends InterpreterTest {
|
|||||||
val code =
|
val code =
|
||||||
"""
|
"""
|
||||||
|polyglot java import org.enso.example.TestClass
|
|polyglot java import org.enso.example.TestClass
|
||||||
|
|from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|main =
|
||||||
| instance = TestClass.new [x -> x * 2]
|
| instance = TestClass.new (Array.new_1 (x -> x * 2))
|
||||||
| instance.callFunctionAndIncrement [10]
|
| instance.callFunctionAndIncrement (Array.new_1 10)
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
eval(code) shouldEqual 21
|
eval(code) shouldEqual 21
|
||||||
}
|
}
|
||||||
|
@ -139,23 +139,6 @@ class LambdaShorthandArgsTest extends InterpreterTest {
|
|||||||
eval(code) shouldEqual 15
|
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 {
|
"work properly when used with dot notation" in {
|
||||||
val code =
|
val code =
|
||||||
"""
|
"""
|
||||||
|
@ -257,16 +257,5 @@ class NamedArgumentsTest extends InterpreterTest {
|
|||||||
|
|
||||||
eval(code) shouldEqual 10
|
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 =
|
|main =
|
||||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||||
| method = Polyglot.get_member class "add"
|
| method = Polyglot.get_member class "add"
|
||||||
| Polyglot.execute method [1, 2]
|
| Polyglot.execute method (Array.new_2 1 2)
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
eval(code) shouldEqual 3
|
eval(code) shouldEqual 3
|
||||||
@ -28,8 +28,8 @@ class PolyglotTest extends InterpreterTest {
|
|||||||
|
|
|
|
||||||
|main =
|
|main =
|
||||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||||
| instance = Polyglot.new class [x -> x * 2]
|
| instance = Polyglot.new class (Array.new_1 (x -> x * 2))
|
||||||
| Polyglot.invoke instance "callFunctionAndIncrement" [10]
|
| Polyglot.invoke instance "callFunctionAndIncrement" (Array.new_1 10)
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
eval(code) shouldEqual 21
|
eval(code) shouldEqual 21
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ class PolyglotTest extends InterpreterTest {
|
|||||||
|
|
|
|
||||||
|main =
|
|main =
|
||||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||||
| instance = Polyglot.new class []
|
| instance = Polyglot.new class Array.empty
|
||||||
| members = Polyglot.get_members instance
|
| members = Polyglot.get_members instance
|
||||||
| IO.println (Polyglot.get_array_size members)
|
| IO.println (Polyglot.get_array_size members)
|
||||||
| IO.println (Polyglot.get_array_element members 0)
|
| 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
|
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
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|main =
|
||||||
| result = System.create_process "echo" [] "" False False False
|
| result = System.create_process "echo" Array.empty "" False False False
|
||||||
| result.exit_code
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
eval(code) shouldEqual 0
|
eval(code) shouldEqual 0
|
||||||
@ -32,7 +32,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"return error when creating nonexistent command" in {
|
"return error when creating nonexistent command" in {
|
||||||
val code =
|
val code =
|
||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|main = System.create_process "nonexistentcommandxyz" [] "" False False False
|
|main = System.create_process "nonexistentcommandxyz" Array.empty "" False False False
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
val error = the[InterpreterException] thrownBy eval(code)
|
val error = the[InterpreterException] thrownBy eval(code)
|
||||||
@ -46,7 +46,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.stdout
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.stdout
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|main =
|
||||||
| result = System.create_process "echo" ["foobar"] "" False False False
|
| result = System.create_process "echo" (Array.new_1 "foobar") "" False False False
|
||||||
| result.stdout
|
| result.stdout
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.exit_code
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.stderr
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
|
|||||||
"""from Builtins import all
|
"""from Builtins import all
|
||||||
|
|
|
|
||||||
|main =
|
|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
|
| result.stderr
|
||||||
|""".stripMargin
|
|""".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.Bench_Utils
|
||||||
import Base.List
|
from Base import all
|
||||||
|
|
||||||
|
polyglot java import java.lang.Long
|
||||||
|
|
||||||
type Counter
|
type Counter
|
||||||
type Sum
|
type Sum
|
||||||
@ -10,6 +12,12 @@ sum_tco = sum_to ->
|
|||||||
res = summator 0 sum_to
|
res = summator 0 sum_to
|
||||||
res
|
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 =
|
sum_co_state_body =
|
||||||
n = State.get Counter
|
n = State.get Counter
|
||||||
acc = State.get Sum
|
acc = State.get Sum
|
||||||
@ -34,6 +42,8 @@ main =
|
|||||||
hundred_mil = 100000000
|
hundred_mil = 100000000
|
||||||
IO.println "Measuring SumTCO"
|
IO.println "Measuring SumTCO"
|
||||||
Bench_Utils.measure (here.sum_tco hundred_mil) "sum_tco" 100 10
|
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"
|
IO.println "Measuring State"
|
||||||
Bench_Utils.measure (here.sum_state hundred_mil) "sum_state" 100 10
|
Bench_Utils.measure (here.sum_state hundred_mil) "sum_state" 100 10
|
||||||
IO.println "Measuring Co-State"
|
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.Deep_Export_Spec
|
||||||
import Test.Names_Spec
|
import Test.Names_Spec
|
||||||
import Test.Process_Spec
|
import Test.Process_Spec
|
||||||
|
import Test.Java_Interop.Spec as Java_Spec
|
||||||
|
import Test.Vector.Spec as Vector_Spec
|
||||||
|
|
||||||
main = Test.Suite.runMain <|
|
main = Test.Suite.runMain <|
|
||||||
List_Spec.spec
|
List_Spec.spec
|
||||||
@ -13,3 +15,5 @@ main = Test.Suite.runMain <|
|
|||||||
Names_Spec.spec
|
Names_Spec.spec
|
||||||
Deep_Export_Spec.spec
|
Deep_Export_Spec.spec
|
||||||
Process_Spec.spec
|
Process_Spec.spec
|
||||||
|
Java_Spec.spec
|
||||||
|
Vector_Spec.spec
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from Base import all
|
||||||
import Base.Process
|
import Base.Process
|
||||||
from Base.Process.Exit_Code import Exit_Success, Exit_Failure
|
from Base.Process.Exit_Code import Exit_Success, Exit_Failure
|
||||||
import Base.System.Platform
|
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