diff --git a/src/libAtomVM/bif.c b/src/libAtomVM/bif.c index 5888d645f..98184bad6 100644 --- a/src/libAtomVM/bif.c +++ b/src/libAtomVM/bif.c @@ -494,6 +494,17 @@ term bif_erlang_add_2(Context *ctx, uint32_t fail_label, int live, term arg1, te } } +term bif_erlang_add_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 5d257588f..136389366 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_add_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 d441da07a..218657eef 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_add_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 b666662a0..17ad7f318 100644 --- a/tests/erlang_tests/CMakeLists.txt +++ b/tests/erlang_tests/CMakeLists.txt @@ -290,6 +290,7 @@ compile_erlang(int28mulneg2) compile_erlang(negdiv) compile_erlang(absovf) compile_erlang(negovf) +compile_erlang(unary_plus) compile_erlang(plusone3) compile_erlang(plusone4) @@ -767,6 +768,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..c8d1d085e --- /dev/null +++ b/tests/erlang_tests/unary_plus.erl @@ -0,0 +1,49 @@ +% +% This file is part of AtomVM. +% +<<<<<<< HEAD +% Copyright 2024 migmatore +======= +% Copyright 2025 migmatore +>>>>>>> f159c3e9 (Fix +/1 (unary plus) not implemented #1512) +% +% 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]). + +start() -> + ok = unary_plus_int(1621436), + ok = unary_plus_float(1135.12523), + ok = 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 87b8a68be..7268db9af 100644 --- a/tests/test.c +++ b/tests/test.c @@ -333,6 +333,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),