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
+3
View File
@@ -50,16 +50,19 @@ EXAMPLES = [
"global_variable6",
"global_variable7",
"global_variable8",
"ignored_parameter",
"if1",
"if2",
"if3",
"match_any_int",
"match_int_default",
"match_int",
"match_placeholder",
"match_type",
"next",
"pattern_init",
"pattern_variable_fail",
"placeholder_variable",
"record1",
"star",
"struct1",
+11 -4
View File
@@ -105,7 +105,8 @@ auto Expression::MakeIdentifierExpression(int line_num, std::string var)
return v;
}
auto Expression::MakeBindingExpression(int line_num, std::string var,
auto Expression::MakeBindingExpression(int line_num,
std::optional<std::string> var,
const Expression* type)
-> const Expression* {
auto* v = new Expression();
@@ -280,11 +281,17 @@ void PrintExp(const Expression* e) {
case ExpressionKind::IdentifierExpression:
std::cout << e->GetIdentifierExpression().name;
break;
case ExpressionKind::BindingExpression:
PrintExp(e->GetBindingExpression().type);
case ExpressionKind::BindingExpression: {
const BindingExpression& binding = e->GetBindingExpression();
if (binding.name.has_value()) {
std::cout << *binding.name;
} else {
std::cout << "_";
}
std::cout << ": ";
std::cout << e->GetBindingExpression().name;
PrintExp(e->GetBindingExpression().type);
break;
}
case ExpressionKind::CallExpression:
PrintExp(e->GetCallExpression().function);
if (e->GetCallExpression().argument->tag() ==
+5 -2
View File
@@ -5,6 +5,7 @@
#ifndef EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
#define EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
#include <optional>
#include <string>
#include <variant>
#include <vector>
@@ -74,7 +75,8 @@ struct IndexExpression {
struct BindingExpression {
static constexpr ExpressionKind Kind = ExpressionKind::BindingExpression;
std::string name;
// nullopt represents the `_` placeholder.
std::optional<std::string> name;
const Expression* type;
};
@@ -136,7 +138,8 @@ struct TypeTypeLiteral {
struct Expression {
static auto MakeIdentifierExpression(int line_num, std::string var)
-> const Expression*;
static auto MakeBindingExpression(int line_num, std::string var,
static auto MakeBindingExpression(int line_num,
std::optional<std::string> var,
const Expression* type)
-> const Expression*;
static auto MakeIntLiteral(int line_num, int i) -> const Expression*;
@@ -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*;
+2
View File
@@ -56,6 +56,7 @@ CONTINUATION_TYPE "__Continuation"
CONTINUATION "__continuation"
RUN "__run"
AWAIT "__await"
UNDERSCORE "_"
identifier [A-Za-z_][A-Za-z0-9_]*
integer_literal [0-9]+
@@ -116,6 +117,7 @@ operand_start [(A-Za-z0-9_"]
{CONTINUATION} { return yy::parser::make_CONTINUATION(context.current_token_position); }
{RUN} { return yy::parser::make_RUN(context.current_token_position); }
{AWAIT} { return yy::parser::make_AWAIT(context.current_token_position); }
{UNDERSCORE} { return yy::parser::make_UNDERSCORE(context.current_token_position); }
"=" return yy::parser::make_EQUAL(context.current_token_position);
"-" return yy::parser::make_MINUS(context.current_token_position);
+7 -1
View File
@@ -104,6 +104,7 @@ void yy::parser::error(
%type <const Carbon::Expression*> return_type
%type <const Carbon::Expression*> paren_expression
%type <const Carbon::Expression*> tuple
%type <std::optional<std::string>> binding_lhs
%type <Carbon::Member*> variable_declaration
%type <Carbon::Member*> member
%type <std::list<Carbon::Member*>> member_list
@@ -146,6 +147,7 @@ void yy::parser::error(
%token DBLARROW "=>"
%token DEFAULT
%token AUTO
%token UNDERSCORE
%token
EQUAL "="
MINUS "-"
@@ -199,6 +201,10 @@ pattern:
expression
{ $$ = $1; }
;
binding_lhs:
identifier { $$ = $1; }
| UNDERSCORE { $$ = std::nullopt; }
;
expression:
identifier
{ $$ = Carbon::Expression::MakeIdentifierExpression(yylineno, $1); }
@@ -206,7 +212,7 @@ expression:
{ $$ = Carbon::Expression::MakeFieldAccessExpression(yylineno, $1, $2); }
| expression "[" expression "]"
{ $$ = Carbon::Expression::MakeIndexExpression(yylineno, $1, $3); }
| identifier ":" expression
| binding_lhs ":" expression
{
$$ = Carbon::Expression::MakeBindingExpression(yylineno, $1, $3);
}
+11
View File
@@ -0,0 +1,11 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
fn ReturnSecond(_: Int, x: Int) -> Int {
return x;
}
fn main() -> Int {
return ReturnSecond(1, 0);
}
@@ -0,0 +1 @@
result: 0
+11
View File
@@ -0,0 +1,11 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
fn main() -> Int {
var t: auto = (1, 2, 3, 4);
match (t) {
case (_: Int, _: auto, x: Int, y: auto) =>
return y - x - 1;
}
}
@@ -0,0 +1 @@
result: 0
@@ -0,0 +1,8 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
fn main() -> Int {
var _: auto = 1;
return 0;
}
@@ -0,0 +1 @@
result: 0