aboutsummaryrefslogtreecommitdiff
path: root/boot/type_check.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-24 18:11:43 +0200
committerEugen Wissner <belka@caraus.de>2026-07-24 18:11:43 +0200
commit5dc1e4c991efae2e0dd96b59bc57b2cd81a8c5fb (patch)
treef18cee693c72e6d7bfa2684bb522e52cd1a08033 /boot/type_check.cc
parentbb4f474cb2247e0e314beab5d7d72e673ff4e8b6 (diff)
downloadelna-5dc1e4c991efae2e0dd96b59bc57b2cd81a8c5fb.tar.gz
Check the compound statement condition is a boolean
Diffstat (limited to 'boot/type_check.cc')
-rw-r--r--boot/type_check.cc69
1 files changed, 69 insertions, 0 deletions
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 761c4b2..9bab537 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -107,6 +107,9 @@ namespace elna::boot
case kind::for_loop:
return "for-loop variable must be an array or a slice, got '"
+ this->actual.to_string() + "'";
+ case kind::condition:
+ return "Condition must be a boolean, got '"
+ + this->actual.to_string() + "'";
default:
__builtin_unreachable();
}
@@ -212,6 +215,16 @@ namespace elna::boot
return true;
}
+ void type_analysis_visitor::visit_and_validate_condition(expression& condition)
+ {
+ condition.accept(this);
+ if (!is_primitive_type(condition.type_decoration, "Bool"))
+ {
+ add_error<type_kind_error>(condition.position(),
+ type_kind_error::kind::condition, condition.type_decoration);
+ }
+ }
+
/*
* Checks whether derived has base in its record parent chain.
*
@@ -492,6 +505,61 @@ namespace elna::boot
this->bag.leave();
}
+ void type_analysis_visitor::visit(repeat_statement *statement)
+ {
+ visit_and_validate_condition(statement->condition());
+
+ for (auto *body_statement : statement->body)
+ {
+ body_statement->accept(this);
+ }
+ }
+
+ void type_analysis_visitor::visit(while_statement *statement)
+ {
+ visit_and_validate_condition(statement->branch().prerequisite());
+
+ for (auto *branch_statement : statement->branch().statements)
+ {
+ branch_statement->accept(this);
+ }
+ for (conditional_statements *branch : statement->branches)
+ {
+ visit_and_validate_condition(branch->prerequisite());
+
+ for (auto *branch_statement : branch->statements)
+ {
+ branch_statement->accept(this);
+ }
+ }
+ }
+
+ void type_analysis_visitor::visit(if_statement *statement)
+ {
+ visit_and_validate_condition(statement->branch().prerequisite());
+
+ for (auto *branch_statement : statement->branch().statements)
+ {
+ branch_statement->accept(this);
+ }
+ for (conditional_statements *branch : statement->branches)
+ {
+ visit_and_validate_condition(branch->prerequisite());
+
+ for (auto *branch_statement : branch->statements)
+ {
+ branch_statement->accept(this);
+ }
+ }
+ if (statement->alternative != nullptr)
+ {
+ for (auto *branch_statement : *statement->alternative)
+ {
+ branch_statement->accept(this);
+ }
+ }
+ }
+
void type_analysis_visitor::visit(type_declaration *declaration)
{
std::vector<std::string> alias_path;
@@ -564,6 +632,7 @@ namespace elna::boot
type(std::make_shared<procedure_type>()),
call->callable().type_decoration);
}
+ // else callable is not declared which is already reported.
}
void type_analysis_visitor::visit(record_constructor_expression *expression)