Remove Array.new and Array.copy and move Vector functions to builtins. (#7147)

- Removed Array methods: `new`, `copy` and `new_[1234]`.
- New builtins for `Vector.insert`, `Vector.remove` and `Vector.flatten`.
- Replaced `Vector_Builder` use of `Array.copy` to a `Vector.Builder` approach.
This commit is contained in:
James Dunkerley 2023-07-03 13:41:41 +01:00 committed by GitHub
parent 4ccf3566ce
commit 4fbe7e3830
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 488 additions and 387 deletions

View File

@ -5,7 +5,6 @@ import project.Data.List.List
import project.Data.Ordering.Ordering
import project.Data.Sort_Direction.Sort_Direction
import project.Data.Pair.Pair
from project.Data.Range.Extensions import all
import project.Data.Range.Range
import project.Data.Text.Text
import project.Data.Vector.Vector
@ -15,113 +14,18 @@ import project.Errors.Common.Incomparable_Values
import project.Errors.Common.Not_Found
import project.Errors.Common.Index_Out_Of_Bounds
import project.Errors.Problem_Behavior.Problem_Behavior
import project.Errors.Unimplemented.Unimplemented
import project.Meta
import project.Nothing.Nothing
import project.Panic.Panic
from project.Data.Boolean import Boolean, False
from project.Data.Index_Sub_Range import Index_Sub_Range
from project.Data.Range.Extensions import all
## The type of primitive mutable arrays.
@Builtin_Type
type Array
## PRIVATE
ADVANCED
Creates an array with length 0.
> Example
Create an empty array.
Array.empty
empty : Array
empty = @Builtin_Method "Array.empty"
## PRIVATE
ADVANCED
Creates a new array of length size, with all elements uninitialized.
Arguments:
- size: The size of the array to create.
> Example
Create a new array of size 10.
Array.new 10
new : Integer -> Array
new size = @Builtin_Method "Array.new"
## PRIVATE
Create an array with one element provided.
Arguments:
- item_1: The one element in the array.
new_1 : Any -> Array
new_1 item_1 = @Builtin_Method "Array.new_1"
## PRIVATE
Create an array with two elements provided.
Arguments:
- item_1: The first element.
- item_2: The second element.
new_2 : Any -> Any -> Array
new_2 item_1 item_2 = @Builtin_Method "Array.new_2"
## PRIVATE
Create an array with three elements provided.
Arguments:
- item_1: The first element.
- item_2: The second element.
- item_3: The third element.
new_3 : Any -> Any -> Any -> Array
new_3 item_1 item_2 item_3 = @Builtin_Method "Array.new_3"
## PRIVATE
Create an array with four elements provided.
Arguments:
- item_1: The first element.
- item_2: The second element.
- item_3: The third element.
- item_4: The fourth element.
new_4 : Any -> Any -> Any -> Any -> Array
new_4 item_1 item_2 item_3 item_4 = @Builtin_Method "Array.new_4"
## PRIVATE
Copies from the source array, beginning at the specified position, to the
specified position in the destination array.
Arguments:
- src: The source array.
- source_index: The start position in the src array.
- dest: The destination array.
- dest_index: The start position in the that array.
A subsequence of array elements are copied from the src array to the
dest array. The number of components copied is equal to count. The
components at positions source_index through source_index + count - 1
in the src array are copied into positions dest_index through
dest_index + count - 1, respectively, of the destination array.
If the src and dest arguments refer to the same array, then the copy
is performed as if the components at positions source_index through
source_index + count - 1 are first copied to a temporary array with
length count, and then the contents of the temporary array are copied
into positions dest_index through dest_index + count - 1 of the
destination array.
> Example
Copying elements from one array to another.
Array.copy [1,2,3].to_array 0 (Vector.fill 3 0).to_array 0 3
copy : Array -> Integer -> Array -> Integer -> Integer -> Nothing
copy src source_index dest dest_index count = @Builtin_Method "Array.copy"
## Gets an element from the array at a specified index (0-based).
Arguments:
@ -593,6 +497,17 @@ type Array
map_with_index : (Integer -> Any -> Any) -> Vector Any
map_with_index self function = Vector.map_with_index self function
## Creates a new array with the skipping elements until `start` and then
continuing until `end` index.
Arguments:
- start: The index of the first element to include.
- end: The index to stop slicing at.
> Example
Remove the first 2 elements then continue until index 5 from the array.
[1, 2, 3, 4, 5, 6, 7, 8].to_array.slice 2 5 == [3, 4, 5].to_array
slice : Integer -> Integer -> Vector Any
slice self start end = Vector.slice self start end

View File

@ -233,7 +233,7 @@ type Filter_Condition
## PRIVATE
Creates a Single_Choice Widget for delimiters.
default_widget : Boolean -> Boolean -> Boolean -> Widget
default_widget : Boolean -> Boolean -> Boolean -> Boolean -> Widget
default_widget include_comparable=True include_text=True include_boolean=True include_nullable=True =
options_builder = Vector.new_builder
if include_comparable then

View File

@ -56,22 +56,22 @@ fit_least_squares : Vector -> Vector -> Model -> Fitted_Model ! Illegal_Argument
fit_least_squares known_xs known_ys model=Model.Linear =
Illegal_Argument.handle_java_exception <| Fit_Error.handle_java_exception <| case model of
Model.Linear intercept ->
fitted = if intercept.is_nothing then Regression.fit_linear known_xs.to_array known_ys.to_array else
Regression.fit_linear known_xs.to_array known_ys.to_array intercept
fitted = if intercept.is_nothing then Regression.fit_linear known_xs known_ys else
Regression.fit_linear known_xs known_ys intercept
Fitted_Model.Linear fitted.slope fitted.intercept fitted.rSquared
Model.Exponential intercept ->
log_ys = Model.ln_series known_ys "Y-values"
fitted = if intercept.is_nothing then Regression.fit_linear known_xs.to_array log_ys.to_array else
Regression.fit_linear known_xs.to_array log_ys.to_array intercept.ln
fitted = if intercept.is_nothing then Regression.fit_linear known_xs log_ys else
Regression.fit_linear known_xs log_ys intercept.ln
Model.fitted_model_with_r_squared Fitted_Model.Exponential fitted.intercept.exp fitted.slope known_xs known_ys
Model.Logarithmic ->
log_xs = Model.ln_series known_xs "X-values"
fitted = Regression.fit_linear log_xs.to_array known_ys.to_array
fitted = Regression.fit_linear log_xs known_ys
Model.fitted_model_with_r_squared Fitted_Model.Logarithmic fitted.slope fitted.intercept known_xs known_ys
Model.Power ->
log_xs = Model.ln_series known_xs "X-values"
log_ys = Model.ln_series known_ys "Y-values"
fitted = Regression.fit_linear log_xs.to_array log_ys.to_array
fitted = Regression.fit_linear log_xs log_ys
Model.fitted_model_with_r_squared Fitted_Model.Power fitted.intercept.exp fitted.slope known_xs known_ys
_ -> Error.throw (Illegal_Argument.Error "Unsupported model.")

View File

@ -65,7 +65,7 @@ type Rank_Method
Error.throw (Incomparable_Values.Error exc.payload.getLeftOperand exc.payload.getRightOperand)
handle_cmp_exc <| handle_nullpointer <|
java_ranks = Rank.rank input.to_array java_method
java_ranks = Rank.rank input java_method
Vector.from_polyglot_array java_ranks
type Statistic
@ -302,19 +302,19 @@ wrap_java_call ~function =
Given two series, get a computed CorrelationStatistics object
calculate_correlation_statistics : Vector -> Vector -> CorrelationStatistics
calculate_correlation_statistics x_data y_data =
wrap_java_call <| CorrelationStatistics.compute x_data.to_array y_data.to_array
wrap_java_call <| CorrelationStatistics.compute x_data y_data
## PRIVATE
Given two series, get a compute the Spearman Rank correlation
calculate_spearman_rank : Vector -> Vector -> Decimal
calculate_spearman_rank x_data y_data =
wrap_java_call <| CorrelationStatistics.spearmanRankCorrelation x_data.to_array y_data.to_array
wrap_java_call <| CorrelationStatistics.spearmanRankCorrelation x_data y_data
## PRIVATE
Given a set of series get CorrelationStatistics objects
calculate_correlation_statistics_matrix : Vector Vector -> Vector CorrelationStatistics
calculate_correlation_statistics_matrix data =
data_array = Vector.new data.length i->(data.at i).to_array . to_array
data_array = Vector.new data.length i->(data.at i).to_array
stats_array = wrap_java_call <| CorrelationStatistics.computeMatrix data_array
Vector.new stats_array.length i->(Vector.from_polyglot_array (stats_array.at i))

View File

@ -1,10 +1,8 @@
## Methods for operating on `Text` in Enso.
import project.Any.Any
import project.Data.Array.Array
import project.Data.Index_Sub_Range.Index_Sub_Range
import project.Data.Locale.Locale
from project.Data.Range.Extensions import all
import project.Data.Range.Range
import project.Data.Text.Case.Case
import project.Data.Text.Case_Sensitivity.Case_Sensitivity
@ -38,6 +36,7 @@ import project.Nothing.Nothing
from project.Data.Boolean import Boolean, True, False
from project.Data.Json import Json, Invalid_JSON, JS_Object
from project.Data.Numbers import Decimal, Integer, Number, Number_Parse_Error
from project.Data.Range.Extensions import all
from project.Widget_Helpers import make_delimiter_selector, make_date_format_selector, make_date_time_format_selector, make_time_format_selector
@ -473,8 +472,8 @@ Text.replace self term replacement case_sensitivity=Case_Sensitivity.Sensitive o
case use_regex of
False -> if term.is_empty then self else
array_from_single_result result = case result of
Nothing -> Array.empty
_ -> Array.new_1 result
Nothing -> []
_ -> [result]
spans_array = case case_sensitivity of
Case_Sensitivity.Sensitive -> case only_first of
False -> Text_Utils.span_of_all self term
@ -673,7 +672,7 @@ Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning =
@encoding Encoding.default_widget
Text.from_bytes : Vector Integer -> Encoding -> Problem_Behavior -> Text
Text.from_bytes bytes encoding on_problems=Problem_Behavior.Report_Error =
result = Encoding_Utils.from_bytes bytes.to_array (encoding . to_java_charset)
result = Encoding_Utils.from_bytes bytes (encoding . to_java_charset)
if result.warnings.is_nothing then result.result else
on_problems.attach_problems_after result.result [Encoding_Error.Error result.warnings]
@ -736,7 +735,7 @@ Text.char_vector self = Vector.from_polyglot_array (Text_Utils.get_chars self)
This is useful for low-level operations, such as binary data encoding and
decoding.
Text.from_char_vector : Vector Integer -> Text
Text.from_char_vector chars = Text_Utils.from_chars chars.to_array
Text.from_char_vector chars = Text_Utils.from_chars chars
## Returns a vector containing integers representing the Unicode codepoints of
the input text.
@ -761,7 +760,7 @@ Text.codepoints self = Vector.from_polyglot_array (Text_Utils.get_codepoints sel
Converting a vector of codepoints back into a text.
Text.from_codepoints [129318, 127996, 8205, 9794, 65039]
Text.from_codepoints : Vector Integer -> Text
Text.from_codepoints codepoints = Text_Utils.from_codepoints codepoints.to_array
Text.from_codepoints codepoints = Text_Utils.from_codepoints codepoints
## ALIAS Check Prefix
@ -1301,7 +1300,7 @@ Text.locate_all self term="" case_sensitivity=Case_Sensitivity.Sensitive = if te
Case_Sensitivity.Default -> self.locate term Case_Sensitivity.Sensitive
Case_Sensitivity.Sensitive ->
codepoint_spans = Vector.from_polyglot_array <| Text_Utils.span_of_all self term
grahpeme_ixes = Vector.from_polyglot_array <| Text_Utils.utf16_indices_to_grapheme_indices self (codepoint_spans.map .codeunit_start).to_array
grahpeme_ixes = Vector.from_polyglot_array <| Text_Utils.utf16_indices_to_grapheme_indices self (codepoint_spans.map .codeunit_start)
## While the codepoint_spans may have different code unit lengths
from our term, the `length` counted in grapheme clusters is
guaranteed to be the same.

View File

@ -161,7 +161,7 @@ type Utf_16_Span
grapheme_ix = Text_Utils.utf16_index_to_grapheme_index self.parent self.start
Span.Value (grapheme_ix.up_to grapheme_ix) self.parent
False ->
grapheme_ixes = Text_Utils.utf16_indices_to_grapheme_indices self.parent [self.start, self.end - 1].to_array
grapheme_ixes = Text_Utils.utf16_indices_to_grapheme_indices self.parent [self.start, self.end - 1]
grapheme_first = grapheme_ixes.at 0
grapheme_last = grapheme_ixes.at 1
## We find the grapheme index of the last code unit actually contained within our span and set the

View File

@ -24,14 +24,11 @@ import project.Panic.Panic
import project.Random
import project.Warning.Warning
from project.Data.Range.Extensions import all
## We have to import also conversion methods, therefore, we import all from the Ordering
module
from project.Data.Ordering import all
from project.Data.Boolean import Boolean, True, False
from project.Data.Index_Sub_Range import Index_Sub_Range, take_helper, drop_helper
from project.Data.Filter_Condition import unify_condition_or_predicate, unify_condition_predicate_or_element
from project.Data.Index_Sub_Range import Index_Sub_Range, take_helper, drop_helper
from project.Data.Ordering import all
from project.Data.Range.Extensions import all
polyglot java import java.lang.IndexOutOfBoundsException
polyglot java import org.enso.base.Array_Builder
@ -568,13 +565,7 @@ type Vector a
[[1, 2, 3], [4, 10], [], [0], [0]] . flatten == [1, 2, 3, 4, 10, 0, 0]
flatten : Vector Any
flatten self =
length = self.fold 0 acc-> elem-> acc + elem.length
arr = Array.new length
self.fold 0 i-> vec->
Array.copy vec.to_array 0 arr i vec.length
i + vec.length
Vector.from_polyglot_array arr
flatten self = @Builtin_Method "Vector.flatten"
## Applies a function to each element of the vector, returning the `Vector`
of results.
@ -691,13 +682,7 @@ type Vector a
[1] + [2]
+ : Vector Any -> Vector Any
+ self that = case that of
_ : Vector ->
self_len = self.length
that_len = that.length
arr = Array.new (self_len + that_len)
Array.copy self.to_array 0 arr 0 self_len
Array.copy that.to_array 0 arr self_len that_len
Vector.from_polyglot_array arr
_ : Vector -> Vector.insert_builtin self self.length that
_ : Array -> self + Vector.from_polyglot_array that
_ -> Error.throw (Type_Error.Error Vector that "that")
@ -723,11 +708,10 @@ type Vector a
if used_index < 0 || used_index > self_len then Error.throw (Index_Out_Of_Bounds.Error at self_len+1) else
if used_index == self_len then self + [item] else
if used_index == 0 then [item] + self else
arr = Array.new (self_len + 1)
Array.copy self.to_array 0 arr 0 used_index
Array.copy [item].to_array 0 arr used_index 1
Array.copy self.to_array used_index arr (used_index + 1) (self_len - used_index)
Vector.from_polyglot_array arr
Vector.insert_builtin self used_index [item]
## PRIVATE
insert_builtin vec at values = @Builtin_Method("Vector.insert_builtin")
## Removes the item at the given index from the vector.
@ -740,10 +724,10 @@ type Vector a
self_len = self.length
used_index = if at < 0 then self_len + at else at
if used_index >= self_len || used_index < 0 then Error.throw (Index_Out_Of_Bounds.Error at self_len) else
arr = Array.new (self_len - 1)
Array.copy self.to_array 0 arr 0 used_index
Array.copy self.to_array (used_index + 1) arr used_index (self_len - used_index - 1)
Vector.from_polyglot_array arr
Vector.remove_builtin self used_index
## PRIVATE
remove_builtin vec at = @Builtin_Method "Vector.remove_builtin"
## When `self` is a vector of text values, concatenates all the values by
interspersing them with `separator`.
@ -763,8 +747,7 @@ type Vector a
if self.length == 1 then prefix + self.at 0 + suffix else
prefix + self.at 0 + (1.up_to self.length . fold "" acc-> i-> acc + separator + self.at i) + suffix
## PRIVATE
Creates a new vector with the skipping elements until `start` and then
## Creates a new vector with the skipping elements until `start` and then
continuing until `end` index.
Arguments:
@ -1113,7 +1096,7 @@ type Builder
## This workaround is needed because
`self.java_builder.addAll subrange.to_array` fails with
`Unsupported argument types: [Array]`.
append_result = self.java_builder.appendTo subrange.to_array
append_result = self.java_builder.appendTo subrange
append_result.if_not_error self
## PRIVATE

View File

@ -136,7 +136,7 @@ type Constructor
new : Vector -> Any
new self fields =
ctor = self.value ...
new_atom ctor fields.to_array
new_atom ctor fields
## ADVANCED
Returns the type that this constructor is a part of.

View File

@ -451,7 +451,7 @@ type HTTP
add_urlencoded form
Request_Body.Bytes bytes ->
builder.header Header.application_octet_stream.name Header.application_octet_stream.value
Pair.new req (body_publishers.ofByteArray bytes.to_array)
Pair.new req (body_publishers.ofByteArray bytes)
# method
req_http_method = req.method.to_http_method_name
case req_with_body of

View File

@ -76,7 +76,7 @@ type Random_Number_Generator
returns a random permutation of the input vector.
sample : Vector Any -> Integer -> Random_Number_Generator -> Vector Any
sample vector k rng =
new_array = Random_Utils.sample vector.to_array k rng.java_random
new_array = Random_Utils.sample vector k rng.java_random
Vector.from_polyglot_array new_array
## PRIVATE

View File

@ -149,7 +149,7 @@ type File
new_output_stream file open_options =
opts = open_options . map (_.to_java) . to_array
stream = File_Error.handle_java_exceptions file <|
file.output_stream_builtin opts
file.output_stream_builtin opts.to_array
## We re-wrap the File Not Found error to return the parent directory
instead of the file itself - because the file that is being written
may not exist and it will not be an error, it is the parent directory
@ -330,7 +330,7 @@ type File
## PRIVATE
Internal method to join two path segments together.
resolve : File
resolve : Text -> File
resolve self subpath = @Builtin_Method "File.resolve"
## PRIVATE
@ -565,9 +565,9 @@ type File
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File copying is forbidden as the Output context is disabled.") else
File_Error.handle_java_exceptions self <| case replace_existing of
True ->
copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array
self.copy_builtin destination copy_options
False -> self.copy_builtin destination Array.empty
copy_options = [StandardCopyOption.REPLACE_EXISTING]
self.copy_builtin destination copy_options.to_array
False -> self.copy_builtin destination [].to_array
## Moves the file to the specified destination.
@ -580,9 +580,9 @@ type File
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File moving is forbidden as the Output context is disabled.") else
File_Error.handle_java_exceptions self <| case replace_existing of
True ->
copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array
self.move_builtin destination copy_options
False -> self.move_builtin destination Array.empty
copy_options = [StandardCopyOption.REPLACE_EXISTING]
self.move_builtin destination copy_options.to_array
False -> self.move_builtin destination [].to_array
## Deletes the file if it exists on disk.
@ -612,7 +612,7 @@ type File
new_input_stream self open_options =
if self.is_directory then Error.throw (File_Error.IO_Error self "File '"+self.path+"' is a directory") else
opts = open_options . map (_.to_java) . to_array
stream = File_Error.handle_java_exceptions self (self.input_stream opts)
stream = File_Error.handle_java_exceptions self (self.input_stream opts.to_array)
resource = Managed_Resource.register stream close_stream
Input_Stream.Value self resource
@ -759,7 +759,7 @@ type Output_Stream
write_bytes : Vector File_Access -> Nothing ! File_Error
write_bytes self contents = self.stream_resource . with java_stream->
File_Error.handle_java_exceptions self.file <|
java_stream.write contents.to_array
java_stream.write contents
java_stream.flush
Nothing
@ -810,7 +810,7 @@ type Output_Stream
the `?` character.
replacement_sequence = Encoding_Utils.INVALID_CHARACTER.bytes encoding on_problems=Problem_Behavior.Ignore
java_charset = encoding.to_java_charset
results = Encoding_Utils.with_stream_encoder java_stream java_charset replacement_sequence.to_array action
results = Encoding_Utils.with_stream_encoder java_stream java_charset replacement_sequence action
problems = Vector.from_polyglot_array results.problems . map Encoding_Error.Error
on_problems.attach_problems_after results.result problems

View File

@ -99,7 +99,7 @@ Vector.write_bytes : (File|Text) -> Existing_File_Behavior -> File ! Illegal_Arg
Vector.write_bytes self path on_existing_file=Existing_File_Behavior.Backup =
Panic.catch Unsupported_Argument_Types handler=(_ -> Error.throw (Illegal_Argument.Error "Only Vectors consisting of bytes (integers in the range from -128 to 127) are supported by the `write_bytes` method.")) <|
## Convert to a byte array before writing - and fail early if there is any problem.
byte_array = Array_Builder.ensureByteArray self.to_array
byte_array = Array_Builder.ensureByteArray self
file = File.new path
r = on_existing_file.write file stream->

View File

@ -71,7 +71,7 @@ type Process_Builder
with_args.create
create : Process_Result
create self =
result = System.create_process self.command self.arguments.to_array self.stdin redirect_in=(self.stdin == False) redirect_out=False redirect_err=False
result = System.create_process self.command self.arguments self.stdin redirect_in=(self.stdin == False) redirect_out=False redirect_err=False
exit_code = Exit_Code.from_number result.exit_code
Process_Result.Value exit_code result.stdout result.stderr

View File

@ -76,7 +76,7 @@ type Warning
- value: the value to which warnings should be set to.
- warnings: vector of warnings to set to the value.
set : Any -> Vector Warning -> Any
set value warnings = set_array value warnings.to_array
set value warnings = set_array value warnings
## PRIVATE
ADVANCED

View File

@ -644,7 +644,7 @@ type Column
## PRIVATE
Round a float-like column using the backend's builtin ROUND function.
round_builtin : Integer -> Boolean -> Column
round_builtin : Integer -> Column
round_builtin self decimal_places =
new_name = self.naming_helpers.function_name "round" [self]
case decimal_places == 0 of

View File

@ -40,7 +40,7 @@ type Image
Image.from_vector [0, 0, 0, 0, 0, 0] rows=2 channels=1
from_vector : Vector -> Integer -> Integer -> Image
from_vector values rows=1 channels=1 =
Image.Value (Java_Image.from_vector values.to_array rows channels)
Image.Value (Java_Image.from_vector values rows channels)
## UNSTABLE
@ -105,7 +105,7 @@ type Image
write_flags = case flags of
_ : Vector -> flags
_ -> [flags]
int_flags = MatOfInt.new (write_flags.flat_map x-> [x.to_integer, x.value]).to_array
int_flags = MatOfInt.new (write_flags.flat_map x-> [x.to_integer, x.value])
Panic.catch JException (Java_Codecs.write path self.opencv_mat int_flags) _->
Error.throw (File_Error.IO_Error (File.new path) 'Failed to write to the file')
@ -435,12 +435,10 @@ core_op : Mat -> Any -> (Mat -> Scalar -> Mat -> Nothing) -> Nothing
core_op mat value function =
result = Mat.new
scalar = case value of
_ : Vector ->
Scalar.new value.to_array
_ : Vector -> Scalar.new value
Matrix.Value m ->
if ((m.rows == mat.rows) && (m.cols == mat.cols) && (m.channels == mat.channels)) then m else Panic.throw Matrix_Error.Dimensions_Not_Equal
_ ->
Scalar.all value
_ -> Scalar.all value
function mat scalar result
Image.Value result

View File

@ -94,7 +94,7 @@ type Matrix
example_from_vector = Matrix.from_vector [1, 1, 0, 0] rows=2
from_vector : Vector -> Integer -> Integer -> Matrix
from_vector values rows=1 channels=1 =
Matrix.Value (Java_Matrix.from_vector values.to_array channels rows)
Matrix.Value (Java_Matrix.from_vector values channels rows)
## Return the number of matrix rows.
@ -397,7 +397,7 @@ core_op mat value function =
result = Mat.new
scalar = case value of
_ : Vector ->
Scalar.new value.to_array
Scalar.new value
Matrix.Value m ->
if ((m.rows == mat.rows) && (m.cols == mat.cols) && (m.channels == mat.channels)) then m else Panic.throw Matrix_Error.Dimensions_Not_Equal
_ ->

View File

@ -47,7 +47,7 @@ type Column
from_vector : Text -> Vector -> Column
from_vector name items =
Illegal_Argument.handle_java_exception <|
Column.Value (Java_Column.fromItems name items.to_array)
Column.Value (Java_Column.fromItems name items)
## PRIVATE
Creates a new column given a name and an internal Java storage.
@ -67,7 +67,7 @@ type Column
from_vector_repeated : Text -> Vector -> Integer -> Column
from_vector_repeated name items repeats =
Illegal_Argument.handle_java_exception <|
Column.Value (Java_Column.fromRepeatedItems name items.to_array repeats)
Column.Value (Java_Column.fromRepeatedItems name items repeats)
## PRIVATE
@ -1783,7 +1783,7 @@ type Column
Sort_Direction.Ascending -> True
Sort_Direction.Descending -> False
rule = OrderBuilder.OrderRule.new self.java_column order_bool missing_last
mask = OrderBuilder.buildOrderMask [rule].to_array
mask = OrderBuilder.buildOrderMask [rule]
new_col = self.java_column.applyMask mask
Column.Value new_col
_ ->
@ -2046,7 +2046,7 @@ normalize_string_for_display string =
A helper to create a new table consisting of slices of the original table.
slice_ranges column ranges =
normalized = Index_Sub_Range_Module.normalize_ranges ranges
Column.Value (column.java_column.slice normalized.to_array)
Column.Value (column.java_column.slice normalized)
## PRIVATE
Creates a storage builder suitable for building a column for the provided

View File

@ -186,22 +186,22 @@ type Data_Formatter
## PRIVATE
make_boolean_parser self = self.wrap_base_parser <|
BooleanParser.new self.true_values.to_array self.false_values.to_array
BooleanParser.new self.true_values self.false_values
## PRIVATE
make_date_parser self = self.wrap_base_parser <|
Panic.catch Any handler=(caught_panic-> Error.throw (Illegal_Argument.Error caught_panic.payload.getMessage)) <|
DateParser.new self.date_formats.to_array self.datetime_locale.java_locale
DateParser.new self.date_formats self.datetime_locale.java_locale
## PRIVATE
make_date_time_parser self = self.wrap_base_parser <|
Panic.catch Any handler=(caught_panic-> Error.throw (Illegal_Argument.Error caught_panic.payload.getMessage)) <|
DateTimeParser.new self.datetime_formats.to_array self.datetime_locale.java_locale
DateTimeParser.new self.datetime_formats self.datetime_locale.java_locale
## PRIVATE
make_time_of_day_parser self = self.wrap_base_parser <|
Panic.catch Any handler=(caught_panic-> Error.throw (Illegal_Argument.Error caught_panic.payload.getMessage)) <|
TimeOfDayParser.new self.time_formats.to_array self.datetime_locale.java_locale
TimeOfDayParser.new self.time_formats self.datetime_locale.java_locale
## PRIVATE
make_identity_parser self = self.wrap_base_parser IdentityParser.new
@ -242,7 +242,7 @@ type Data_Formatter
## PRIVATE
make_auto_parser self =
fallback_parser = self.make_identity_parser
TypeInferringParser.new self.get_specific_type_parsers.to_array fallback_parser
TypeInferringParser.new self.get_specific_type_parsers fallback_parser
## PRIVATE
make_integer_formatter self =
@ -289,7 +289,7 @@ type Data_Formatter
make_auto_formatter self =
# TODO The panic rethrow+recover is a workaround for the vector error propagation bug.
formatters = Panic.recover Illegal_Argument (self.get_specific_type_formatters.map Panic.rethrow)
AnyObjectFormatter.new formatters.to_array
AnyObjectFormatter.new formatters
## PRIVATE
make_formatter_for_column_type self (column_type : Value_Type) = case column_type of

View File

@ -28,7 +28,7 @@ type Expression
handle_arguments = handle_java_error IllegalArgumentException Expression_Error.Argument_Mismatch
handle_parse_error <| handle_unsupported <| handle_arguments <|
ExpressionVisitorImpl.evaluate expression get_column make_constant module_name type_name var_args_functions.to_array
ExpressionVisitorImpl.evaluate expression get_column make_constant module_name type_name var_args_functions
type Expression_Error
## PRIVATE

View File

@ -91,7 +91,7 @@ type Table
if cols.is_empty then Error.throw (Illegal_Argument.Error "Cannot create a table with no columns.") else
if (cols.all c-> c.getSize == cols.first.getSize).not then Error.throw (Illegal_Argument.Error "All columns must have the same row count.") else
if cols.distinct .getName . length != cols.length then Error.throw (Illegal_Argument.Error "Column names must be distinct.") else
Table.Value (Java_Table.new cols.to_array)
Table.Value (Java_Table.new cols)
## Creates a new table from a vector of column names and a vector of vectors
specifying row contents.
@ -595,11 +595,11 @@ type Table
on_problems.attach_problems_before validated.problems <| Illegal_Argument.handle_java_exception <|
java_key_columns = validated.key_columns.map .java_column
index = self.java_table.indexFromColumns java_key_columns.to_array
index = self.java_table.indexFromColumns java_key_columns
new_columns = validated.valid_columns.map c->(Aggregate_Column_Helper.java_aggregator c.first c.second)
java_table = index.makeTable new_columns.to_array
java_table = index.makeTable new_columns
new_table = Table.Value java_table
on_problems.attach_problems_after new_table <|
@ -689,7 +689,7 @@ type Table
Case_Sensitivity.Insensitive locale -> ObjectComparator.new False locale.java_locale
java_table = Illegal_Argument.handle_java_exception <| Incomparable_Values.handle_errors <|
self.java_table.orderBy java_columns.to_array directions.to_array comparator
self.java_table.orderBy java_columns directions comparator
Table.Value java_table
## Returns the distinct set of rows within the specified columns from the
@ -735,7 +735,7 @@ type Table
java_columns = key_columns.map .java_column
text_folding_strategy = Case_Sensitivity.folding_strategy case_sensitivity
java_table = Illegal_Argument.handle_java_exception <|
self.java_table.distinct java_columns.to_array text_folding_strategy
self.java_table.distinct java_columns text_folding_strategy
on_problems.attach_problems_after (Table.Value java_table) <|
problems = java_table.getProblems
Java_Problems.parse_aggregated_problems problems
@ -1796,7 +1796,7 @@ type Table
java_id = id_columns.map .java_column
unique.mark_used (id_columns.map .name)
result = Table.Value (Java_Table.transpose java_id.to_array java_data.to_array (unique.make_unique attribute_column_name) (unique.make_unique value_column_name))
result = Table.Value (Java_Table.transpose java_id java_data (unique.make_unique attribute_column_name) (unique.make_unique value_column_name))
problem_builder.report_unique_name_strategy unique
problem_builder.attach_problems_after on_problems result
@ -1884,7 +1884,7 @@ type Table
problem_builder.attach_problems_before on_problems <| Illegal_Argument.handle_java_exception <|
java_key_columns = grouping.map .java_column
index = self.java_table.indexFromColumns java_key_columns.to_array
index = self.java_table.indexFromColumns java_key_columns
name_mapper = if matched_name.is_empty then Aggregate_Column_Helper.default_aggregate_column_name else
if validated_values.length == 1 then (_ -> "") else
@ -1900,7 +1900,7 @@ type Table
result = case matched_name.is_empty of
True ->
group_by = grouping.map g->(Aggregate_Column_Helper.java_aggregator g.name (Aggregate_Column.Group_By g))
index.makeTable (group_by + data_columns).to_array
index.makeTable (group_by + data_columns)
False ->
aggregate_names = validated_values.map c->
c.new_name.if_nothing (name_mapper c)
@ -2080,7 +2080,7 @@ print_table header rows indices_count format_term =
A helper to create a new table consisting of slices of the original table.
slice_ranges table ranges =
normalized = Index_Sub_Range_Module.normalize_ranges ranges
Table.Value (table.java_table.slice normalized.to_array)
Table.Value (table.java_table.slice normalized)
## PRIVATE
make_join_helpers left_table right_table =

View File

@ -103,5 +103,5 @@ make_grouped_ordered_enumeration name grouping_columns ordering from step =
enum_value = nth_index from step enum_ix
long_array.set row_ix enum_value
storage = LongStorage.fromArray long_array.to_array
storage = LongStorage.fromArray long_array
Column.from_storage name storage

View File

@ -220,7 +220,7 @@ java_aggregator name column =
Count _ -> CountAggregator.new name
Count_Distinct columns _ ignore_nothing ->
resolved = columns.map .java_column
CountDistinctAggregator.new name resolved.to_array ignore_nothing
CountDistinctAggregator.new name resolved ignore_nothing
Count_Not_Nothing c _ -> CountNothingAggregator.new name c.java_column False
Count_Nothing c _ -> CountNothingAggregator.new name c.java_column True
Count_Not_Empty c _ -> CountEmptyAggregator.new name c.java_column False
@ -235,12 +235,12 @@ java_aggregator name column =
if ordering.is_nothing then FirstAggregator.new name c.java_column ignore_nothing else
order_columns = ordering.map c->c.column.java_column
order_directions = ordering.map c->c.direction.to_sign
FirstAggregator.new name c.java_column ignore_nothing order_columns.to_array order_directions.to_array
FirstAggregator.new name c.java_column ignore_nothing order_columns order_directions
Last c _ ignore_nothing ordering ->
if ordering.is_nothing then LastAggregator.new name c.java_column ignore_nothing else
order_columns = ordering.map c->c.column.java_column
order_direction = ordering.map c->c.direction.to_sign
LastAggregator.new name c.java_column ignore_nothing order_columns.to_array order_direction.to_array
LastAggregator.new name c.java_column ignore_nothing order_columns order_direction
Maximum c _ -> MinOrMaxAggregator.new name c.java_column MinOrMaxAggregator.MAX
Minimum c _ -> MinOrMaxAggregator.new name c.java_column MinOrMaxAggregator.MIN
Shortest c _ -> ShortestOrLongestAggregator.new name c.java_column ShortestOrLongestAggregator.SHORTEST

View File

@ -118,10 +118,10 @@ prepare_reader java_reader format max_columns on_problems newline_override=Nothi
QuoteStrippingParser.new quote
value_parser = if format.value_formatter.is_nothing then base_parser else
wrapped = format.value_formatter.wrap_base_parser base_parser
TypeInferringParser.new format.value_formatter.get_specific_type_parsers.to_array wrapped
TypeInferringParser.new format.value_formatter.get_specific_type_parsers wrapped
cell_type_guesser = if format.headers != Infer then Nothing else
formatter = format.value_formatter.if_nothing Data_Formatter.Value
TypeInferringParser.new formatter.get_specific_type_parsers.to_array IdentityParser.new
TypeInferringParser.new formatter.get_specific_type_parsers IdentityParser.new
newline = newline_override.if_nothing <| case format.line_endings of
Infer -> Nothing
endings -> endings.to_text

View File

@ -70,7 +70,7 @@ append_to_file table format file match_columns on_problems =
Nothing -> table.java_table
Detected_Headers.Existing column_names -> case match_columns of
Match_Columns.By_Name ->
ColumnMapper.mapColumnsByName table.java_table column_names.to_array
ColumnMapper.mapColumnsByName table.java_table column_names
Match_Columns.By_Position ->
column_count = column_names.length
ColumnMapper.mapColumnsByPosition table.java_table column_count
@ -156,7 +156,7 @@ write_to_writer table format java_writer separator_override=Nothing needs_leadin
endings -> endings.to_text
if needs_leading_newline then
java_writer.write newline
writer = DelimitedWriter.new java_writer column_formatters.to_array format.delimiter newline quote_characters.first quote_characters.second format.comment_character quote_behavior write_headers
writer = DelimitedWriter.new java_writer column_formatters format.delimiter newline quote_characters.first quote_characters.second format.comment_character quote_behavior write_headers
writer.write table.java_table
warnings = Java_Problems.parse_aggregated_problems writer.getReportedWarnings
Problem_Behavior.Report_Warning.attach_problems_after Nothing warnings

View File

@ -55,16 +55,14 @@ type Vector_Builder
Materializes the actual vector from this builder.
build : Vector Any
build self =
array = Array.new self.length
go ix elem = case elem of
Leaf vec ->
Array.copy vec.to_array 0 array ix vec.length
ix + vec.length
vec_builder = Vector.new_builder self.length
go elem = case elem of
Leaf vec -> vec_builder.append_vector_range vec
Append l r _ ->
ix2 = go ix l
go ix2 r
go 0 self
Vector.from_polyglot_array array
go l
go r
go self
vec_builder.to_vector
## PRIVATE

View File

@ -549,5 +549,6 @@ Any.should_not_contain self element frames_to_skip=0 =
rules of the particular type - be it a `Vector`, `Text` or any custom type
implementing a method `contains : a -> Boolean`.
Error.should_not_contain : Any -> Integer -> Test_Result
Error.should_not_contain self _ frames_to_skip=0 =
Error.should_not_contain self element frames_to_skip=0 =
_ = [element]
Test.fail_match_on_unexpected_error self 1+frames_to_skip

View File

@ -333,13 +333,13 @@ class BuiltinTypesTest
val requestId = UUID.randomUUID()
val metadata = new Metadata
val idMain = metadata.addItem(45, 19)
val idMain = metadata.addItem(40, 18)
val code =
"""import Standard.Base.Data.Array.Array
"""from Standard.Base import Vector
|
|main =
| Array.new_1 42
| [42].to_array
|""".stripMargin.linesIterator.mkString("\n")
val contents = metadata.appendToCode(code)
@ -359,13 +359,13 @@ class BuiltinTypesTest
val requestId = UUID.randomUUID()
val metadata = new Metadata
val idMain = metadata.addItem(47, 34)
val idMain = metadata.addItem(40, 7)
val code =
"""from Standard.Base import Vector, Array
"""from Standard.Base import Vector
|
|main =
| Vector.from_array Array.empty
| []
|""".stripMargin.linesIterator.mkString("\n")
val contents = metadata.appendToCode(code)

View File

@ -0,0 +1,112 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CopyNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
type = "Vector",
name = "flatten",
description = "Flattens a vector of vectors into a single vector.",
autoRegister = false)
public abstract class FlattenVectorNode extends Node {
static FlattenVectorNode build() {
return FlattenVectorNodeGen.create();
}
abstract Vector execute(Object self);
@Specialization
Vector fromVector(
Vector self, @Cached CopyNode copyNode, @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return flatten(self.toArray(), copyNode, interop);
} catch (UnsupportedMessageException e) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeTypeError(builtins.vector(), self, "self"), this);
}
}
@Specialization
Vector fromArray(
Array self, @Cached CopyNode copyNode, @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return flatten(self, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(self);
}
}
@Specialization(guards = "interop.hasArrayElements(self)")
Vector fromArrayLike(
Object self, @Cached CopyNode copyNode, @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return flatten(self, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(self);
}
}
@Fallback
Vector fromUnknown(Object self) {
throw unsupportedException(self);
}
private PanicException unsupportedException(Object self) {
CompilerDirectives.transferToInterpreter();
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", self, "self");
throw new PanicException(err, this);
}
private Vector flatten(Object storage, CopyNode copyNode, InteropLibrary interop)
throws UnsupportedMessageException {
try {
long length = interop.getArraySize(storage);
long flattened_length = 0;
for (long i = 0; i < length; i++) {
var item = interop.readArrayElement(storage, i);
if (!interop.hasArrayElements(item)) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeTypeError(builtins.vector(), item, "[" + i + "]"), this);
}
flattened_length += interop.getArraySize(item);
}
Array result = Array.allocate(flattened_length);
long current_index = 0;
for (long i = 0; i < length; i++) {
var item = interop.readArrayElement(storage, i);
var item_length = interop.getArraySize(item);
copyNode.execute(item, 0, result, current_index, item_length);
current_index += item_length;
}
return Vector.fromArray(result);
} catch (InvalidArrayIndexException e) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeInvalidArrayIndex(storage, e.getInvalidIndex()), this);
}
}
}

