diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index e65660e1594e586328cdb7dc908ae629fa91f4ad..8714258e6303fff8a1aacf8d420e89a4b8627897 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -236,6 +236,19 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise(ir::Expression *left, ir:: bool isEqualOp, checker::Type *const leftType, checker::Type *const rightType, Type *unboxedL, Type *unboxedR) { + // NOTE (mmartin): These need to be done for other binary expressions, but currently it's not defined precisely when + // to apply this conversion + + if (leftType->IsETSEnumType()) { + left->AddAstNodeFlags(ir::AstNodeFlags::ENUM_GET_VALUE); + unboxedL = GlobalIntType(); + } + + if (rightType->IsETSEnumType()) { + right->AddAstNodeFlags(ir::AstNodeFlags::ENUM_GET_VALUE); + unboxedR = GlobalIntType(); + } + if (leftType->IsETSUnionType() || rightType->IsETSUnionType()) { ThrowTypeError("Bad operand type, unions are not allowed in binary expressions except equality.", pos); } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 9603461920f60c560ea4dc739ebc7265f423bd9a..a7f000ba114596f96f055e11d2fb3767282cd4ea 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -961,6 +961,13 @@ void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targe { auto ttctx = TargetTypeContext(this, targetType); + if (node->HasAstNodeFlags(ir::AstNodeFlags::ENUM_GET_VALUE)) { + Ra().Emit( + node, node->AsExpression()->TsType()->AsETSEnumType()->GetValueMethod().globalSignature->InternalName(), + dummyReg_, 0); + node->RemoveAstNodeFlags(ir::AstNodeFlags::ENUM_GET_VALUE); + } + if ((node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U) { ApplyBoxingConversion(node); return; diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index f6eedfb88e7aae97f6adb4fe243611a6f69f63d6..4b20f93db346cc953bcf72a36e663d1400b190c3 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -450,7 +450,7 @@ public: { \ return ((member_name)&flag) != 0U; \ } \ - void Remove##flag_type(flag_type flag) noexcept \ + void Remove##flag_type(flag_type flag) const noexcept \ { \ (member_name) &= ~flag; \ } diff --git a/ets2panda/ir/astNodeFlags.h b/ets2panda/ir/astNodeFlags.h index f6420bb131169df655c2d9ce113a41c983aa62a6..fb74be021bc80d3c8a18e49082a594d858a9cc10 100644 --- a/ets2panda/ir/astNodeFlags.h +++ b/ets2panda/ir/astNodeFlags.h @@ -22,6 +22,7 @@ namespace panda::es2panda::ir { enum class AstNodeFlags { NO_OPTS = 0, CHECKCAST = 1U << 0U, + ENUM_GET_VALUE = 1U << 1U, }; enum class ModifierFlags : uint32_t { diff --git a/ets2panda/test/runtime/ets/Enum6.ets b/ets2panda/test/runtime/ets/Enum6.ets new file mode 100644 index 0000000000000000000000000000000000000000..39b8f0c5dbc6055f02556c7eafd137f1a757f249 --- /dev/null +++ b/ets2panda/test/runtime/ets/Enum6.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +enum Access { + READ = 1, + WRITE = 2, + READWRITE = 3 +} + +enum TestEnum { + A = 144, + B, + C = 795 +} + +function main(): void { + test_access_enum_bitwise(Access.WRITE); + assert (Access.WRITE & Access.READWRITE) == 2; + + test_test_enum_bitwise(TestEnum.C); + assert (TestEnum.B & TestEnum.A) == 144 + +} + +function test_access_enum_bitwise(enum_val: Access): void { + assert (enum_val & Access.READ) == 0 + assert (enum_val & Access.WRITE) == 2 + assert (enum_val | Access.READ) == 3 + assert (enum_val | Access.READWRITE) == 3 + assert (enum_val & Access.READWRITE) == 2 +} + +function test_test_enum_bitwise(enum_val: TestEnum): void { + assert (enum_val & TestEnum.A) == 16 + assert (enum_val | TestEnum.A) == 923 + assert (enum_val & TestEnum.B) == 17 + assert (enum_val | TestEnum.B) == 923 +}