Skip to content

Commit

Permalink
[cpp] fixed an issue where semantic analysis would not be performed o…
Browse files Browse the repository at this point in the history
…n blocks which are children of if or for statements
  • Loading branch information
harrand committed May 16, 2024
1 parent 83ea5d6 commit 56bb2d0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
29 changes: 29 additions & 0 deletions cpp/src/semal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,13 +491,42 @@ namespace semal
{
type if_expr_ty = expression(d, *payload.if_expr);
d.assert_that(if_expr_ty.is_primitive() && if_expr_ty.as_primitive() == primitive_type::boolean, std::format("expression of if-statement operand must be a boolean, you passed a {}", if_expr_ty.name()));

const auto& node = d.tree.get(d.path);
d.assert_that(node.children.size() == 1 || node.children.size() == 2, std::format("if-statement AST node is expected to have *1* child representing its if-true-clause (or *2* children if it's an if-then-else), but the node actually has \"{}\"", node.children.size()));
for(std::size_t i = 0; i < node.children.size(); i++)
{
const ast::node& child = node.children[i];
d.assert_that(std::holds_alternative<ast::block>(child.payload), std::format("child nodes of an if-statement node must only ever be blocks. detected a non-block AST child node."));
for(std::size_t j = 0; j < child.children.size(); j++)
{
const ast::node& grandchild = child.children[j];
data d2 = d;
d2.path.push_back(i);
d2.path.push_back(j);
generic(d2, grandchild.payload);
}
}
return type::undefined();
}

type for_statement(const data& d, const ast::for_statement& payload)
{
type cond_expr_ty = expression(d, *payload.cond_expr);
d.assert_that(cond_expr_ty.is_primitive() && cond_expr_ty.as_primitive() == primitive_type::boolean, std::format("condition-expression (2nd part) of for-statement operand must be a boolean, you passed a {}", cond_expr_ty.name()));
const auto& node = d.tree.get(d.path);

d.assert_that(node.children.size() == 1, std::format("for-statement AST node is expected to have *1* child representing its loop block, but the node actually has \"{}\"", node.children.size()));
const ast::node& child = node.children.front();
d.assert_that(std::holds_alternative<ast::block>(child.payload), std::format("child nodes of an for-statement node must only ever be blocks. detected a non-block AST child node."));
for(std::size_t j = 0; j < child.children.size(); j++)
{
const ast::node& grandchild = child.children[j];
data d2 = d;
d2.path.push_back(0);
d2.path.push_back(j);
generic(d2, grandchild.payload);
}
return type::undefined();
}

Expand Down
2 changes: 1 addition & 1 deletion samples/scratchpad.psy
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ dub :: (val : i64) -> i64
myint : i64 := 0;
for myint = 0, myint == 5, myint = myint + 1
{
putchar(myint);
putchar(myint@i8);
}
}

Expand Down

0 comments on commit 56bb2d0

Please sign in to comment.