View File

@ -0,0 +1,114 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CopyNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
type = "Vector",
name = "insert_builtin",
description = "Inserts a set of values into the Vector at the specified index.",
autoRegister = false)
public abstract class InsertBuiltinVectorNode extends Node {
static InsertBuiltinVectorNode build() {
return InsertBuiltinVectorNodeGen.create();
}
abstract Vector execute(Object vec, long index, Object values);
@Specialization
Vector fromVector(
Vector vec,
long index,
Vector values,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec.toArray(), index, values.toArray(), copyNode, interop);
}
@Specialization
Vector fromArray(
Array vec,
long index,
Vector values,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values.toArray(), copyNode, interop);
}
@Specialization(guards = "interop.hasArrayElements(vec)")
Vector fromArrayLike(
Object vec,
long index,
Vector values,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values.toArray(), copyNode, interop);
}
@Specialization(guards = "interop.hasArrayElements(values)")
Vector fromVectorWithArrayLikeObject(
Vector vec,
long index,
Object values,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec.toArray(), index, values, copyNode, interop);
}
@Specialization(guards = "interop.hasArrayElements(values)")
Vector fromArrayWithArrayLikeObject(
Array vec,
long index,
Object values,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values, copyNode, interop);
}
@Specialization(guards = {"interop.hasArrayElements(vec)", "interop.hasArrayElements(values)"})
Vector fromArrayLikeWithArrayLikeObject(
Object vec,
long index,
Object values,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values, copyNode, interop);
}
@Fallback
Vector fromUnknown(Object vec, long index, Object values) {
throw unsupportedException(values);
}
private PanicException unsupportedException(Object values) {
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", values, "values");
throw new PanicException(err, this);
}
private Vector insertBuiltin(
Object current, long index, Object values, CopyNode copyNode, InteropLibrary interop) {
try {
long currentLength = interop.getArraySize(current);
long valuesLength = interop.getArraySize(values);
Array result = Array.allocate(currentLength + valuesLength);
copyNode.execute(current, 0, result, 0, index);
copyNode.execute(values, 0, result, index, valuesLength);
copyNode.execute(current, index, result, index + valuesLength, currentLength - index);
return Vector.fromArray(result);
} catch (UnsupportedMessageException e) {
throw unsupportedException(values);
}
}
}

