mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-29 15:24:58 +01:00
Add support for _ placeholder. (#661)
Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
co-authored by
Jon Meow
parent
c3c89a77a4
commit
def98d1182
@@ -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",
|
||||
|
||||
@@ -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,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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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*;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user