Change keyword statements to bracket arguments. (#2394)

This changes `return`, `break`, and `continue` to treat the keyword as the "start" and semicolon as the "parent", essentially bracketing the keyword.

Pragmatically this is focusing on making `return` work with only one ParseNodeKind: because `return` and `;` now bracket the expression, we can tightly determine whether the `return` has arguments without looking at subtree size. However, it's possible that `break` and `continue` may in the future take some kind of label as an argument, so the consistency seems beneficial there too.

Note this eliminates the StatementEnd ParseNodeKind, as it's obsolete with this change.
This commit is contained in:
Jon Ross-Perkins
2022-11-15 22:42:54 -08:00
committed by GitHub
parent ed654c1aa8
commit b914f46ec5
13 changed files with 174 additions and 83 deletions
@@ -106,7 +106,7 @@ auto SemanticsParseTreeHandler::Build() -> void {
case ParseNodeKind::DeclaredName():
case ParseNodeKind::FunctionIntroducer():
case ParseNodeKind::ParameterListEnd():
case ParseNodeKind::StatementEnd(): {
case ParseNodeKind::ReturnStatementStart(): {
// The token has no action, but we still track it for the stack.
Push(parse_node);
break;
@@ -255,14 +255,13 @@ auto SemanticsParseTreeHandler::HandleParameterList(ParseTree::Node parse_node)
auto SemanticsParseTreeHandler::HandleReturnStatement(
ParseTree::Node parse_node) -> void {
Pop(ParseNodeKind::StatementEnd());
// TODO: Restructure ReturnStatement so that we can do this without
// looking at the subtree size.
if (parse_tree_->node_subtree_size(parse_node) == 2) {
if (parse_tree_->node_kind(node_stack_.back().parse_node) ==
ParseNodeKind::ReturnStatementStart()) {
Pop(ParseNodeKind::ReturnStatementStart());
Push(parse_node, SemanticsNode::MakeReturn());
} else {
auto arg = PopWithResult();
Pop(ParseNodeKind::ReturnStatementStart());
Push(parse_node, SemanticsNode::MakeReturnExpression(arg));
}
}