Change Match clauses from pairs to classes (#858)

Updates style of the Match class at the same time.
This commit is contained in:
Jon Meow
2021-09-29 13:36:54 -07:00
committed by GitHub
parent bf49f2efed
commit 25dce9fbcf
6 changed files with 57 additions and 43 deletions
@@ -737,7 +737,7 @@ auto Interpreter::StepStmt() -> Transition {
// { { (match (e) ...) :: C, E, F} :: S, H}
// -> { { e :: (match ([]) ...) :: C, E, F} :: S, H}
frame->scopes.Push(arena->New<Scope>(CurrentEnv()));
return Spawn{arena->New<ExpressionAction>(match_stmt.Exp())};
return Spawn{arena->New<ExpressionAction>(&match_stmt.expression())};
} else {
// Regarding act->Pos():
// * odd: start interpreting the pattern of a clause
@@ -749,31 +749,31 @@ auto Interpreter::StepStmt() -> Transition {
// * 2: the pattern for clause 1
// * ...
auto clause_num = (act->Pos() - 1) / 2;
if (clause_num >= static_cast<int>(match_stmt.Clauses().size())) {
if (clause_num >= static_cast<int>(match_stmt.clauses().size())) {
DeallocateScope(frame->scopes.Top());
frame->scopes.Pop();
return Done{};
}
auto c = match_stmt.Clauses()[clause_num];
auto c = match_stmt.clauses()[clause_num];
if (act->Pos() % 2 == 1) {
// start interpreting the pattern of the clause
// { {v :: (match ([]) ...) :: C, E, F} :: S, H}
// -> { {pi :: (match ([]) ...) :: C, E, F} :: S, H}
return Spawn{arena->New<PatternAction>(c.first)};
return Spawn{arena->New<PatternAction>(&c.pattern())};
} else { // try to match
auto v = act->Results()[0];
auto pat = act->Results()[clause_num + 1];
std::optional<Env> matches = PatternMatch(pat, v, stmt->SourceLoc());
if (matches) { // we have a match, start the body
// Ensure we don't process any more clauses.
act->SetPos(2 * match_stmt.Clauses().size() + 1);
act->SetPos(2 * match_stmt.clauses().size() + 1);
for (const auto& [name, value] : *matches) {
frame->scopes.Top()->values.Set(name, value);
frame->scopes.Top()->locals.push_back(name);
}
return Spawn{arena->New<StatementAction>(c.second)};
return Spawn{arena->New<StatementAction>(&c.statement())};
} else {
return RunAgain{};
}
@@ -631,10 +631,10 @@ auto TypeChecker::TypeCheckCase(Nonnull<const Value*> expected,
Nonnull<Pattern*> pat, Nonnull<Statement*> body,
TypeEnv types, Env values,
Nonnull<ReturnTypeContext*> return_type_context)
-> std::pair<Nonnull<Pattern*>, Nonnull<Statement*>> {
-> Match::Clause {
auto pat_res = TypeCheckPattern(pat, types, values, expected);
auto res = TypeCheckStmt(body, pat_res.types, values, return_type_context);
return std::make_pair(pat, res.stmt);
return Match::Clause(pat, res.stmt);
}
auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
@@ -644,13 +644,12 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
switch (s->Tag()) {
case Statement::Kind::Match: {
auto& match = cast<Match>(*s);
auto res = TypeCheckExp(match.Exp(), types, values);
auto res = TypeCheckExp(&match.expression(), types, values);
auto res_type = res.type;
std::vector<std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>>
new_clauses;
for (auto& clause : match.Clauses()) {
new_clauses.push_back(TypeCheckCase(res_type, clause.first,
clause.second, types, values,
std::vector<Match::Clause> new_clauses;
for (auto& clause : match.clauses()) {
new_clauses.push_back(TypeCheckCase(res_type, &clause.pattern(),
&clause.statement(), types, values,
return_type_context));
}
auto new_s = arena->New<Match>(s->SourceLoc(), res.exp, new_clauses);
@@ -806,14 +805,14 @@ auto TypeChecker::CheckOrEnsureReturn(
switch (stmt->Tag()) {
case Statement::Kind::Match: {
auto& match = cast<Match>(*stmt);
std::vector<std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>>
new_clauses;
for (const auto& clause : match.Clauses()) {
auto s = CheckOrEnsureReturn(clause.second, omitted_ret_type,
std::vector<Match::Clause> new_clauses;
for (auto& clause : match.clauses()) {
auto s = CheckOrEnsureReturn(&clause.statement(), omitted_ret_type,
stmt->SourceLoc());
new_clauses.push_back(std::make_pair(clause.first, s));
new_clauses.push_back(Match::Clause(&clause.pattern(), s));
}
return arena->New<Match>(stmt->SourceLoc(), match.Exp(), new_clauses);
return arena->New<Match>(stmt->SourceLoc(), &match.expression(),
new_clauses);
}
case Statement::Kind::Block:
return arena->New<Block>(
@@ -130,7 +130,7 @@ class TypeChecker {
auto TypeCheckCase(Nonnull<const Value*> expected, Nonnull<Pattern*> pat,
Nonnull<Statement*> body, TypeEnv types, Env values,
Nonnull<ReturnTypeContext*> return_type_context)
-> std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>;
-> Match::Clause;
auto TypeOfFunDef(TypeEnv types, Env values, FunctionDefinition* fun_def)
-> Nonnull<const Value*>;