aboutsummaryrefslogtreecommitdiff
path: root/boot/evaluator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/evaluator.cc')
-rw-r--r--boot/evaluator.cc70
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"))
{