Skip to content

Commit

Permalink
Merge pull request #1277 from pguyot/w38/add-elixir-list-chars-protocol
Browse files Browse the repository at this point in the history
Add Elixir List.Chars protocol.

https://github.com/elixir-lang/elixir/blob/v1.17.2/lib/elixir/lib/list/chars.ex

Split into several source files because of how our CMakeLists.txt is built

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
  • Loading branch information
bettio committed Sep 24, 2024
2 parents 4f851d3 + 7faa258 commit 0c598ab
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ also non string parameters (e.g. `Enum.join([1, 2], ",")`
- Support for `lists:last/1` and `lists:mapfoldl/3`
- Add support to Elixir for `Process.send/2` `Process.send_after/3/4` and `Process.cancel_timer/1`
- Add support for `handle_continue` callback in `gen_server`
- Support for Elixir `List.Chars` protocol

### Changed

Expand Down
7 changes: 7 additions & 0 deletions libs/exavmlib/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ set(ELIXIR_MODULES
Collectable.Map
Collectable.MapSet

List.Chars
List.Chars.Atom
List.Chars.BitString
List.Chars.Float
List.Chars.Integer
List.Chars.List

String.Chars
String.Chars.Atom
String.Chars.BitString
Expand Down
26 changes: 26 additions & 0 deletions libs/exavmlib/lib/List.Chars.Atom.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# This file is part of elixir-lang.
#
# Copyright 2013-2023 Elixir Contributors
# https://github.com/elixir-lang/elixir/commits/v1.17.2/lib/elixir/lib/list/chars.ex
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defimpl List.Chars, for: Atom do
def to_charlist(nil), do: ~c""

def to_charlist(atom), do: Atom.to_charlist(atom)
end
36 changes: 36 additions & 0 deletions libs/exavmlib/lib/List.Chars.BitString.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#
# This file is part of elixir-lang.
#
# Copyright 2013-2023 Elixir Contributors
# https://github.com/elixir-lang/elixir/commits/v1.17.2/lib/elixir/lib/list/chars.ex
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defimpl List.Chars, for: BitString do
@doc """
Returns the given binary `term` converted to a charlist.
"""
def to_charlist(term) when is_binary(term) do
String.to_charlist(term)
end

def to_charlist(term) do
raise Protocol.UndefinedError,
protocol: @protocol,
value: term,
description: "cannot convert a bitstring to a charlist"
end
end
27 changes: 27 additions & 0 deletions libs/exavmlib/lib/List.Chars.Float.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#
# This file is part of elixir-lang.
#
# Copyright 2013-2023 Elixir Contributors
# https://github.com/elixir-lang/elixir/commits/v1.17.2/lib/elixir/lib/list/chars.ex
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defimpl List.Chars, for: Float do
def to_charlist(term) do
# TODO: :short option not yet supported right now, so :decimals+:compact should be replaced
:erlang.float_to_list(term, [{:decimals, 17}, :compact])
end
end
26 changes: 26 additions & 0 deletions libs/exavmlib/lib/List.Chars.Integer.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# This file is part of elixir-lang.
#
# Copyright 2013-2023 Elixir Contributors
# https://github.com/elixir-lang/elixir/commits/v1.17.2/lib/elixir/lib/list/chars.ex
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defimpl List.Chars, for: Integer do
def to_charlist(term) do
Integer.to_charlist(term)
end
end
25 changes: 25 additions & 0 deletions libs/exavmlib/lib/List.Chars.List.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# This file is part of elixir-lang.
#
# Copyright 2013-2023 Elixir Contributors
# https://github.com/elixir-lang/elixir/commits/v1.17.2/lib/elixir/lib/list/chars.ex
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defimpl List.Chars, for: List do
# Note that same inlining is used for the rewrite rule.
def to_charlist(list), do: list
end
39 changes: 39 additions & 0 deletions libs/exavmlib/lib/List.Chars.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#
# This file is part of elixir-lang.
#
# Copyright 2013-2023 Elixir Contributors
# https://github.com/elixir-lang/elixir/commits/v1.17.2/lib/elixir/lib/list/chars.ex
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defprotocol List.Chars do
@moduledoc ~S"""
The `List.Chars` protocol is responsible for
converting a structure to a charlist (only if applicable).
The only function that must be implemented is
`to_charlist/1` which does the conversion.
The `to_charlist/1` function automatically imported
by `Kernel` invokes this protocol.
"""

@doc """
Converts `term` to a charlist.
"""
@spec to_charlist(t) :: charlist
def to_charlist(term)
end

0 comments on commit 0c598ab

Please sign in to comment.