Add support for _ placeholder. (#661)

Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
This commit is contained in:
Geoff Romer
2021-07-19 10:33:06 -07:00
committed by GitHub
co-authored by Jon Meow
parent c3c89a77a4
commit def98d1182
15 changed files with 88 additions and 20 deletions
@@ -384,9 +384,13 @@ auto PatternMatch(const Value* p, const Value* v, Env values,
-> std::optional<Env> {
switch (p->tag()) {
case ValKind::BindingPlaceholderValue: {
Address a = state->heap.AllocateValue(CopyVal(v, line_num));
vars->push_back(p->GetBindingPlaceholderValue().name);
values.Set(p->GetBindingPlaceholderValue().name, a);
const BindingPlaceholderValue& placeholder =
p->GetBindingPlaceholderValue();
if (placeholder.name.has_value()) {
Address a = state->heap.AllocateValue(CopyVal(v, line_num));
vars->push_back(*placeholder.name);
values.Set(*placeholder.name, a);
}
return values;
}
case ValKind::TupleValue:
@@ -153,10 +153,12 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
} else if (expected) {
ExpectType(e->line_num, "pattern variable", t, expected);
}
auto new_e = Expression::MakeBindingExpression(
e->line_num, e->GetBindingExpression().name,
ReifyType(t, e->line_num));
types.Set(e->GetBindingExpression().name, t);
const std::optional<std::string>& name = e->GetBindingExpression().name;
auto new_e = Expression::MakeBindingExpression(e->line_num, name,
ReifyType(t, e->line_num));
if (name.has_value()) {
types.Set(*name, t);
}
return TCResult(new_e, t, types);
}
case ExpressionKind::IndexExpression: {
+10 -3
View File
@@ -171,8 +171,8 @@ auto Value::MakeContinuationValue(std::vector<Frame*> stack) -> Value* {
return v;
}
auto Value::MakeBindingPlaceholderValue(std::string name, const Value* type)
-> const Value* {
auto Value::MakeBindingPlaceholderValue(std::optional<std::string> name,
const Value* type) -> const Value* {
auto* v = new Value();
v->value = BindingPlaceholderValue({.name = std::move(name), .type = type});
return v;
@@ -352,8 +352,15 @@ auto PrintValue(const Value* val, std::ostream& out) -> void {
break;
}
case ValKind::BindingPlaceholderValue: {
const BindingPlaceholderValue& placeholder =
val->GetBindingPlaceholderValue();
if (placeholder.name.has_value()) {
out << *placeholder.name;
} else {
out << "_";
}
out << ": ";
PrintValue(val->GetBindingPlaceholderValue().type, out);
out << ": " << val->GetBindingPlaceholderValue().name;
break;
}
case ValKind::AlternativeValue: {
+4 -3
View File
@@ -110,7 +110,8 @@ struct TupleValue {
struct BindingPlaceholderValue {
static constexpr ValKind Kind = ValKind::BindingPlaceholderValue;
std::string name;
// nullopt represents the `_` placeholder
std::optional<std::string> name;
const Value* type;
};
@@ -183,8 +184,8 @@ struct Value {
static auto MakeAlternativeConstructorValue(std::string alt_name,
std::string choice_name)
-> const Value*;
static auto MakeBindingPlaceholderValue(std::string name, const Value* type)
-> const Value*;
static auto MakeBindingPlaceholderValue(std::optional<std::string> name,
const Value* type) -> const Value*;
static auto MakeIntType() -> const Value*;
static auto MakeContinuationType() -> const Value*;
static auto MakeAutoType() -> const Value*;