diff --git a/CHANGELOG.md b/CHANGELOG.md index eaa5cc68b..5b3295ae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `esp:partition_read/3`, and documentation for `esp:partition_erase_range/2/3` and `esp:partition_write/3` - Added support for list insertion in 'ets:insert/2'. - Support to OTP-28 +- Added `erlang:+/1` ### Fixed - ESP32: improved sntp sync speed from a cold boot. diff --git a/src/libAtomVM/bif.c b/src/libAtomVM/bif.c index 82b5c038f..de5c9780e 100644 --- a/src/libAtomVM/bif.c +++ b/src/libAtomVM/bif.c @@ -497,6 +497,17 @@ term bif_erlang_add_2(Context *ctx, uint32_t fail_label, int live, term arg1, te } } +term bif_erlang_plus_1(Context *ctx, uint32_t fail_label, int live, term arg1) +{ + UNUSED(live); + + if (LIKELY(term_is_number(arg1))) { + return arg1; + } else { + RAISE_ERROR_BIF(fail_label, BADARITH_ATOM); + } +} + static term sub_overflow_helper(Context *ctx, uint32_t fail_label, uint32_t live, term arg1, term arg2) { avm_int_t val1 = term_to_int(arg1); diff --git a/src/libAtomVM/bif.h b/src/libAtomVM/bif.h index d7d20468c..dc15b4ded 100644 --- a/src/libAtomVM/bif.h +++ b/src/libAtomVM/bif.h @@ -70,6 +70,7 @@ term bif_erlang_map_size_1(Context *ctx, uint32_t fail_label, int live, term arg term bif_erlang_map_get_2(Context *ctx, uint32_t fail_label, term arg1, term arg2); term bif_erlang_add_2(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2); +term bif_erlang_plus_1(Context *ctx, uint32_t fail_label, int live, term arg1); term bif_erlang_sub_2(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2); term bif_erlang_mul_2(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2); term bif_erlang_div_2(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2); diff --git a/src/libAtomVM/bifs.gperf b/src/libAtomVM/bifs.gperf index 71b252ff8..a2e4eb383 100644 --- a/src/libAtomVM/bifs.gperf +++ b/src/libAtomVM/bifs.gperf @@ -72,6 +72,7 @@ erlang:*/2, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif2_ptr = bif_erlan erlang:div/2, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif2_ptr = bif_erlang_div_2} erlang:rem/2, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif2_ptr = bif_erlang_rem_2} erlang:-/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_neg_1} +erlang:+/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_plus_1} erlang:abs/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_abs_1} erlang:ceil/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_ceil_1} erlang:floor/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_floor_1} diff --git a/tests/erlang_tests/CMakeLists.txt b/tests/erlang_tests/CMakeLists.txt index 9b885696e..2d4f9bcfc 100644 --- a/tests/erlang_tests/CMakeLists.txt +++ b/tests/erlang_tests/CMakeLists.txt @@ -292,6 +292,7 @@ compile_erlang(int28mulneg2) compile_erlang(negdiv) compile_erlang(absovf) compile_erlang(negovf) +compile_erlang(unary_plus) compile_erlang(plusone3) compile_erlang(plusone4) @@ -771,6 +772,7 @@ add_custom_target(erlang_test_modules DEPENDS negdiv.beam absovf.beam negovf.beam + unary_plus.beam plusone3.beam plusone4.beam diff --git a/tests/erlang_tests/unary_plus.erl b/tests/erlang_tests/unary_plus.erl new file mode 100644 index 000000000..9cc0ddf46 --- /dev/null +++ b/tests/erlang_tests/unary_plus.erl @@ -0,0 +1,45 @@ +% +% This file is part of AtomVM. +% +% Copyright 2025 migmatore +% +% 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 OR LGPL-2.1-or-later +% + +-module(unary_plus). + +-export([start/0, unary_plus_int/1, unary_plus_float/1, unary_plus_str/1]). + +start() -> + ok = ?MODULE:unary_plus_int(1621436), + ok = ?MODULE:unary_plus_float(1135.12523), + ok = ?MODULE:unary_plus_str("string"), + 0. + +unary_plus_int(A) -> + +A, + ok. + +unary_plus_float(A) -> + +A, + ok. + +unary_plus_str(A) -> + try +A of + ok -> error + catch + error:badarith -> ok; + _:_ -> error + end. diff --git a/tests/test.c b/tests/test.c index 718207c94..3a5ec67f7 100644 --- a/tests/test.c +++ b/tests/test.c @@ -334,6 +334,7 @@ struct Test tests[] = { TEST_CASE_EXPECTED(negdiv, 134217728), TEST_CASE_EXPECTED(absovf, 134217728), TEST_CASE_EXPECTED(negovf, 134217728), + TEST_CASE(unary_plus), TEST_CASE_EXPECTED(plusone3, 134217726), TEST_CASE_EXPECTED(plusone4, 134217728),