diff options
Diffstat (limited to 'boot/evaluator.cc')
| -rw-r--r-- | boot/evaluator.cc | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/boot/evaluator.cc b/boot/evaluator.cc index 14ca889..d8d9ddc 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -73,31 +73,18 @@ namespace elna::boot { auto resolved = resolve_underlying_type(subject); - if (is_primitive_type(resolved, "Int") - || resolved.get<enumeration_type>() != nullptr) + if (resolved.get<enumeration_type>() != nullptr) { - return target.int_properties; + return target.word_properties.front(); } - else if (is_primitive_type(resolved, "Word")) - { - return target.word_properties; - } - else if (is_primitive_type(resolved, "Char")) + else if (auto resolved_primitive = resolved.get<primitive_type>()) { - return target.char_properties; - } - else if (is_primitive_type(resolved, "Float")) - { - return target.float_properties; - } - else if (is_primitive_type(resolved, "Bool")) - { - return target.bool_properties; + return resolved_primitive->properties; } else if (resolved.get<slice_type>() != nullptr) { return type_properties{ - .size = target.pointer_properties.size + target.word_properties.size, + .size = target.pointer_properties.size + target.word_properties.front().size, .alignment = target.pointer_properties.alignment }; } @@ -812,13 +799,23 @@ namespace elna::boot { type const resolved = resolve_underlying_type(subject.types.front()); - if (is_primitive_type(resolved, "Int")) - { - return constant_value{ integer_literal::from(std::numeric_limits<std::ptrdiff_t>::min()) }; - } - if (is_primitive_type(resolved, "Word")) + if (auto resolved_primitive = resolved.get<primitive_type>()) { - return constant_value{ integer_literal::from<std::size_t>(0) }; + if (resolved_primitive->identifier.starts_with("Int")) + { + const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT; + const integer_literal one = integer_literal::from<std::ptrdiff_t>( + resolved_primitive->properties.size, 1U).value(); + + return constant_value{ + one.shl(integer_literal::from<std::size_t>(bits - 1U)).value() + }; + } + if (resolved_primitive->identifier.starts_with("Word")) + { + return constant_value{ integer_literal::from<std::size_t>( + resolved_primitive->properties.size, 0U).value() }; + } } if (is_primitive_type(resolved, "Char")) { @@ -841,13 +838,26 @@ namespace elna::boot { type const resolved = resolve_underlying_type(subject.types.front()); - if (is_primitive_type(resolved, "Int")) + if (auto resolved_primitive = resolved.get<primitive_type>()) { - return constant_value{ integer_literal::from(std::numeric_limits<std::ptrdiff_t>::max()) }; - } - if (is_primitive_type(resolved, "Word")) - { - return constant_value{ integer_literal::from(std::numeric_limits<std::size_t>::max()) }; + if (resolved_primitive->identifier.starts_with("Int")) + { + const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT; + const integer_literal one = integer_literal::from<std::ptrdiff_t>( + resolved_primitive->properties.size, 1U).value(); + const std::optional<integer_literal> minimum = one.shl( + integer_literal::from<std::size_t>(bits - 1U)); + + return constant_value{ ~minimum.value() }; + } + if (resolved_primitive->identifier.starts_with("Word")) + { + // All bits set. + std::optional<integer_literal> zero = integer_literal::from<std::size_t>( + resolved_primitive->properties.size, 0U); + + return constant_value{ ~zero.value() }; + } } if (is_primitive_type(resolved, "Char")) { |
