From 54f67d75bc49e71a2f75f6c9cf9422ade7f1793e Mon Sep 17 00:00:00 2001 From: migmatore Date: Sun, 16 Feb 2025 22:06:48 +0300 Subject: [PATCH] Fix +/1 (unary plus) not implemented #1512 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 Signed-off-by: migmatore --- src/libAtomVM/bif.c | 11 ++++++++ src/libAtomVM/bif.h | 1 + src/libAtomVM/bifs.gperf | 1 + tests/erlang_tests/CMakeLists.txt | 2 ++ tests/erlang_tests/unary_plus.erl | 45 +++++++++++++++++++++++++++++++ tests/test.c | 1 + 6 files changed, 61 insertions(+) create mode 100644 tests/erlang_tests/unary_plus.erl diff --git a/src/libAtomVM/bif.c b/src/libAtomVM/bif.c index 82b5c038f..65cfdcddb 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_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 d7d20468c..52e164b59 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 71b252ff8..32d62afac 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 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..c86652bff --- /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]). + +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 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),