mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-28 12:20:10 +01:00
Convert Pattern and Expression to Ptr (#787)
Sorry about the big change, this is hard to split. ParenContents is used by both, templated, and expects the same pointer type. While I could duplicate ParenContents with some ExpressionParenContents or PatternParenContents, that seems a little kludgy versus a single large change handling both. The worst of it is that Expression is already pretty sweeping, Pattern is really just incrementally adding. That said, I believe this includes a couple fixes I found with incorrect use of dyn_cast in typecheck.cpp (checked nullptr at the wrong step in 2 code locations). There's also a missing `*` in member.cpp this caught. I adjust passing of expressions for Return due to nullness (I felt adding another constructor was the best solution). I add a `.Release()` to BisonWrap due to things like `$3.first` needing some way to work through BIsonWrap. I felt this was better than `operator->`, but feel free to comment if you prefer the other path (`.Release()` conveniently lets me do pair unwrapping, so it felt a better solution). I do add a TODO to think about better Ptr-to-Ptr cast<> support too, though, as that doesn't work cleanly with LLVM's infra. But so far it seems to only come up in one spot, so I'm not prioritizing it.
This commit is contained in:
@@ -142,9 +142,9 @@ void InitEnv(const Declaration& d, Env* env) {
|
||||
for (Ptr<const Member> m : class_def.members) {
|
||||
switch (m->Tag()) {
|
||||
case Member::Kind::FieldMember: {
|
||||
const BindingPattern* binding = cast<FieldMember>(*m).Binding();
|
||||
const Expression* type_expression =
|
||||
cast<ExpressionPattern>(binding->Type())->Expression();
|
||||
Ptr<const BindingPattern> binding = cast<FieldMember>(*m).Binding();
|
||||
Ptr<const Expression> type_expression =
|
||||
cast<ExpressionPattern>(*binding->Type()).Expression();
|
||||
auto type = InterpExp(Env(), type_expression);
|
||||
fields.push_back(make_pair(*binding->Name(), type));
|
||||
break;
|
||||
@@ -205,7 +205,7 @@ void DeallocateLocals(Ptr<Frame> frame) {
|
||||
}
|
||||
}
|
||||
|
||||
const Value* CreateTuple(Ptr<Action> act, const Expression* exp) {
|
||||
const Value* CreateTuple(Ptr<Action> act, Ptr<const Expression> exp) {
|
||||
// { { (v1,...,vn) :: C, E, F} :: S, H}
|
||||
// -> { { `(v1,...,vn) :: C, E, F} :: S, H}
|
||||
const auto& tup_lit = cast<TupleLiteral>(*exp);
|
||||
@@ -431,7 +431,7 @@ using Transition =
|
||||
// State transitions for lvalues.
|
||||
Transition StepLvalue() {
|
||||
Ptr<Action> act = state->stack.Top()->todo.Top();
|
||||
const Expression* exp = cast<LValAction>(*act).Exp();
|
||||
Ptr<const Expression> exp = cast<LValAction>(*act).Exp();
|
||||
if (tracing_output) {
|
||||
llvm::outs() << "--- step lvalue " << *exp << " --->\n";
|
||||
}
|
||||
@@ -483,7 +483,8 @@ Transition StepLvalue() {
|
||||
if (act->Pos() == 0) {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
const Expression* e1 = cast<TupleLiteral>(*exp).Fields()[0].expression;
|
||||
Ptr<const Expression> e1 =
|
||||
cast<TupleLiteral>(*exp).Fields()[0].expression;
|
||||
return Spawn{global_arena->New<LValAction>(e1)};
|
||||
} else if (act->Pos() !=
|
||||
static_cast<int>(cast<TupleLiteral>(*exp).Fields().size())) {
|
||||
@@ -491,7 +492,7 @@ Transition StepLvalue() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Expression* elt =
|
||||
Ptr<const Expression> elt =
|
||||
cast<TupleLiteral>(*exp).Fields()[act->Pos()].expression;
|
||||
return Spawn{global_arena->New<LValAction>(elt)};
|
||||
} else {
|
||||
@@ -518,7 +519,7 @@ Transition StepLvalue() {
|
||||
// State transitions for expressions.
|
||||
Transition StepExp() {
|
||||
Ptr<Action> act = state->stack.Top()->todo.Top();
|
||||
const Expression* exp = cast<ExpressionAction>(*act).Exp();
|
||||
Ptr<const Expression> exp = cast<ExpressionAction>(*act).Exp();
|
||||
if (tracing_output) {
|
||||
llvm::outs() << "--- step exp " << *exp << " --->\n";
|
||||
}
|
||||
@@ -555,7 +556,7 @@ Transition StepExp() {
|
||||
if (cast<TupleLiteral>(*exp).Fields().size() > 0) {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
const Expression* e1 =
|
||||
Ptr<const Expression> e1 =
|
||||
cast<TupleLiteral>(*exp).Fields()[0].expression;
|
||||
return Spawn{global_arena->New<ExpressionAction>(e1)};
|
||||
} else {
|
||||
@@ -567,7 +568,7 @@ Transition StepExp() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Expression* elt =
|
||||
Ptr<const Expression> elt =
|
||||
cast<TupleLiteral>(*exp).Fields()[act->Pos()].expression;
|
||||
return Spawn{global_arena->New<ExpressionAction>(elt)};
|
||||
} else {
|
||||
@@ -608,7 +609,7 @@ Transition StepExp() {
|
||||
if (act->Pos() != static_cast<int>(op.Arguments().size())) {
|
||||
// { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
|
||||
// -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H}
|
||||
const Expression* arg = op.Arguments()[act->Pos()];
|
||||
Ptr<const Expression> arg = op.Arguments()[act->Pos()];
|
||||
return Spawn{global_arena->New<ExpressionAction>(arg)};
|
||||
} else {
|
||||
// { {v :: op(vs,[]) :: C, E, F} :: S, H}
|
||||
@@ -715,7 +716,7 @@ Transition StepExp() {
|
||||
|
||||
Transition StepPattern() {
|
||||
Ptr<Action> act = state->stack.Top()->todo.Top();
|
||||
const Pattern* pattern = cast<PatternAction>(*act).Pat();
|
||||
Ptr<const Pattern> pattern = cast<PatternAction>(*act).Pat();
|
||||
if (tracing_output) {
|
||||
llvm::outs() << "--- step pattern " << *pattern << " --->\n";
|
||||
}
|
||||
@@ -739,7 +740,7 @@ Transition StepPattern() {
|
||||
if (tuple.Fields().empty()) {
|
||||
return Done{&TupleValue::Empty()};
|
||||
} else {
|
||||
const Pattern* p1 = tuple.Fields()[0].pattern;
|
||||
Ptr<const Pattern> p1 = tuple.Fields()[0].pattern;
|
||||
return Spawn{(global_arena->New<PatternAction>(p1))};
|
||||
}
|
||||
} else if (act->Pos() != static_cast<int>(tuple.Fields().size())) {
|
||||
@@ -747,7 +748,7 @@ Transition StepPattern() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Pattern* elt = tuple.Fields()[act->Pos()].pattern;
|
||||
Ptr<const Pattern> elt = tuple.Fields()[act->Pos()].pattern;
|
||||
return Spawn{global_arena->New<PatternAction>(elt)};
|
||||
} else {
|
||||
std::vector<TupleElement> elements;
|
||||
@@ -775,7 +776,7 @@ Transition StepPattern() {
|
||||
}
|
||||
case Pattern::Kind::ExpressionPattern:
|
||||
return Delegate{global_arena->New<ExpressionAction>(
|
||||
cast<ExpressionPattern>(pattern)->Expression())};
|
||||
cast<ExpressionPattern>(*pattern).Expression())};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,8 +1046,7 @@ Transition StepStmt() {
|
||||
Stack<Ptr<Scope>>(global_arena->New<Scope>(CurrentEnv(state)));
|
||||
Stack<Ptr<Action>> todo;
|
||||
todo.Push(global_arena->New<StatementAction>(
|
||||
global_arena->RawNew<Return>(stmt->SourceLoc(), nullptr,
|
||||
/*is_omitted_exp=*/true)));
|
||||
global_arena->RawNew<Return>(stmt->SourceLoc())));
|
||||
todo.Push(
|
||||
global_arena->New<StatementAction>(cast<Continuation>(*stmt).Body()));
|
||||
auto continuation_frame =
|
||||
@@ -1076,7 +1076,7 @@ Transition StepStmt() {
|
||||
auto ignore_result = global_arena->New<StatementAction>(
|
||||
global_arena->RawNew<ExpressionStatement>(
|
||||
stmt->SourceLoc(),
|
||||
global_arena->RawNew<TupleLiteral>(stmt->SourceLoc())));
|
||||
global_arena->New<TupleLiteral>(stmt->SourceLoc())));
|
||||
frame->todo.Push(ignore_result);
|
||||
// Push the continuation onto the current stack.
|
||||
const std::vector<Ptr<Frame>>& continuation_vector =
|
||||
@@ -1217,9 +1217,9 @@ auto InterpProgram(const std::list<Ptr<const Declaration>>& fs) -> int {
|
||||
|
||||
SourceLocation loc("<InterpProgram()>", 0);
|
||||
|
||||
const Expression* arg = global_arena->RawNew<TupleLiteral>(loc);
|
||||
const Expression* call_main = global_arena->RawNew<CallExpression>(
|
||||
loc, global_arena->RawNew<IdentifierExpression>(loc, "main"), arg);
|
||||
Ptr<const Expression> arg = global_arena->New<TupleLiteral>(loc);
|
||||
Ptr<const Expression> call_main = global_arena->New<CallExpression>(
|
||||
loc, global_arena->New<IdentifierExpression>(loc, "main"), arg);
|
||||
auto todo =
|
||||
Stack<Ptr<Action>>(global_arena->New<ExpressionAction>(call_main));
|
||||
auto scopes = Stack<Ptr<Scope>>(global_arena->New<Scope>(globals));
|
||||
@@ -1241,7 +1241,7 @@ auto InterpProgram(const std::list<Ptr<const Declaration>>& fs) -> int {
|
||||
}
|
||||
|
||||
// Interpret an expression at compile-time.
|
||||
auto InterpExp(Env values, const Expression* e) -> const Value* {
|
||||
auto InterpExp(Env values, Ptr<const Expression> e) -> const Value* {
|
||||
CHECK(state->program_value == std::nullopt);
|
||||
auto program_value_guard =
|
||||
llvm::make_scope_exit([] { state->program_value = std::nullopt; });
|
||||
@@ -1258,7 +1258,7 @@ auto InterpExp(Env values, const Expression* e) -> const Value* {
|
||||
}
|
||||
|
||||
// Interpret a pattern at compile-time.
|
||||
auto InterpPattern(Env values, const Pattern* p) -> const Value* {
|
||||
auto InterpPattern(Env values, Ptr<const Pattern> p) -> const Value* {
|
||||
CHECK(state->program_value == std::nullopt);
|
||||
auto program_value_guard =
|
||||
llvm::make_scope_exit([] { state->program_value = std::nullopt; });
|
||||
|
||||
Reference in New Issue
Block a user