mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:41:27 +01:00
Add support for return; (#678)
This creates a ReturnExpression. A separate change should enforce that an implicit return of `()` is only allowed in functions that have an implicit return type of `()`, and I think the structure taken here should ease that.
This commit is contained in:
@@ -100,12 +100,17 @@ auto Expression::MakeContinuationTypeLiteral(int line_num)
|
||||
return type;
|
||||
}
|
||||
|
||||
auto Expression::MakeFunctionTypeLiteral(int line_num, const Expression* param,
|
||||
const Expression* ret)
|
||||
auto Expression::MakeFunctionTypeLiteral(int line_num,
|
||||
const Expression* parameter,
|
||||
const Expression* return_type,
|
||||
bool is_omitted_return_type)
|
||||
-> const Expression* {
|
||||
auto* t = global_arena->New<Expression>();
|
||||
t->line_num = line_num;
|
||||
t->value = FunctionTypeLiteral({.parameter = param, .return_type = ret});
|
||||
t->value =
|
||||
FunctionTypeLiteral({.parameter = parameter,
|
||||
.return_type = return_type,
|
||||
.is_omitted_return_type = is_omitted_return_type});
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ struct FunctionTypeLiteral {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::FunctionTypeLiteral;
|
||||
const Expression* parameter;
|
||||
const Expression* return_type;
|
||||
bool is_omitted_return_type;
|
||||
};
|
||||
|
||||
struct BoolTypeLiteral {
|
||||
@@ -162,8 +163,9 @@ struct Expression {
|
||||
static auto MakeTypeTypeLiteral(int line_num) -> const Expression*;
|
||||
static auto MakeIntTypeLiteral(int line_num) -> const Expression*;
|
||||
static auto MakeBoolTypeLiteral(int line_num) -> const Expression*;
|
||||
static auto MakeFunctionTypeLiteral(int line_num, const Expression* param,
|
||||
const Expression* ret)
|
||||
static auto MakeFunctionTypeLiteral(int line_num, const Expression* parameter,
|
||||
const Expression* return_type,
|
||||
bool is_omitted_return_type)
|
||||
-> const Expression*;
|
||||
static auto MakeContinuationTypeLiteral(int line_num) -> const Expression*;
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ void FunctionDefinition::PrintDepth(int depth, llvm::raw_ostream& out) const {
|
||||
}
|
||||
out << "]";
|
||||
}
|
||||
out << *param_pattern << " -> " << *return_type;
|
||||
out << *param_pattern;
|
||||
if (!is_omitted_return_type) {
|
||||
out << " -> " << *return_type;
|
||||
}
|
||||
if (body) {
|
||||
out << " {\n";
|
||||
body->PrintDepth(depth, out);
|
||||
|
||||
@@ -25,12 +25,14 @@ struct FunctionDefinition {
|
||||
FunctionDefinition(int line_num, std::string name,
|
||||
std::vector<GenericBinding> deduced_params,
|
||||
const TuplePattern* param_pattern,
|
||||
const Pattern* return_type, const Statement* body)
|
||||
const Pattern* return_type, bool is_omitted_return_type,
|
||||
const Statement* body)
|
||||
: line_num(line_num),
|
||||
name(std::move(name)),
|
||||
deduced_parameters(deduced_params),
|
||||
param_pattern(param_pattern),
|
||||
return_type(return_type),
|
||||
is_omitted_return_type(is_omitted_return_type),
|
||||
body(body) {}
|
||||
|
||||
void Print(llvm::raw_ostream& out) const { PrintDepth(-1, out); }
|
||||
@@ -42,6 +44,7 @@ struct FunctionDefinition {
|
||||
std::vector<GenericBinding> deduced_parameters;
|
||||
const TuplePattern* param_pattern;
|
||||
const Pattern* return_type;
|
||||
bool is_omitted_return_type;
|
||||
const Statement* body;
|
||||
};
|
||||
|
||||
|
||||
@@ -117,11 +117,15 @@ auto Statement::MakeContinue(int line_num) -> const Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeReturn(int line_num, const Expression* e)
|
||||
-> const Statement* {
|
||||
auto Statement::MakeReturn(int line_num, const Expression* exp,
|
||||
bool is_omitted_exp) -> const Statement* {
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Return({.exp = e});
|
||||
if (exp == nullptr) {
|
||||
CHECK(is_omitted_exp);
|
||||
exp = Expression::MakeTupleLiteral(line_num, {});
|
||||
}
|
||||
s->value = Return({.exp = exp, .is_omitted_exp = is_omitted_exp});
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -230,7 +234,11 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const {
|
||||
}
|
||||
break;
|
||||
case StatementKind::Return:
|
||||
out << "return " << *GetReturn().exp << ";";
|
||||
if (GetReturn().is_omitted_exp) {
|
||||
out << "return;";
|
||||
} else {
|
||||
out << "return " << *GetReturn().exp << ";";
|
||||
}
|
||||
break;
|
||||
case StatementKind::Sequence:
|
||||
GetSequence().stmt->PrintDepth(depth, out);
|
||||
|
||||
@@ -60,6 +60,7 @@ struct If {
|
||||
struct Return {
|
||||
static constexpr StatementKind Kind = StatementKind::Return;
|
||||
const Expression* exp;
|
||||
bool is_omitted_exp;
|
||||
};
|
||||
|
||||
struct Sequence {
|
||||
@@ -120,7 +121,8 @@ struct Statement {
|
||||
static auto MakeIf(int line_num, const Expression* cond,
|
||||
const Statement* then_stmt, const Statement* else_stmt)
|
||||
-> const Statement*;
|
||||
static auto MakeReturn(int line_num, const Expression* e) -> const Statement*;
|
||||
static auto MakeReturn(int line_num, const Expression* exp,
|
||||
bool is_omitted_exp) -> const Statement*;
|
||||
static auto MakeSequence(int line_num, const Statement* s1,
|
||||
const Statement* s2) -> const Statement*;
|
||||
static auto MakeBlock(int line_num, const Statement* s) -> const Statement*;
|
||||
|
||||
Reference in New Issue
Block a user