View File

@ -0,0 +1,94 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CopyNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
type = "Vector",
name = "remove_builtin",
description = "Removes a value for the vector at the specified index.",
autoRegister = false)
public abstract class RemoveAtVectorNode extends Node {
static RemoveAtVectorNode build() {
return RemoveAtVectorNodeGen.create();
}
abstract Vector execute(Object vec, long index);
@Specialization
Vector fromVector(
Vector vec,
long index,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return removeAtIndex(vec.toArray(), index, copyNode, interop);
} catch (UnsupportedMessageException e) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(builtins.error().makeTypeError(builtins.vector(), vec, "vec"), this);
}
}
@Specialization
Vector fromArray(
Array vec,
long index,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return removeAtIndex(vec, index, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(vec);
}
}
@Specialization(guards = "interop.hasArrayElements(vec)")
Vector fromArrayLike(
Object vec,
long index,
@Cached CopyNode copyNode,
@CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return removeAtIndex(vec, index, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(vec);
}
}
@Fallback
Vector fromUnknown(Object vec, long index) {
throw unsupportedException(vec);
}
private PanicException unsupportedException(Object vec) {
CompilerDirectives.transferToInterpreter();
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", vec, "vec");
throw new PanicException(err, this);
}
private Vector removeAtIndex(
Object storage, long index, CopyNode copyArrayNode, InteropLibrary interop)
throws UnsupportedMessageException {
long length = interop.getArraySize(storage);
long actualIndex = index < 0 ? index + length : index;
Array array = Array.allocate(length - 1);
copyArrayNode.execute(storage, 0, array, 0, actualIndex);
copyArrayNode.execute(storage, actualIndex + 1, array, actualIndex, length - actualIndex - 1);
return Vector.fromArray(array);
}
}

View File

@ -31,18 +31,8 @@ public abstract class CoerceArrayNode extends Node {
}
@Specialization
Object[] doVector(Vector arr, @Cached HostValueToEnsoNode hostValueToEnsoNode) {
try {
return convertToArray(arr, hostValueToEnsoNode);
} catch (UnsupportedMessageException e) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
Atom err = builtins.error().makeTypeError(builtins.array(), arr, "arr");
throw new PanicException(err, this);
} catch (InvalidArrayIndexException e) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeInvalidArrayIndex(arr, e.getInvalidIndex()), this);
}
Object[] doVector(Vector arr, @Cached CoerceArrayNode coerceArrayNode) {
return coerceArrayNode.execute(arr.toArray());
}
@Specialization(guards = "interop.hasArrayElements(arr)")

View File

@ -8,25 +8,19 @@ import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
type = "Array",
name = "copy",
description = "Copies one array to another.",
autoRegister = false)
public abstract class CopyNode extends Node {
static CopyNode build() {
public static CopyNode build() {
return CopyNodeGen.create();
}
abstract Object execute(Object src, long source_index, Array dest, long dest_index, long count);
public abstract Object execute(
Object src, long source_index, Array dest, long dest_index, long count);
@Specialization
Object doArray(Array src, long source_index, Array dest, long dest_index, long count) {

View File

@ -35,37 +35,25 @@ public final class Array implements TruffleObject {
*
* @param items the element values
*/
@Builtin.Method(
expandVarargs = 4,
description = "Creates an array with given elements.",
autoRegister = false)
public Array(Object... items) {
assert noNulls(items);
this.items = items;
}
/**
* Creates an uninitialized array of the given size.
* Creates an uninitialized array of the given size. The values must be filled before the array is
* returned to Enso.
*
* @param size the size of the created array.
*/
@Builtin.Method(
description = "Creates an uninitialized array of a given size.",
autoRegister = false,
name = "new")
public static Array allocate(long size) {
var arr = new Object[(int) size];
var ctx = EnsoContext.get(null);
var nothing = ctx.getBuiltins().nothing();
for (int i = 0; i < arr.length; i++) {
arr[i] = nothing;
}
return new Array(arr);
}
private static final boolean noNulls(Object[] arr) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == null) {
private static boolean noNulls(Object[] arr) {
for (Object o : arr) {
if (o == null) {
return false;
}
}
@ -115,6 +103,7 @@ public final class Array implements TruffleObject {
}
return WithWarnings.wrap(EnsoContext.get(warnings), v, extracted);
}
return v;
}
@ -123,7 +112,6 @@ public final class Array implements TruffleObject {
}
/** @return an empty array */
@Builtin.Method(description = "Creates an empty Array", autoRegister = false)
public static Array empty() {
return allocate(0);
}
@ -190,8 +178,8 @@ public final class Array implements TruffleObject {
}
private boolean hasWarningElements(Object[] items, WarningsLibrary warnings) {
for (int i = 0; i < items.length; i++) {
if (warnings.hasWarnings(items[i])) {
for (Object item : items) {
if (warnings.hasWarnings(item)) {
return true;
}
}
@ -219,9 +207,9 @@ public final class Array implements TruffleObject {
private EconomicSet<Warning> collectAllWarnings(WarningsLibrary warnings, Node location)
throws UnsupportedMessageException {
EconomicSet<Warning> setOfWarnings = EconomicSet.create(new WithWarnings.WarningEquivalence());
for (int i = 0; i < items.length; i++) {
if (warnings.hasWarnings(items[i])) {
setOfWarnings.addAll(Arrays.asList(warnings.getWarnings(items[i], location)));
for (Object item : items) {
if (warnings.hasWarnings(item)) {
setOfWarnings.addAll(Arrays.asList(warnings.getWarnings(item, location)));
}
}
return setOfWarnings;

View File

@ -1,43 +0,0 @@
package org.enso.interpreter.test;
import java.net.URI;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import static org.junit.Assert.assertTrue;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class ArrayTest extends TestBase {
private static Context ctx;
@BeforeClass
public static void prepareCtx() {
ctx = createDefaultContext();
}
@AfterClass
public static void disposeCtx() {
ctx.close();
}
@Test
public void dontExposeNullsOutOfArray() throws Exception {
final URI facUri = new URI("memory://choose.enso");
final Source facSrc = Source.newBuilder("enso", """
from Standard.Base import all
null =
a = Array.new 1
b = a.at 0
b
""", "nulls.enso")
.uri(facUri)
.buildLiteral();
var module = ctx.eval(facSrc);
var res = module.invokeMember("eval_expression", "null");
assertTrue("i null", res.isNull());
}
}

View File

@ -193,7 +193,7 @@ class MethodsTest extends InterpreterTest {
|import Standard.Base.Data.Text.Text
|
|main =
| a = Array.new_1 1
| a = [1].to_array
| t_1 = "foo"
| t_2 = "bar"
|

View File

@ -21,7 +21,7 @@ class PolyglotTest extends InterpreterTest {
|main =
| class = Java.lookup_class "org.enso.example.TestClass"
| method = Polyglot.get_member class "add"
| Polyglot.execute method (Array.new_2 1 2)
| Polyglot.execute method ([1, 2].to_array)
|""".stripMargin
eval(code) shouldEqual 3
@ -38,9 +38,8 @@ class PolyglotTest extends InterpreterTest {
try {
eval(code) shouldEqual "An exception shall be thrown"
} catch {
case ex: InterpreterException => {
case ex: InterpreterException =>
ex.getMessage() shouldEqual null
}
}
}
"interop exception with a message" in {
@ -61,12 +60,11 @@ class PolyglotTest extends InterpreterTest {
"allow instantiating objects and calling methods on them" in {
val code =
"""from Standard.Base import all
|import Standard.Base.Data.Array.Array
|
|main =
| class = Java.lookup_class "org.enso.example.TestClass"
| instance = Polyglot.new class (Array.new_1 (x -> x * 2))
| Polyglot.invoke instance "callFunctionAndIncrement" (Array.new_1 10)
| instance = Polyglot.new class [x -> x * 2]
| Polyglot.invoke instance "callFunctionAndIncrement" [10]
|""".stripMargin
eval(code) shouldEqual 21
}
@ -74,11 +72,10 @@ class PolyglotTest extends InterpreterTest {
"allow listing available members of an object" in {
val code =
"""from Standard.Base import all
|import Standard.Base.Data.Array.Array
|
|main =
| class = Java.lookup_class "org.enso.example.TestClass"
| instance = Polyglot.new class Array.empty
| instance = Polyglot.new class []
| members = Polyglot.get_members instance
| IO.println members.length
| IO.println (members.at 0)

View File

@ -19,11 +19,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return success exit code (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "echo" Array.empty "" False False False
| result = System.create_process "echo" [] "" False False False
| result.exit_code
|""".stripMargin
eval(code) shouldEqual 0
@ -34,11 +33,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return success exit code (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "cmd" (Array.new_1 "/c") "" False False False
| result = System.create_process "cmd" ["/c"] "" False False False
| result.exit_code
|""".stripMargin
eval(code) shouldEqual 0
@ -49,9 +47,8 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return error when creating nonexistent command" in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|main = System.create_process "nonexistentcommandxyz" Array.empty "" False False False
|main = System.create_process "nonexistentcommandxyz" [] "" False False False
|""".stripMargin
val error = the[InterpreterException] thrownBy eval(code)
@ -64,11 +61,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return error exit code (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "ls --gibberish") "" False False False
| result = System.create_process "bash" ["-c", "ls --gibberish"] "" False False False
| result.exit_code
|""".stripMargin
@ -80,11 +76,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return error exit code (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "cmd" (Array.new_2 "/c" "exit 7") "" False False False
| result = System.create_process "cmd" ["/c", "exit 7"] "" False False False
| result.exit_code
|""".stripMargin
@ -96,11 +91,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdin chars (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "read line; echo $line") "" True True True
| result = System.create_process "bash" ["-c", "read line; echo $line"] "" True True True
| result.exit_code
|""".stripMargin
@ -113,11 +107,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdin chars (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::ReadLine()") "" True True True
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::ReadLine()"] "" True True True
| result.exit_code
|""".stripMargin
@ -131,11 +124,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
val input = Random.nextBytes(Byte.MaxValue)
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "wc -c") "" True True True
| result = System.create_process "bash" ["-c", "wc -c"] "" True True True
| result.exit_code
|""".stripMargin
@ -150,11 +142,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
pending
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "echo 42") "" True True True
| result = System.create_process "bash" ["-c", "echo 42"] "" True True True
| result.exit_code
|""".stripMargin
@ -167,11 +158,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdin unused (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "cmd" (Array.new_2 "/c" "echo 9") "" True True True
| result = System.create_process "cmd" ["/c", "echo 9"] "" True True True
| result.exit_code
|""".stripMargin
@ -184,11 +174,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdin empty (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "echo 9") "" True True True
| result = System.create_process "bash" ["-c", "echo 9"] "" True True True
| result.exit_code
|""".stripMargin
@ -200,11 +189,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdin empty (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "cmd" (Array.new_2 "/c" "echo 9") "" True True True
| result = System.create_process "cmd" ["/c", "echo 9"] "" True True True
| result.exit_code
|""".stripMargin
@ -216,11 +204,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"provide stdin string (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "read line; printf $line") "hello" False False False
| result = System.create_process "bash" ["-c", "read line; printf $line"] "hello" False False False
| result.stdout
|""".stripMargin
@ -232,11 +219,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"provide stdin string (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::ReadLine()") "hello" False False False
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::ReadLine()"] "hello" False False False
| result.stdout
|""".stripMargin
@ -248,11 +234,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdout chars (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "echo foobar") "" False True True
| result = System.create_process "bash" ["-c", "echo foobar"] "" False True True
| result.exit_code
|""".stripMargin
@ -264,11 +249,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdout chars (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "cmd" (Array.new_2 "/c" "echo foobar") "" False True True
| result = System.create_process "cmd" ["/c", "echo foobar"] "" False True True
| result.exit_code
|""".stripMargin
@ -280,11 +264,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stdout binary (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "printf '%b' '\x01\x0F\x10'") "" False True True
| result = System.create_process "bash" ["-c", "printf '%b' '\x01\x0F\x10'"] "" False True True
| result.exit_code
|""".stripMargin
@ -296,11 +279,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return stdout string (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "echo foobar") "" False False False
| result = System.create_process "bash" ["-c", "echo foobar"] "" False False False
| result.stdout
|""".stripMargin
@ -313,11 +295,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return stdout string (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "cmd" (Array.new_2 "/c" "echo foobar") "" False False False
| result = System.create_process "cmd" ["/c", "echo foobar"] "" False False False
| result.stdout
|""".stripMargin
@ -330,11 +311,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stderr chars (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "printf err 1>&2") "" False True True
| result = System.create_process "bash" ["-c", "printf err 1>&2"] "" False True True
| result.exit_code
|""".stripMargin
@ -346,11 +326,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stderr chars (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::Error.WriteLine('err')") "" False True True
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::Error.WriteLine('err')"] "" False True True
| result.exit_code
|""".stripMargin
@ -362,11 +341,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"redirect stderr binary (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "printf '%b' '\xCA\xFE\xBA\xBE' 1>&2") "" False True True
| result = System.create_process "bash" ["-c", "printf '%b' '\xCA\xFE\xBA\xBE' 1>&2"] "" False True True
| result.exit_code
|""".stripMargin
@ -378,11 +356,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return stderr string (Unix)" taggedAs OsUnix in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "bash" (Array.new_2 "-c" "printf err 1>&2") "" False False False
| result = System.create_process "bash" ["-c", "printf err 1>&2"] "" False False False
| result.stderr
|""".stripMargin
@ -394,11 +371,10 @@ class SystemProcessTest extends InterpreterTest with OsSpec {
"return stderr string (Windows)" taggedAs OsWindows in {
val code =
"""import Standard.Base.System
|import Standard.Base.Data.Array.Array
|from Standard.Base.Data.Boolean import all
|
|main =
| result = System.create_process "PowerShell" (Array.new_2 "-Command" "[System.Console]::Error.WriteLine('err')") "" False False False
| result = System.create_process "PowerShell" ["-Command", "[System.Console]::Error.WriteLine('err')"] "" False False False
| result.stderr
|""".stripMargin

View File

@ -1029,7 +1029,7 @@ spec make_new_connection prefix persistent_connector=True =
If `exploding_index` is accessed, an exception will be thrown.
make_mock_column name values exploding_index =
storage = ExplodingStorage.new values.to_array exploding_index
storage = ExplodingStorage.new values exploding_index
Column.from_storage name storage
## PRIVATE

View File

@ -29,7 +29,7 @@ spec = Test.group "Aggregate Columns" <|
acc = Aggregate_Column_Helper.java_aggregator "Name" resolved
indexes = Vector.new table.row_count v->v
Illegal_Argument.handle_java_exception <|
acc.aggregate indexes.to_array
acc.aggregate indexes
if epsilon != False then ((result - expected_result).abs < epsilon).should_be_true else
result.should_equal expected_result

View File

@ -7,12 +7,10 @@ import Standard.Test.Extensions
Array.method self = 0
## Returns an array with the same contents as the given vector, surely backed by
the Enso Array primitive.
## Returns the backing array of the given vector. Will be an Enso Array if from
a literal vector.
make_enso_array vector =
enso_array = Array.new vector.length
Array.copy vector.to_array 0 enso_array 0 vector.length
enso_array
vector.to_array
test_arrays array_from_vector =
Test.specify "should allow accessing elements" <|
@ -38,11 +36,6 @@ spec =
(make_enso_array [1,2,3]).should_equal (make_enso_array [1,2,3])
(make_enso_array [1]).should_not_equal (make_enso_array [2])
Test.specify "should propagate dataflow errors" <|
err = Error.throw (Illegal_State.Error "Foo")
res = Array.new err
res . should_fail_with Illegal_State
Test.specify "should not sort in place" <|
arr = make_enso_array [3, 1, 2]
new_arr = arr.sort

View File

@ -39,7 +39,7 @@ spec =
Test.specify "should correctly translate a series of codepoint indices to a grapheme indices in a batch" <|
translate_indices text ixes =
Vector.from_polyglot_array <| Text_Utils.utf16_indices_to_grapheme_indices text ixes.to_array
Vector.from_polyglot_array <| Text_Utils.utf16_indices_to_grapheme_indices text ixes
codepoint_indices = Vector.new text.char_vector.length ix->ix
translate_indices text codepoint_indices . should_equal codepoints_to_graphemes

View File

@ -193,7 +193,7 @@ spec =
([(Child.Value 1)] == [(Child.Value 2)]).should_be_false
Test.specify "should dispatch to overriden `==` in arrays" <|
((Array.new_1 (Child.Value 1)) == (Array.new_1 (Child.Value 101))).should_be_true
([Child.Value 1].to_array == [Child.Value 101].to_array).should_be_true
Test.specify "should handle recursive atoms without custom `==`" <|
rnd = (Random.new seed=42).java_random

View File

@ -52,6 +52,6 @@ spec =
Bar.meh b 2 . should_equal 3
Test.group "Fully Qualified Names" <|
Test.specify "should be correctly resolved" <|
a = Standard.Base.Data.Array.Array.new 10
a = Standard.Base.Data.Vector.Vector.new 10 _->Nothing
a.length . should_equal 10
Standard.Base.Errors.Problem_Behavior.Problem_Behavior.Report_Error.to_text . should_equal "Report_Error"

View File

@ -13,8 +13,4 @@ spec = Test.group "System" <|
result = System.create_process "echo" ["foo", "bar"] "" False False False
result.exit_code . should_equal 0
result_2 = System.create_process "echo" ["foo", "bar"].to_array "" False False False
result_2.exit_code . should_equal 0
main = Test_Suite.run_main spec

View File

@ -2,7 +2,3 @@
type Array
at self index = @Builtin_Method "Array.at"
length self = @Builtin_Method "Array.length"
new_1 item_1 = @Builtin_Method "Array.new_1"
new_2 item_1 item_2 = @Builtin_Method "Array.new_2"
empty = @Builtin_Method "Array.empty"