Add underscores to private data members (#898)

This is the last PR I plan to have focused on #720
This commit is contained in:
Jon Meow
2021-10-19 14:27:10 -07:00
committed by GitHub
parent dc9c36660b
commit ffa4e76ede
17 changed files with 363 additions and 356 deletions
+6 -6
View File
@@ -17,9 +17,9 @@ class SourceLocation {
public:
// The filename should be eternal or arena-allocated to eliminate copies.
SourceLocation(const char* filename, int line_num)
: filename(filename), line_num(line_num) {}
: filename_(filename), line_num_(line_num) {}
SourceLocation(Nonnull<const std::string*> filename, int line_num)
: filename(filename->c_str()), line_num(line_num) {}
: filename_(filename->c_str()), line_num_(line_num) {}
SourceLocation(const SourceLocation&) = default;
SourceLocation(SourceLocation&&) = default;
@@ -27,17 +27,17 @@ class SourceLocation {
auto operator=(SourceLocation&&) -> SourceLocation& = default;
bool operator==(SourceLocation other) const {
return filename == other.filename && line_num == other.line_num;
return filename_ == other.filename_ && line_num_ == other.line_num_;
}
void Print(llvm::raw_ostream& out) const {
out << filename << ":" << line_num;
out << filename_ << ":" << line_num_;
}
LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
private:
std::string_view filename;
int line_num;
std::string_view filename_;
int line_num_;
};
} // namespace Carbon
+5 -5
View File
@@ -20,7 +20,7 @@ class Arena {
auto smart_ptr =
std::make_unique<ArenaEntryTyped<T>>(std::forward<Args>(args)...);
Nonnull<T*> ptr = smart_ptr->Instance();
arena.push_back(std::move(smart_ptr));
arena_.push_back(std::move(smart_ptr));
return ptr;
}
@@ -38,16 +38,16 @@ class Arena {
public:
template <typename... Args>
explicit ArenaEntryTyped(Args&&... args)
: instance(std::forward<Args>(args)...) {}
: instance_(std::forward<Args>(args)...) {}
auto Instance() -> Nonnull<T*> { return Nonnull<T*>(&instance); }
auto Instance() -> Nonnull<T*> { return Nonnull<T*>(&instance_); }
private:
T instance;
T instance_;
};
// Manages allocations in an arena for destruction at shutdown.
std::vector<std::unique_ptr<ArenaEntry>> arena;
std::vector<std::unique_ptr<ArenaEntry>> arena_;
};
} // namespace Carbon
+6 -6
View File
@@ -27,7 +27,7 @@ class Address {
// Returns true if the two addresses refer to the same memory location.
friend auto operator==(const Address& lhs, const Address& rhs) -> bool {
return lhs.index == rhs.index;
return lhs.index_ == rhs.index_;
}
friend auto operator!=(const Address& lhs, const Address& rhs) -> bool {
@@ -40,7 +40,7 @@ class Address {
// the whole memory allocation, and an optional FieldPath specifying a
// particular field within that allocation.
void Print(llvm::raw_ostream& out) const {
out << "Address(" << index << ")" << field_path;
out << "Address(" << index_ << ")" << field_path_;
}
LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
@@ -49,7 +49,7 @@ class Address {
// `field_name`, this method returns the address of that field.
auto SubobjectAddress(std::string field_name) const -> Address {
Address result = *this;
result.field_path.Append(std::move(field_name));
result.field_path_.Append(std::move(field_name));
return result;
}
@@ -59,10 +59,10 @@ class Address {
// details of the Heap.
friend class Heap;
explicit Address(uint64_t index) : index(index) {}
explicit Address(uint64_t index) : index_(index) {}
uint64_t index;
FieldPath field_path;
uint64_t index_;
FieldPath field_path_;
};
} // namespace Carbon
+14 -14
View File
@@ -44,10 +44,10 @@ class Dictionary {
// NOLINTNEXTLINE(readability-identifier-naming)
using iterator_category = std::forward_iterator_tag;
explicit Iterator(std::optional<Nonnull<Node*>> x) : p(x) {}
Iterator(const Iterator& iter) : p(iter.p) {}
explicit Iterator(std::optional<Nonnull<Node*>> x) : p_(x) {}
Iterator(const Iterator& iter) : p_(iter.p_) {}
auto operator++() -> Iterator& {
p = (*p)->next;
p_ = (*p_)->next;
return *this;
}
auto operator++(int) -> Iterator {
@@ -55,17 +55,17 @@ class Dictionary {
operator++();
return tmp;
}
auto operator==(const Iterator& rhs) const -> bool { return p == rhs.p; }
auto operator!=(const Iterator& rhs) const -> bool { return p != rhs.p; }
auto operator*() -> const value_type& { return (*p)->curr; }
auto operator->() -> const value_type* { return &(*p)->curr; }
auto operator==(const Iterator& rhs) const -> bool { return p_ == rhs.p_; }
auto operator!=(const Iterator& rhs) const -> bool { return p_ != rhs.p_; }
auto operator*() -> const value_type& { return (*p_)->curr; }
auto operator->() -> const value_type* { return &(*p_)->curr; }
private:
std::optional<Nonnull<Node*>> p;
std::optional<Nonnull<Node*>> p_;
};
// Create an empty dictionary.
explicit Dictionary(Nonnull<Arena*> arena) : arena(arena) {}
explicit Dictionary(Nonnull<Arena*> arena) : arena_(arena) {}
// Return the value associated with the given key.
// Time complexity: O(n) where n is the number of times
@@ -82,21 +82,21 @@ class Dictionary {
// Associate the value v with key k in the dictionary.
// Time complexity: O(1).
auto Set(const K& k, const V& v) -> void {
head = arena->New<Node>(std::make_pair(k, v), head);
head_ = arena_->New<Node>(std::make_pair(k, v), head_);
}
auto IsEmpty() -> bool { return !head; }
auto IsEmpty() -> bool { return !head_; }
// The position of the first element of the dictionary
// or `end()` if the dictionary is empty.
auto begin() const -> Iterator { return Iterator(head); }
auto begin() const -> Iterator { return Iterator(head_); }
// The position one past that of the last element.
auto end() const -> Iterator { return Iterator(std::nullopt); }
private:
std::optional<Nonnull<Node*>> head;
Nonnull<Arena*> arena;
std::optional<Nonnull<Node*>> head_;
Nonnull<Arena*> arena_;
};
} // namespace Carbon
@@ -30,7 +30,7 @@ class FieldPath {
FieldPath() = default;
// Constructs a FieldPath consisting of a single step.
explicit FieldPath(std::string name) : components({std::move(name)}) {}
explicit FieldPath(std::string name) : components_({std::move(name)}) {}
FieldPath(const FieldPath&) = default;
FieldPath(FieldPath&&) = default;
@@ -38,15 +38,15 @@ class FieldPath {
auto operator=(FieldPath&&) -> FieldPath& = default;
// Returns whether *this is empty.
auto IsEmpty() const -> bool { return components.empty(); }
auto IsEmpty() const -> bool { return components_.empty(); }
// Appends `name` to the end of *this.
auto Append(std::string name) -> void {
components.push_back(std::move(name));
components_.push_back(std::move(name));
}
void Print(llvm::raw_ostream& out) const {
for (const std::string& component : components) {
for (const std::string& component : components_) {
out << "." << component;
}
}
@@ -58,7 +58,7 @@ class FieldPath {
// another Value, so its implementation details are tied to the implementation
// details of Value.
friend class Value;
std::vector<std::string> components;
std::vector<std::string> components_;
};
} // namespace Carbon
+14 -14
View File
@@ -14,37 +14,37 @@ auto Heap::AllocateValue(Nonnull<const Value*> v) -> Address {
// ensures that we don't do anything else in between, which is really bad!
// Consider whether to include a copy of the input v in this function
// or to leave it up to the caller.
Address a(values.size());
values.push_back(v);
alive.push_back(true);
Address a(values_.size());
values_.push_back(v);
alive_.push_back(true);
return a;
}
auto Heap::Read(const Address& a, SourceLocation source_loc)
-> Nonnull<const Value*> {
this->CheckAlive(a, source_loc);
return values[a.index]->GetField(arena, a.field_path, source_loc);
return values_[a.index_]->GetField(arena_, a.field_path_, source_loc);
}
void Heap::Write(const Address& a, Nonnull<const Value*> v,
SourceLocation source_loc) {
this->CheckAlive(a, source_loc);
values[a.index] =
values[a.index]->SetField(arena, a.field_path, v, source_loc);
values_[a.index_] =
values_[a.index_]->SetField(arena_, a.field_path_, v, source_loc);
}
void Heap::CheckAlive(const Address& address, SourceLocation source_loc) {
if (!alive[address.index]) {
if (!alive_[address.index_]) {
FATAL_RUNTIME_ERROR(source_loc)
<< "undefined behavior: access to dead value "
<< *values[address.index];
<< *values_[address.index_];
}
}
void Heap::Deallocate(const Address& address) {
CHECK(address.field_path.IsEmpty());
if (alive[address.index]) {
alive[address.index] = false;
CHECK(address.field_path_.IsEmpty());
if (alive_[address.index_]) {
alive_[address.index_] = false;
} else {
FATAL_RUNTIME_ERROR_NO_LINE() << "deallocating an already dead value";
}
@@ -52,17 +52,17 @@ void Heap::Deallocate(const Address& address) {
void Heap::Print(llvm::raw_ostream& out) const {
llvm::ListSeparator sep;
for (size_t i = 0; i < values.size(); ++i) {
for (size_t i = 0; i < values_.size(); ++i) {
out << sep;
PrintAddress(Address(i), out);
}
}
void Heap::PrintAddress(const Address& a, llvm::raw_ostream& out) const {
if (!alive[a.index]) {
if (!alive_[a.index_]) {
out << "!!";
}
out << *values[a.index];
out << *values_[a.index_];
}
} // namespace Carbon
+4 -4
View File
@@ -18,7 +18,7 @@ namespace Carbon {
class Heap {
public:
// Constructs an empty Heap.
explicit Heap(Nonnull<Arena*> arena) : arena(arena){};
explicit Heap(Nonnull<Arena*> arena) : arena_(arena){};
Heap(const Heap&) = delete;
auto operator=(const Heap&) -> Heap& = delete;
@@ -51,9 +51,9 @@ class Heap {
// Signal an error if the address is no longer alive.
void CheckAlive(const Address& address, SourceLocation source_loc);
Nonnull<Arena*> arena;
std::vector<Nonnull<const Value*>> values;
std::vector<bool> alive;
Nonnull<Arena*> arena_;
std::vector<Nonnull<const Value*>> values_;
std::vector<bool> alive_;
};
} // namespace Carbon
+174 -170
View File
@@ -36,7 +36,7 @@ void Interpreter::PrintEnv(Env values, llvm::raw_ostream& out) {
llvm::ListSeparator sep;
for (const auto& [name, address] : values) {
out << sep << name << ": ";
heap.PrintAddress(address, out);
heap_.PrintAddress(address, out);
}
}
@@ -45,7 +45,7 @@ void Interpreter::PrintEnv(Env values, llvm::raw_ostream& out) {
//
auto Interpreter::CurrentEnv() -> Env {
Nonnull<Frame*> frame = stack.Top();
Nonnull<Frame*> frame = stack_.Top();
return frame->scopes.Top()->values;
}
@@ -62,11 +62,11 @@ auto Interpreter::GetFromEnv(SourceLocation source_loc, const std::string& name)
void Interpreter::PrintState(llvm::raw_ostream& out) {
out << "{\nstack: ";
llvm::ListSeparator sep(" :: ");
for (const auto& frame : stack) {
for (const auto& frame : stack_) {
out << sep << *frame;
}
out << "\nheap: " << heap;
if (!stack.IsEmpty() && !stack.Top()->scopes.IsEmpty()) {
out << "\nheap: " << heap_;
if (!stack_.IsEmpty() && !stack_.Top()->scopes.IsEmpty()) {
out << "\nvalues: ";
PrintEnv(CurrentEnv(), out);
}
@@ -78,28 +78,28 @@ auto Interpreter::EvalPrim(Operator op,
SourceLocation source_loc) -> Nonnull<const Value*> {
switch (op) {
case Operator::Neg:
return arena->New<IntValue>(-cast<IntValue>(*args[0]).value());
return arena_->New<IntValue>(-cast<IntValue>(*args[0]).value());
case Operator::Add:
return arena->New<IntValue>(cast<IntValue>(*args[0]).value() +
cast<IntValue>(*args[1]).value());
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() +
cast<IntValue>(*args[1]).value());
case Operator::Sub:
return arena->New<IntValue>(cast<IntValue>(*args[0]).value() -
cast<IntValue>(*args[1]).value());
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() -
cast<IntValue>(*args[1]).value());
case Operator::Mul:
return arena->New<IntValue>(cast<IntValue>(*args[0]).value() *
cast<IntValue>(*args[1]).value());
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() *
cast<IntValue>(*args[1]).value());
case Operator::Not:
return arena->New<BoolValue>(!cast<BoolValue>(*args[0]).value());
return arena_->New<BoolValue>(!cast<BoolValue>(*args[0]).value());
case Operator::And:
return arena->New<BoolValue>(cast<BoolValue>(*args[0]).value() &&
cast<BoolValue>(*args[1]).value());
return arena_->New<BoolValue>(cast<BoolValue>(*args[0]).value() &&
cast<BoolValue>(*args[1]).value());
case Operator::Or:
return arena->New<BoolValue>(cast<BoolValue>(*args[0]).value() ||
cast<BoolValue>(*args[1]).value());
return arena_->New<BoolValue>(cast<BoolValue>(*args[0]).value() ||
cast<BoolValue>(*args[1]).value());
case Operator::Eq:
return arena->New<BoolValue>(ValueEqual(args[0], args[1], source_loc));
return arena_->New<BoolValue>(ValueEqual(args[0], args[1], source_loc));
case Operator::Ptr:
return arena->New<PointerType>(args[0]);
return arena_->New<PointerType>(args[0]);
case Operator::Deref:
FATAL() << "dereference not implemented yet";
}
@@ -112,12 +112,13 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
Env new_env = *env;
// Bring the deduced parameters into scope.
for (const auto& deduced : func_def.deduced_parameters()) {
Address a = heap.AllocateValue(arena->New<VariableType>(deduced.name));
Address a =
heap_.AllocateValue(arena_->New<VariableType>(deduced.name));
new_env.Set(deduced.name, a);
}
auto pt = InterpPattern(new_env, &func_def.param_pattern());
auto f = arena->New<FunctionValue>(func_def.name(), pt, func_def.body());
Address a = heap.AllocateValue(f);
auto f = arena_->New<FunctionValue>(func_def.name(), pt, func_def.body());
Address a = heap_.AllocateValue(f);
env->Set(func_def.name(), a);
break;
}
@@ -132,15 +133,15 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
const BindingPattern& binding = cast<FieldMember>(*m).binding();
const Expression& type_expression =
cast<ExpressionPattern>(binding.type()).expression();
auto type = InterpExp(Env(arena), &type_expression);
auto type = InterpExp(Env(arena_), &type_expression);
fields.push_back(make_pair(*binding.name(), type));
break;
}
}
}
auto st = arena->New<NominalClassType>(
auto st = arena_->New<NominalClassType>(
class_def.name(), std::move(fields), std::move(methods));
auto a = heap.AllocateValue(st);
auto a = heap_.AllocateValue(st);
env->Set(class_def.name(), a);
break;
}
@@ -149,11 +150,11 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
const auto& choice = cast<ChoiceDeclaration>(d);
VarValues alts;
for (const auto& alternative : choice.alternatives()) {
auto t = InterpExp(Env(arena), &alternative.signature());
auto t = InterpExp(Env(arena_), &alternative.signature());
alts.push_back(make_pair(alternative.name(), t));
}
auto ct = arena->New<ChoiceType>(choice.name(), std::move(alts));
auto a = heap.AllocateValue(ct);
auto ct = arena_->New<ChoiceType>(choice.name(), std::move(alts));
auto a = heap_.AllocateValue(ct);
env->Set(choice.name(), a);
break;
}
@@ -163,7 +164,7 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
// Adds an entry in `globals` mapping the variable's name to the
// result of evaluating the initializer.
auto v = InterpExp(*env, &var.initializer());
Address a = heap.AllocateValue(v);
Address a = heap_.AllocateValue(v);
env->Set(*var.binding().name(), a);
break;
}
@@ -172,7 +173,7 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
void Interpreter::InitGlobals(llvm::ArrayRef<Nonnull<Declaration*>> fs) {
for (const auto d : fs) {
InitEnv(*d, &globals);
InitEnv(*d, &globals_);
}
}
@@ -180,7 +181,7 @@ void Interpreter::DeallocateScope(Nonnull<Scope*> scope) {
for (const auto& l : scope->locals) {
std::optional<Address> a = scope->values.Get(l);
CHECK(a);
heap.Deallocate(*a);
heap_.Deallocate(*a);
}
}
@@ -198,7 +199,7 @@ auto Interpreter::CreateTuple(Nonnull<Action*> act,
// -> { { `(v1,...,vn) :: C, E, F} :: S, H}
const auto& tup_lit = cast<TupleLiteral>(*exp);
CHECK(act->results().size() == tup_lit.fields().size());
return arena->New<TupleValue>(act->results());
return arena_->New<TupleValue>(act->results());
}
auto Interpreter::CreateStruct(const std::vector<FieldInitializer>& fields,
@@ -210,7 +211,7 @@ auto Interpreter::CreateStruct(const std::vector<FieldInitializer>& fields,
elements.push_back({.name = fields[i].name(), .value = values[i]});
}
return arena->New<StructValue>(std::move(elements));
return arena_->New<StructValue>(std::move(elements));
}
auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
@@ -219,9 +220,9 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
switch (p->kind()) {
case Value::Kind::BindingPlaceholderValue: {
const auto& placeholder = cast<BindingPlaceholderValue>(*p);
Env values(arena);
Env values(arena_);
if (placeholder.name().has_value()) {
Address a = heap.AllocateValue(v);
Address a = heap_.AllocateValue(v);
values.Set(*placeholder.name(), a);
}
return values;
@@ -236,7 +237,7 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
<< "arity mismatch in tuple pattern match:\n pattern: "
<< p_tup << "\n value: " << v_tup;
}
Env values(arena);
Env values(arena_);
for (size_t i = 0; i < p_tup.elements().size(); ++i) {
std::optional<Env> matches = PatternMatch(
p_tup.elements()[i], v_tup.elements()[i], source_loc);
@@ -256,7 +257,7 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
const auto& p_struct = cast<StructValue>(*p);
const auto& v_struct = cast<StructValue>(*v);
CHECK(p_struct.elements().size() == v_struct.elements().size());
Env values(arena);
Env values(arena_);
for (size_t i = 0; i < p_struct.elements().size(); ++i) {
CHECK(p_struct.elements()[i].name == v_struct.elements()[i].name);
std::optional<Env> matches =
@@ -312,10 +313,10 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
case Value::Kind::AutoType:
// `auto` matches any type, without binding any new names. We rely
// on the typechecker to ensure that `v` is a type.
return Env(arena);
return Env(arena_);
default:
if (ValueEqual(p, v, source_loc)) {
return Env(arena);
return Env(arena_);
} else {
return std::nullopt;
}
@@ -327,7 +328,7 @@ void Interpreter::PatternAssignment(Nonnull<const Value*> pat,
SourceLocation source_loc) {
switch (pat->kind()) {
case Value::Kind::PointerValue:
heap.Write(cast<PointerValue>(*pat).value(), val, source_loc);
heap_.Write(cast<PointerValue>(*pat).value(), val, source_loc);
break;
case Value::Kind::TupleValue: {
switch (val->kind()) {
@@ -374,7 +375,7 @@ void Interpreter::PatternAssignment(Nonnull<const Value*> pat,
}
auto Interpreter::StepLvalue() -> Transition {
Nonnull<Action*> act = stack.Top()->todo.Top();
Nonnull<Action*> act = stack_.Top()->todo.Top();
const Expression& exp = cast<LValAction>(*act).expression();
if (trace_) {
llvm::outs() << "--- step lvalue " << exp << " (" << exp.source_loc()
@@ -386,14 +387,14 @@ auto Interpreter::StepLvalue() -> Transition {
// -> { {E(x) :: C, E, F} :: S, H}
Address pointer =
GetFromEnv(exp.source_loc(), cast<IdentifierExpression>(exp).name());
Nonnull<const Value*> v = arena->New<PointerValue>(pointer);
Nonnull<const Value*> v = arena_->New<PointerValue>(pointer);
return Done{v};
}
case Expression::Kind::FieldAccessExpression: {
if (act->pos() == 0) {
// { {e.f :: C, E, F} :: S, H}
// -> { e :: [].f :: C, E, F} :: S, H}
return Spawn{arena->New<LValAction>(
return Spawn{arena_->New<LValAction>(
&cast<FieldAccessExpression>(exp).aggregate())};
} else {
// { v :: [].f :: C, E, F} :: S, H}
@@ -401,7 +402,7 @@ auto Interpreter::StepLvalue() -> Transition {
Address aggregate = cast<PointerValue>(*act->results()[0]).value();
Address field = aggregate.SubobjectAddress(
cast<FieldAccessExpression>(exp).field());
return Done{arena->New<PointerValue>(field)};
return Done{arena_->New<PointerValue>(field)};
}
}
case Expression::Kind::IndexExpression: {
@@ -409,11 +410,11 @@ auto Interpreter::StepLvalue() -> Transition {
// { {e[i] :: C, E, F} :: S, H}
// -> { e :: [][i] :: C, E, F} :: S, H}
return Spawn{
arena->New<LValAction>(&cast<IndexExpression>(exp).aggregate())};
arena_->New<LValAction>(&cast<IndexExpression>(exp).aggregate())};
} else if (act->pos() == 1) {
return Spawn{
arena->New<ExpressionAction>(&cast<IndexExpression>(exp).offset())};
return Spawn{arena_->New<ExpressionAction>(
&cast<IndexExpression>(exp).offset())};
} else {
// { v :: [][i] :: C, E, F} :: S, H}
// -> { { &v[i] :: C, E, F} :: S, H }
@@ -421,7 +422,7 @@ auto Interpreter::StepLvalue() -> Transition {
std::string f =
std::to_string(cast<IntValue>(*act->results()[1]).value());
Address field = aggregate.SubobjectAddress(f);
return Done{arena->New<PointerValue>(field)};
return Done{arena_->New<PointerValue>(field)};
}
}
case Expression::Kind::TupleLiteral: {
@@ -431,7 +432,7 @@ auto Interpreter::StepLvalue() -> Transition {
// H}
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
// H}
return Spawn{arena->New<LValAction>(
return Spawn{arena_->New<LValAction>(
cast<TupleLiteral>(exp).fields()[act->pos()])};
} else {
return Done{CreateTuple(act, &exp)};
@@ -457,7 +458,7 @@ auto Interpreter::StepLvalue() -> Transition {
}
auto Interpreter::StepExp() -> Transition {
Nonnull<Action*> act = stack.Top()->todo.Top();
Nonnull<Action*> act = stack_.Top()->todo.Top();
const Expression& exp = cast<ExpressionAction>(*act).expression();
if (trace_) {
llvm::outs() << "--- step exp " << exp << " (" << exp.source_loc()
@@ -468,11 +469,11 @@ auto Interpreter::StepExp() -> Transition {
if (act->pos() == 0) {
// { { e[i] :: C, E, F} :: S, H}
// -> { { e :: [][i] :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<IndexExpression>(exp).aggregate())};
} else if (act->pos() == 1) {
return Spawn{
arena->New<ExpressionAction>(&cast<IndexExpression>(exp).offset())};
return Spawn{arena_->New<ExpressionAction>(
&cast<IndexExpression>(exp).offset())};
} else {
// { { v :: [][i] :: C, E, F} :: S, H}
// -> { { v_i :: C, E, F} : S, H}
@@ -492,7 +493,7 @@ auto Interpreter::StepExp() -> Transition {
// H}
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
// H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
cast<TupleLiteral>(exp).fields()[act->pos()])};
} else {
return Done{CreateTuple(act, &exp)};
@@ -501,7 +502,7 @@ auto Interpreter::StepExp() -> Transition {
case Expression::Kind::StructLiteral: {
const auto& literal = cast<StructLiteral>(exp);
if (act->pos() < static_cast<int>(literal.fields().size())) {
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&literal.fields()[act->pos()].expression())};
} else {
return Done{CreateStruct(literal.fields(), act->results())};
@@ -510,14 +511,14 @@ auto Interpreter::StepExp() -> Transition {
case Expression::Kind::StructTypeLiteral: {
const auto& struct_type = cast<StructTypeLiteral>(exp);
if (act->pos() < static_cast<int>(struct_type.fields().size())) {
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&struct_type.fields()[act->pos()].expression())};
} else {
VarValues fields;
for (size_t i = 0; i < struct_type.fields().size(); ++i) {
fields.push_back({struct_type.fields()[i].name(), act->results()[i]});
}
return Done{arena->New<StructType>(std::move(fields))};
return Done{arena_->New<StructType>(std::move(fields))};
}
}
case Expression::Kind::FieldAccessExpression: {
@@ -525,12 +526,12 @@ auto Interpreter::StepExp() -> Transition {
if (act->pos() == 0) {
// { { e.f :: C, E, F} :: S, H}
// -> { { e :: [].f :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(&access.aggregate())};
return Spawn{arena_->New<ExpressionAction>(&access.aggregate())};
} else {
// { { v :: [].f :: C, E, F} :: S, H}
// -> { { v_f :: C, E, F} : S, H}
return Done{act->results()[0]->GetField(
arena, FieldPath(access.field()), exp.source_loc())};
arena_, FieldPath(access.field()), exp.source_loc())};
}
}
case Expression::Kind::IdentifierExpression: {
@@ -538,23 +539,23 @@ auto Interpreter::StepExp() -> Transition {
const auto& ident = cast<IdentifierExpression>(exp);
// { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
Address pointer = GetFromEnv(exp.source_loc(), ident.name());
return Done{heap.Read(pointer, exp.source_loc())};
return Done{heap_.Read(pointer, exp.source_loc())};
}
case Expression::Kind::IntLiteral:
CHECK(act->pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
return Done{arena->New<IntValue>(cast<IntLiteral>(exp).value())};
return Done{arena_->New<IntValue>(cast<IntLiteral>(exp).value())};
case Expression::Kind::BoolLiteral:
CHECK(act->pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
return Done{arena->New<BoolValue>(cast<BoolLiteral>(exp).value())};
return Done{arena_->New<BoolValue>(cast<BoolLiteral>(exp).value())};
case Expression::Kind::PrimitiveOperatorExpression: {
const auto& op = cast<PrimitiveOperatorExpression>(exp);
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}
Nonnull<const Expression*> arg = op.arguments()[act->pos()];
return Spawn{arena->New<ExpressionAction>(arg)};
return Spawn{arena_->New<ExpressionAction>(arg)};
} else {
// { {v :: op(vs,[]) :: C, E, F} :: S, H}
// -> { {eval_prim(op, (vs,v)) :: C, E, F} :: S, H}
@@ -565,12 +566,12 @@ auto Interpreter::StepExp() -> Transition {
if (act->pos() == 0) {
// { {e1(e2) :: C, E, F} :: S, H}
// -> { {e1 :: [](e2) :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<CallExpression>(exp).function())};
} else if (act->pos() == 1) {
// { { v :: [](e) :: C, E, F} :: S, H}
// -> { { e :: v([]) :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<CallExpression>(exp).argument())};
} else if (act->pos() == 2) {
// { { v2 :: v1([]) :: C, E, F} :: S, H}
@@ -579,7 +580,7 @@ auto Interpreter::StepExp() -> Transition {
case Value::Kind::AlternativeConstructorValue: {
const auto& alt =
cast<AlternativeConstructorValue>(*act->results()[0]);
return Done{arena->New<AlternativeValue>(
return Done{arena_->New<AlternativeValue>(
alt.alt_name(), alt.choice_name(), act->results()[1])};
}
case Value::Kind::FunctionValue:
@@ -603,7 +604,7 @@ auto Interpreter::StepExp() -> Transition {
switch (cast<IntrinsicExpression>(exp).intrinsic()) {
case IntrinsicExpression::Intrinsic::Print:
Address pointer = GetFromEnv(exp.source_loc(), "format_str");
Nonnull<const Value*> pointee = heap.Read(pointer, exp.source_loc());
Nonnull<const Value*> pointee = heap_.Read(pointer, exp.source_loc());
CHECK(pointee->kind() == Value::Kind::StringValue);
// TODO: This could eventually use something like llvm::formatv.
llvm::outs() << cast<StringValue>(*pointee).value();
@@ -612,50 +613,50 @@ auto Interpreter::StepExp() -> Transition {
case Expression::Kind::IntTypeLiteral: {
CHECK(act->pos() == 0);
return Done{arena->New<IntType>()};
return Done{arena_->New<IntType>()};
}
case Expression::Kind::BoolTypeLiteral: {
CHECK(act->pos() == 0);
return Done{arena->New<BoolType>()};
return Done{arena_->New<BoolType>()};
}
case Expression::Kind::TypeTypeLiteral: {
CHECK(act->pos() == 0);
return Done{arena->New<TypeType>()};
return Done{arena_->New<TypeType>()};
}
case Expression::Kind::FunctionTypeLiteral: {
if (act->pos() == 0) {
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<FunctionTypeLiteral>(exp).parameter())};
} else if (act->pos() == 1) {
// { { pt :: fn [] -> e :: C, E, F} :: S, H}
// -> { { e :: fn pt -> []) :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<FunctionTypeLiteral>(exp).return_type())};
} else {
// { { rt :: fn pt -> [] :: C, E, F} :: S, H}
// -> { fn pt -> rt :: {C, E, F} :: S, H}
return Done{arena->New<FunctionType>(std::vector<GenericBinding>(),
act->results()[0],
act->results()[1])};
return Done{arena_->New<FunctionType>(std::vector<GenericBinding>(),
act->results()[0],
act->results()[1])};
}
}
case Expression::Kind::ContinuationTypeLiteral: {
CHECK(act->pos() == 0);
return Done{arena->New<ContinuationType>()};
return Done{arena_->New<ContinuationType>()};
}
case Expression::Kind::StringLiteral:
CHECK(act->pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
return Done{arena->New<StringValue>(cast<StringLiteral>(exp).value())};
return Done{arena_->New<StringValue>(cast<StringLiteral>(exp).value())};
case Expression::Kind::StringTypeLiteral: {
CHECK(act->pos() == 0);
return Done{arena->New<StringType>()};
return Done{arena_->New<StringType>()};
}
} // switch (exp->kind)
}
auto Interpreter::StepPattern() -> Transition {
Nonnull<Action*> act = stack.Top()->todo.Top();
Nonnull<Action*> act = stack_.Top()->todo.Top();
const Pattern& pattern = cast<PatternAction>(*act).pattern();
if (trace_) {
llvm::outs() << "--- step pattern " << pattern << " ("
@@ -664,15 +665,15 @@ auto Interpreter::StepPattern() -> Transition {
switch (pattern.kind()) {
case Pattern::Kind::AutoPattern: {
CHECK(act->pos() == 0);
return Done{arena->New<AutoType>()};
return Done{arena_->New<AutoType>()};
}
case Pattern::Kind::BindingPattern: {
const auto& binding = cast<BindingPattern>(pattern);
if (act->pos() == 0) {
return Spawn{arena->New<PatternAction>(&binding.type())};
return Spawn{arena_->New<PatternAction>(&binding.type())};
} else {
return Done{arena->New<BindingPlaceholderValue>(binding.name(),
act->results()[0])};
return Done{arena_->New<BindingPlaceholderValue>(binding.name(),
act->results()[0])};
}
}
case Pattern::Kind::TuplePattern: {
@@ -682,27 +683,27 @@ auto Interpreter::StepPattern() -> Transition {
// H}
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
// H}
return Spawn{arena->New<PatternAction>(tuple.fields()[act->pos()])};
return Spawn{arena_->New<PatternAction>(tuple.fields()[act->pos()])};
} else {
return Done{arena->New<TupleValue>(act->results())};
return Done{arena_->New<TupleValue>(act->results())};
}
}
case Pattern::Kind::AlternativePattern: {
const auto& alternative = cast<AlternativePattern>(pattern);
if (act->pos() == 0) {
return Spawn{arena->New<ExpressionAction>(&alternative.choice_type())};
return Spawn{arena_->New<ExpressionAction>(&alternative.choice_type())};
} else if (act->pos() == 1) {
return Spawn{arena->New<PatternAction>(&alternative.arguments())};
return Spawn{arena_->New<PatternAction>(&alternative.arguments())};
} else {
CHECK(act->pos() == 2);
const auto& choice_type = cast<ChoiceType>(*act->results()[0]);
return Done{arena->New<AlternativeValue>(alternative.alternative_name(),
choice_type.name(),
act->results()[1])};
return Done{arena_->New<AlternativeValue>(
alternative.alternative_name(), choice_type.name(),
act->results()[1])};
}
}
case Pattern::Kind::ExpressionPattern:
return Delegate{arena->New<ExpressionAction>(
return Delegate{arena_->New<ExpressionAction>(
&cast<ExpressionPattern>(pattern).expression())};
}
}
@@ -737,7 +738,7 @@ static auto HasLocalScope(Nonnull<Action*> act) -> bool {
}
auto Interpreter::StepStmt() -> Transition {
Nonnull<Frame*> frame = stack.Top();
Nonnull<Frame*> frame = stack_.Top();
Nonnull<Action*> act = frame->todo.Top();
const Statement& stmt = cast<StatementAction>(*act).statement();
if (trace_) {
@@ -751,8 +752,8 @@ auto Interpreter::StepStmt() -> Transition {
if (act->pos() == 0) {
// { { (match (e) ...) :: C, E, F} :: S, H}
// -> { { e :: (match ([]) ...) :: C, E, F} :: S, H}
frame->scopes.Push(arena->New<Scope>(CurrentEnv()));
return Spawn{arena->New<ExpressionAction>(&match_stmt.expression())};
frame->scopes.Push(arena_->New<Scope>(CurrentEnv()));
return Spawn{arena_->New<ExpressionAction>(&match_stmt.expression())};
} else {
// Regarding act->pos():
// * odd: start interpreting the pattern of a clause
@@ -775,7 +776,7 @@ auto Interpreter::StepStmt() -> Transition {
// start interpreting the pattern of the clause
// { {v :: (match ([]) ...) :: C, E, F} :: S, H}
// -> { {pi :: (match ([]) ...) :: C, E, F} :: S, H}
return Spawn{arena->New<PatternAction>(&c.pattern())};
return Spawn{arena_->New<PatternAction>(&c.pattern())};
} else { // try to match
auto v = act->results()[0];
auto pat = act->results()[clause_num + 1];
@@ -788,7 +789,7 @@ auto Interpreter::StepStmt() -> Transition {
frame->scopes.Top()->values.Set(name, value);
frame->scopes.Top()->locals.push_back(name);
}
return Spawn{arena->New<StatementAction>(&c.statement())};
return Spawn{arena_->New<StatementAction>(&c.statement())};
} else {
return RunAgain{};
}
@@ -801,11 +802,11 @@ auto Interpreter::StepStmt() -> Transition {
// -> { { e :: (while ([]) s) :: C, E, F} :: S, H}
act->Clear();
return Spawn{
arena->New<ExpressionAction>(&cast<While>(stmt).condition())};
arena_->New<ExpressionAction>(&cast<While>(stmt).condition())};
} else if (cast<BoolValue>(*act->results().back()).value()) {
// { {true :: (while ([]) s) :: C, E, F} :: S, H}
// -> { { s :: (while (e) s) :: C, E, F } :: S, H}
return Spawn{arena->New<StatementAction>(&cast<While>(stmt).body())};
return Spawn{arena_->New<StatementAction>(&cast<While>(stmt).body())};
} else {
// { {false :: (while ([]) s) :: C, E, F} :: S, H}
// -> { { C, E, F } :: S, H}
@@ -840,8 +841,8 @@ auto Interpreter::StepStmt() -> Transition {
if (act->pos() == 0) {
const auto& block = cast<Block>(stmt);
if (block.statement()) {
frame->scopes.Push(arena->New<Scope>(CurrentEnv()));
return Spawn{arena->New<StatementAction>(*block.statement())};
frame->scopes.Push(arena_->New<Scope>(CurrentEnv()));
return Spawn{arena_->New<StatementAction>(*block.statement())};
} else {
return Done{};
}
@@ -856,10 +857,10 @@ auto Interpreter::StepStmt() -> Transition {
if (act->pos() == 0) {
// { {(var x = e) :: C, E, F} :: S, H}
// -> { {e :: (var x = []) :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<VariableDefinition>(stmt).init())};
} else if (act->pos() == 1) {
return Spawn{arena->New<PatternAction>(
return Spawn{arena_->New<PatternAction>(
&cast<VariableDefinition>(stmt).pattern())};
} else {
// { { v :: (x = []) :: C, E, F} :: S, H}
@@ -881,7 +882,7 @@ auto Interpreter::StepStmt() -> Transition {
if (act->pos() == 0) {
// { {e :: C, E, F} :: S, H}
// -> { {e :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(
return Spawn{arena_->New<ExpressionAction>(
&cast<ExpressionStatement>(stmt).expression())};
} else {
return Done{};
@@ -890,11 +891,11 @@ auto Interpreter::StepStmt() -> Transition {
if (act->pos() == 0) {
// { {(lv = e) :: C, E, F} :: S, H}
// -> { {lv :: ([] = e) :: C, E, F} :: S, H}
return Spawn{arena->New<LValAction>(&cast<Assign>(stmt).lhs())};
return Spawn{arena_->New<LValAction>(&cast<Assign>(stmt).lhs())};
} else if (act->pos() == 1) {
// { { a :: ([] = e) :: C, E, F} :: S, H}
// -> { { e :: (a = []) :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(&cast<Assign>(stmt).rhs())};
return Spawn{arena_->New<ExpressionAction>(&cast<Assign>(stmt).rhs())};
} else {
// { { v :: (a = []) :: C, E, F} :: S, H}
// -> { { C, E, F} :: S, H(a := v)}
@@ -907,19 +908,20 @@ auto Interpreter::StepStmt() -> Transition {
if (act->pos() == 0) {
// { {(if (e) then_stmt else else_stmt) :: C, E, F} :: S, H}
// -> { { e :: (if ([]) then_stmt else else_stmt) :: C, E, F} :: S, H}
return Spawn{arena->New<ExpressionAction>(&cast<If>(stmt).condition())};
return Spawn{
arena_->New<ExpressionAction>(&cast<If>(stmt).condition())};
} else if (cast<BoolValue>(*act->results()[0]).value()) {
// { {true :: if ([]) then_stmt else else_stmt :: C, E, F} ::
// S, H}
// -> { { then_stmt :: C, E, F } :: S, H}
return Delegate{
arena->New<StatementAction>(&cast<If>(stmt).then_statement())};
arena_->New<StatementAction>(&cast<If>(stmt).then_statement())};
} else if (cast<If>(stmt).else_statement()) {
// { {false :: if ([]) then_stmt else else_stmt :: C, E, F} ::
// S, H}
// -> { { else_stmt :: C, E, F } :: S, H}
return Delegate{
arena->New<StatementAction>(*cast<If>(stmt).else_statement())};
arena_->New<StatementAction>(*cast<If>(stmt).else_statement())};
} else {
return Done{};
}
@@ -928,7 +930,7 @@ auto Interpreter::StepStmt() -> Transition {
// { {return e :: C, E, F} :: S, H}
// -> { {e :: return [] :: C, E, F} :: S, H}
return Spawn{
arena->New<ExpressionAction>(&cast<Return>(stmt).expression())};
arena_->New<ExpressionAction>(&cast<Return>(stmt).expression())};
} else {
// { {v :: return [] :: C, E, F} :: {C', E', F'} :: S, H}
// -> { {v :: C', E', F'} :: S, H}
@@ -939,11 +941,11 @@ auto Interpreter::StepStmt() -> Transition {
// -> { { s1 :: s2 :: C, E, F} :: S, H}
const auto& seq = cast<Sequence>(stmt);
if (act->pos() == 0) {
return Spawn{arena->New<StatementAction>(&seq.statement())};
return Spawn{arena_->New<StatementAction>(&seq.statement())};
} else {
if (seq.next()) {
return Delegate{
arena->New<StatementAction>(*cast<Sequence>(stmt).next())};
arena_->New<StatementAction>(*cast<Sequence>(stmt).next())};
} else {
return Done{};
}
@@ -953,17 +955,17 @@ auto Interpreter::StepStmt() -> Transition {
CHECK(act->pos() == 0);
// Create a continuation object by creating a frame similar the
// way one is created in a function call.
auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(CurrentEnv()));
auto scopes = Stack<Nonnull<Scope*>>(arena_->New<Scope>(CurrentEnv()));
Stack<Nonnull<Action*>> todo;
todo.Push(arena->New<StatementAction>(
arena->New<Return>(arena, stmt.source_loc())));
todo.Push(arena->New<StatementAction>(&cast<Continuation>(stmt).body()));
auto continuation_stack = arena->New<std::vector<Nonnull<Frame*>>>();
todo.Push(arena_->New<StatementAction>(
arena_->New<Return>(arena_, stmt.source_loc())));
todo.Push(arena_->New<StatementAction>(&cast<Continuation>(stmt).body()));
auto continuation_stack = arena_->New<std::vector<Nonnull<Frame*>>>();
auto continuation_frame =
arena->New<Frame>("__continuation", scopes, todo);
arena_->New<Frame>("__continuation", scopes, todo);
continuation_stack->push_back(continuation_frame);
Address continuation_address =
heap.AllocateValue(arena->New<ContinuationValue>(continuation_stack));
Address continuation_address = heap_.AllocateValue(
arena_->New<ContinuationValue>(continuation_stack));
// Store the continuation's address in the frame.
continuation_frame->continuation = continuation_address;
// Bind the continuation object to the continuation variable
@@ -977,21 +979,22 @@ auto Interpreter::StepStmt() -> Transition {
case Statement::Kind::Run:
if (act->pos() == 0) {
// Evaluate the argument of the run statement.
return Spawn{arena->New<ExpressionAction>(&cast<Run>(stmt).argument())};
return Spawn{
arena_->New<ExpressionAction>(&cast<Run>(stmt).argument())};
} else {
frame->todo.Pop(1);
// Push an expression statement action to ignore the result
// value from the continuation.
auto ignore_result =
arena->New<StatementAction>(arena->New<ExpressionStatement>(
arena_->New<StatementAction>(arena_->New<ExpressionStatement>(
stmt.source_loc(),
arena->New<TupleLiteral>(stmt.source_loc())));
arena_->New<TupleLiteral>(stmt.source_loc())));
frame->todo.Push(ignore_result);
// Push the continuation onto the current stack.
// Push the continuation onto the current stack_.
std::vector<Nonnull<Frame*>>& continuation_vector =
cast<ContinuationValue>(*act->results()[0]).stack();
while (!continuation_vector.empty()) {
stack.Push(continuation_vector.back());
stack_.Push(continuation_vector.back());
continuation_vector.pop_back();
}
return ManualTransition{};
@@ -1002,11 +1005,11 @@ auto Interpreter::StepStmt() -> Transition {
frame->todo.Pop();
std::vector<Nonnull<Frame*>> paused;
do {
paused.push_back(stack.Pop());
paused.push_back(stack_.Pop());
} while (paused.back()->continuation == std::nullopt);
// Update the continuation with the paused stack.
// Update the continuation with the paused stack_.
const auto& continuation = cast<ContinuationValue>(
*heap.Read(*paused.back()->continuation, stmt.source_loc()));
*heap_.Read(*paused.back()->continuation, stmt.source_loc()));
CHECK(continuation.stack().empty());
continuation.stack() = std::move(paused);
return ManualTransition{};
@@ -1019,12 +1022,12 @@ class Interpreter::DoTransition {
explicit DoTransition(Interpreter* interpreter) : interpreter(interpreter) {}
void operator()(const Done& done) {
Nonnull<Frame*> frame = interpreter->stack.Top();
Nonnull<Frame*> frame = interpreter->stack_.Top();
if (frame->todo.Top()->kind() != Action::Kind::StatementAction) {
CHECK(done.result);
frame->todo.Pop();
if (frame->todo.IsEmpty()) {
interpreter->program_value = *done.result;
interpreter->program_value_ = *done.result;
} else {
frame->todo.Top()->AddResult(*done.result);
}
@@ -1035,25 +1038,25 @@ class Interpreter::DoTransition {
}
void operator()(const Spawn& spawn) {
Nonnull<Frame*> frame = interpreter->stack.Top();
Nonnull<Frame*> frame = interpreter->stack_.Top();
Nonnull<Action*> action = frame->todo.Top();
action->set_pos(action->pos() + 1);
frame->todo.Push(spawn.child);
}
void operator()(const Delegate& delegate) {
Nonnull<Frame*> frame = interpreter->stack.Top();
Nonnull<Frame*> frame = interpreter->stack_.Top();
frame->todo.Pop();
frame->todo.Push(delegate.delegate);
}
void operator()(const RunAgain&) {
Nonnull<Action*> action = interpreter->stack.Top()->todo.Top();
Nonnull<Action*> action = interpreter->stack_.Top()->todo.Top();
action->set_pos(action->pos() + 1);
}
void operator()(const UnwindTo& unwind_to) {
Nonnull<Frame*> frame = interpreter->stack.Top();
Nonnull<Frame*> frame = interpreter->stack_.Top();
while (frame->todo.Top() != unwind_to.new_top) {
if (HasLocalScope(frame->todo.Top())) {
interpreter->DeallocateScope(frame->scopes.Top());
@@ -1064,36 +1067,36 @@ class Interpreter::DoTransition {
}
void operator()(const UnwindFunctionCall& unwind) {
interpreter->DeallocateLocals(interpreter->stack.Top());
interpreter->stack.Pop();
if (interpreter->stack.Top()->todo.IsEmpty()) {
interpreter->program_value = unwind.return_val;
interpreter->DeallocateLocals(interpreter->stack_.Top());
interpreter->stack_.Pop();
if (interpreter->stack_.Top()->todo.IsEmpty()) {
interpreter->program_value_ = unwind.return_val;
} else {
interpreter->stack.Top()->todo.Top()->AddResult(unwind.return_val);
interpreter->stack_.Top()->todo.Top()->AddResult(unwind.return_val);
}
}
void operator()(const CallFunction& call) {
interpreter->stack.Top()->todo.Pop();
interpreter->stack_.Top()->todo.Pop();
std::optional<Env> matches = interpreter->PatternMatch(
&call.function->parameters(), call.args, call.source_loc);
CHECK(matches.has_value())
<< "internal error in call_function, pattern match failed";
// Create the new frame and push it on the stack
Env values = interpreter->globals;
Env values = interpreter->globals_;
std::vector<std::string> params;
for (const auto& [name, value] : *matches) {
values.Set(name, value);
params.push_back(name);
}
auto scopes =
Stack<Nonnull<Scope*>>(interpreter->arena->New<Scope>(values, params));
Stack<Nonnull<Scope*>>(interpreter->arena_->New<Scope>(values, params));
CHECK(call.function->body()) << "Calling a function that's missing a body";
auto todo = Stack<Nonnull<Action*>>(
interpreter->arena->New<StatementAction>(*call.function->body()));
interpreter->arena_->New<StatementAction>(*call.function->body()));
auto frame =
interpreter->arena->New<Frame>(call.function->name(), scopes, todo);
interpreter->stack.Push(frame);
interpreter->arena_->New<Frame>(call.function->name(), scopes, todo);
interpreter->stack_.Push(frame);
}
void operator()(const ManualTransition&) {}
@@ -1104,7 +1107,7 @@ class Interpreter::DoTransition {
// State transition.
void Interpreter::Step() {
Nonnull<Frame*> frame = stack.Top();
Nonnull<Frame*> frame = stack_.Top();
if (frame->todo.IsEmpty()) {
std::visit(DoTransition(this),
Transition{UnwindFunctionCall{TupleValue::Empty()}});
@@ -1131,64 +1134,65 @@ void Interpreter::Step() {
auto Interpreter::InterpProgram(llvm::ArrayRef<Nonnull<Declaration*>> fs,
Nonnull<const Expression*> call_main) -> int {
// Check that the interpreter is in a clean state.
CHECK(globals.IsEmpty());
CHECK(stack.IsEmpty());
CHECK(program_value == std::nullopt);
CHECK(globals_.IsEmpty());
CHECK(stack_.IsEmpty());
CHECK(program_value_ == std::nullopt);
if (trace_) {
llvm::outs() << "********** initializing globals **********\n";
}
InitGlobals(fs);
auto todo = Stack<Nonnull<Action*>>(arena->New<ExpressionAction>(call_main));
auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(globals));
stack = Stack<Nonnull<Frame*>>(arena->New<Frame>("top", scopes, todo));
auto todo = Stack<Nonnull<Action*>>(arena_->New<ExpressionAction>(call_main));
auto scopes = Stack<Nonnull<Scope*>>(arena_->New<Scope>(globals_));
stack_ = Stack<Nonnull<Frame*>>(arena_->New<Frame>("top", scopes, todo));
if (trace_) {
llvm::outs() << "********** calling main function **********\n";
PrintState(llvm::outs());
}
while (stack.Count() > 1 || !stack.Top()->todo.IsEmpty()) {
while (stack_.Count() > 1 || !stack_.Top()->todo.IsEmpty()) {
Step();
if (trace_) {
PrintState(llvm::outs());
}
}
return cast<IntValue>(**program_value).value();
return cast<IntValue>(**program_value_).value();
}
auto Interpreter::InterpExp(Env values, Nonnull<const Expression*> e)
-> Nonnull<const Value*> {
CHECK(program_value == std::nullopt);
CHECK(program_value_ == std::nullopt);
auto program_value_guard =
llvm::make_scope_exit([&] { program_value = std::nullopt; });
auto todo = Stack<Nonnull<Action*>>(arena->New<ExpressionAction>(e));
auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(values));
stack = Stack<Nonnull<Frame*>>(arena->New<Frame>("InterpExp", scopes, todo));
llvm::make_scope_exit([&] { program_value_ = std::nullopt; });
auto todo = Stack<Nonnull<Action*>>(arena_->New<ExpressionAction>(e));
auto scopes = Stack<Nonnull<Scope*>>(arena_->New<Scope>(values));
stack_ =
Stack<Nonnull<Frame*>>(arena_->New<Frame>("InterpExp", scopes, todo));
while (stack.Count() > 1 || !stack.Top()->todo.IsEmpty()) {
while (stack_.Count() > 1 || !stack_.Top()->todo.IsEmpty()) {
Step();
}
CHECK(program_value != std::nullopt);
return *program_value;
CHECK(program_value_ != std::nullopt);
return *program_value_;
}
auto Interpreter::InterpPattern(Env values, Nonnull<const Pattern*> p)
-> Nonnull<const Value*> {
CHECK(program_value == std::nullopt);
CHECK(program_value_ == std::nullopt);
auto program_value_guard =
llvm::make_scope_exit([&] { program_value = std::nullopt; });
auto todo = Stack<Nonnull<Action*>>(arena->New<PatternAction>(p));
auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(values));
stack =
Stack<Nonnull<Frame*>>(arena->New<Frame>("InterpPattern", scopes, todo));
llvm::make_scope_exit([&] { program_value_ = std::nullopt; });
auto todo = Stack<Nonnull<Action*>>(arena_->New<PatternAction>(p));
auto scopes = Stack<Nonnull<Scope*>>(arena_->New<Scope>(values));
stack_ =
Stack<Nonnull<Frame*>>(arena_->New<Frame>("InterpPattern", scopes, todo));
while (stack.Count() > 1 || !stack.Top()->todo.IsEmpty()) {
while (stack_.Count() > 1 || !stack_.Top()->todo.IsEmpty()) {
Step();
}
CHECK(program_value != std::nullopt);
return *program_value;
CHECK(program_value_ != std::nullopt);
return *program_value_;
}
} // namespace Carbon
@@ -26,7 +26,7 @@ using Env = Dictionary<std::string, Address>;
class Interpreter {
public:
explicit Interpreter(Nonnull<Arena*> arena, bool trace)
: arena(arena), globals(arena), heap(arena), trace_(trace) {}
: arena_(arena), globals_(arena), heap_(arena), trace_(trace) {}
// Interpret the whole program.
auto InterpProgram(llvm::ArrayRef<Nonnull<Declaration*>> fs,
@@ -47,7 +47,7 @@ class Interpreter {
// Support TypeChecker allocating values on the heap.
auto AllocateValue(Nonnull<const Value*> v) -> Address {
return heap.AllocateValue(v);
return heap_.AllocateValue(v);
}
void InitEnv(const Declaration& d, Env* env);
@@ -152,14 +152,14 @@ class Interpreter {
void PrintState(llvm::raw_ostream& out);
Nonnull<Arena*> arena;
Nonnull<Arena*> arena_;
// Globally-defined entities, such as functions, structs, or choices.
Env globals;
Env globals_;
Stack<Nonnull<Frame*>> stack;
Heap heap;
std::optional<Nonnull<const Value*>> program_value;
Stack<Nonnull<Frame*>> stack_;
Heap heap_;
std::optional<Nonnull<const Value*>> program_value_;
bool trace_;
};
+11 -11
View File
@@ -26,15 +26,15 @@ struct Stack {
explicit Stack(T x) : Stack() { Push(std::move(x)); }
// Pushes `x` onto the top of the stack.
void Push(T x) { elements.push_back(std::move(x)); }
void Push(T x) { elements_.push_back(std::move(x)); }
// Removes and returns the top element of the stack.
//
// - Requires: !this->IsEmpty()
auto Pop() -> T {
CHECK(!IsEmpty()) << "Can't pop from empty stack.";
auto r = std::move(elements.back());
elements.pop_back();
auto r = std::move(elements_.back());
elements_.pop_back();
return r;
}
@@ -43,9 +43,9 @@ struct Stack {
// - Requires: n >= 0 && n <= Count()
void Pop(int n) {
CHECK(n >= 0) << "Negative pop count disallowed.";
CHECK(static_cast<size_t>(n) <= elements.size())
CHECK(static_cast<size_t>(n) <= elements_.size())
<< "Can only pop as many elements as stack has.";
elements.erase(elements.end() - n, elements.end());
elements_.erase(elements_.end() - n, elements_.end());
}
// Returns the top element of the stack.
@@ -53,21 +53,21 @@ struct Stack {
// - Requires: !this->IsEmpty()
auto Top() const -> T {
CHECK(!IsEmpty()) << "Empty stack has no Top().";
return elements.back();
return elements_.back();
}
// Returns `true` iff `Count() > 0`.
auto IsEmpty() const -> bool { return elements.empty(); }
auto IsEmpty() const -> bool { return elements_.empty(); }
// Returns the number of elements in `*this`.
auto Count() const -> int { return elements.size(); }
auto Count() const -> int { return elements_.size(); }
// Iterates over the Stack from top to bottom.
auto begin() const -> const_iterator { return elements.crbegin(); }
auto end() const -> const_iterator { return elements.crend(); }
auto begin() const -> const_iterator { return elements_.crbegin(); }
auto end() const -> const_iterator { return elements_.crend(); }
private:
std::vector<T> elements;
std::vector<T> elements_;
};
} // namespace Carbon
@@ -369,7 +369,7 @@ auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
for (const auto& elt : cast<TupleValue>(*type).elements()) {
elts.push_back(Substitute(dict, elt));
}
return arena->New<TupleValue>(elts);
return arena_->New<TupleValue>(elts);
}
case Value::Kind::StructType: {
VarValues fields;
@@ -377,17 +377,17 @@ auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
auto new_type = Substitute(dict, value);
fields.push_back({name, new_type});
}
return arena->New<StructType>(std::move(fields));
return arena_->New<StructType>(std::move(fields));
}
case Value::Kind::FunctionType: {
const auto& fn_type = cast<FunctionType>(*type);
auto param = Substitute(dict, &fn_type.parameters());
auto ret = Substitute(dict, &fn_type.return_type());
return arena->New<FunctionType>(std::vector<GenericBinding>(), param,
ret);
return arena_->New<FunctionType>(std::vector<GenericBinding>(), param,
ret);
}
case Value::Kind::PointerType: {
return arena->New<PointerType>(
return arena_->New<PointerType>(
Substitute(dict, &cast<PointerType>(*type).type()));
}
case Value::Kind::AutoType:
@@ -421,7 +421,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
llvm::outs() << "checking expression " << *e << "\ntypes: ";
PrintTypeEnv(types, llvm::outs());
llvm::outs() << "\nvalues: ";
interpreter.PrintEnv(values, llvm::outs());
interpreter_.PrintEnv(values, llvm::outs());
llvm::outs() << "\n";
}
switch (e->kind()) {
@@ -433,7 +433,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
case Value::Kind::TupleValue: {
const auto& tuple_type = cast<TupleValue>(aggregate_type);
int i =
cast<IntValue>(*interpreter.InterpExp(values, &index.offset()))
cast<IntValue>(*interpreter_.InterpExp(values, &index.offset()))
.value();
if (i < 0 || i >= static_cast<int>(tuple_type.elements().size())) {
FATAL_COMPILATION_ERROR(e->source_loc())
@@ -454,7 +454,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
new_types = arg_res.types;
arg_types.push_back(&arg->static_type());
}
SetStaticType(e, arena->New<TupleValue>(std::move(arg_types)));
SetStaticType(e, arena_->New<TupleValue>(std::move(arg_types)));
return TCResult(new_types);
}
case Expression::Kind::StructLiteral: {
@@ -467,7 +467,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
new_args.push_back(FieldInitializer(arg.name(), &arg.expression()));
arg_types.push_back({arg.name(), &arg.expression().static_type()});
}
SetStaticType(e, arena->New<StructType>(std::move(arg_types)));
SetStaticType(e, arena_->New<StructType>(std::move(arg_types)));
return TCResult(new_types);
}
case Expression::Kind::StructTypeLiteral: {
@@ -478,7 +478,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
auto arg_res = TypeCheckExp(&arg.expression(), new_types, values);
new_types = arg_res.types;
ExpectIsConcreteType(arg.expression().source_loc(),
interpreter.InterpExp(values, &arg.expression()));
interpreter_.InterpExp(values, &arg.expression()));
new_args.push_back(FieldInitializer(arg.name(), &arg.expression()));
}
if (struct_type.fields().empty()) {
@@ -486,9 +486,9 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
// This applies only if there are no fields, because (unlike with
// tuples) non-empty struct types are syntactically disjoint
// from non-empty struct values.
SetStaticType(&struct_type, arena->New<StructType>());
SetStaticType(&struct_type, arena_->New<StructType>());
} else {
SetStaticType(&struct_type, arena->New<TypeType>());
SetStaticType(&struct_type, arena_->New<TypeType>());
}
return TCResult(new_types);
}
@@ -533,7 +533,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
const auto& choice = cast<ChoiceType>(aggregate_type);
for (const auto& vt : choice.alternatives()) {
if (access.field() == vt.first) {
SetStaticType(&access, arena->New<FunctionType>(
SetStaticType(&access, arena_->New<FunctionType>(
std::vector<GenericBinding>(),
vt.second, &aggregate_type));
return TCResult(res.types);
@@ -561,10 +561,10 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
}
}
case Expression::Kind::IntLiteral:
SetStaticType(e, arena->New<IntType>());
SetStaticType(e, arena_->New<IntType>());
return TCResult(types);
case Expression::Kind::BoolLiteral:
SetStaticType(e, arena->New<BoolType>());
SetStaticType(e, arena_->New<BoolType>());
return TCResult(types);
case Expression::Kind::PrimitiveOperatorExpression: {
auto& op = cast<PrimitiveOperatorExpression>(*e);
@@ -579,60 +579,60 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
}
switch (op.op()) {
case Operator::Neg:
ExpectExactType(e->source_loc(), "negation", arena->New<IntType>(),
ExpectExactType(e->source_loc(), "negation", arena_->New<IntType>(),
ts[0]);
SetStaticType(&op, arena->New<IntType>());
SetStaticType(&op, arena_->New<IntType>());
return TCResult(new_types);
case Operator::Add:
ExpectExactType(e->source_loc(), "addition(1)", arena->New<IntType>(),
ts[0]);
ExpectExactType(e->source_loc(), "addition(2)", arena->New<IntType>(),
ts[1]);
SetStaticType(&op, arena->New<IntType>());
ExpectExactType(e->source_loc(), "addition(1)",
arena_->New<IntType>(), ts[0]);
ExpectExactType(e->source_loc(), "addition(2)",
arena_->New<IntType>(), ts[1]);
SetStaticType(&op, arena_->New<IntType>());
return TCResult(new_types);
case Operator::Sub:
ExpectExactType(e->source_loc(), "subtraction(1)",
arena->New<IntType>(), ts[0]);
arena_->New<IntType>(), ts[0]);
ExpectExactType(e->source_loc(), "subtraction(2)",
arena->New<IntType>(), ts[1]);
SetStaticType(&op, arena->New<IntType>());
arena_->New<IntType>(), ts[1]);
SetStaticType(&op, arena_->New<IntType>());
return TCResult(new_types);
case Operator::Mul:
ExpectExactType(e->source_loc(), "multiplication(1)",
arena->New<IntType>(), ts[0]);
arena_->New<IntType>(), ts[0]);
ExpectExactType(e->source_loc(), "multiplication(2)",
arena->New<IntType>(), ts[1]);
SetStaticType(&op, arena->New<IntType>());
arena_->New<IntType>(), ts[1]);
SetStaticType(&op, arena_->New<IntType>());
return TCResult(new_types);
case Operator::And:
ExpectExactType(e->source_loc(), "&&(1)", arena->New<BoolType>(),
ExpectExactType(e->source_loc(), "&&(1)", arena_->New<BoolType>(),
ts[0]);
ExpectExactType(e->source_loc(), "&&(2)", arena->New<BoolType>(),
ExpectExactType(e->source_loc(), "&&(2)", arena_->New<BoolType>(),
ts[1]);
SetStaticType(&op, arena->New<BoolType>());
SetStaticType(&op, arena_->New<BoolType>());
return TCResult(new_types);
case Operator::Or:
ExpectExactType(e->source_loc(), "||(1)", arena->New<BoolType>(),
ExpectExactType(e->source_loc(), "||(1)", arena_->New<BoolType>(),
ts[0]);
ExpectExactType(e->source_loc(), "||(2)", arena->New<BoolType>(),
ExpectExactType(e->source_loc(), "||(2)", arena_->New<BoolType>(),
ts[1]);
SetStaticType(&op, arena->New<BoolType>());
SetStaticType(&op, arena_->New<BoolType>());
return TCResult(new_types);
case Operator::Not:
ExpectExactType(e->source_loc(), "!", arena->New<BoolType>(), ts[0]);
SetStaticType(&op, arena->New<BoolType>());
ExpectExactType(e->source_loc(), "!", arena_->New<BoolType>(), ts[0]);
SetStaticType(&op, arena_->New<BoolType>());
return TCResult(new_types);
case Operator::Eq:
ExpectExactType(e->source_loc(), "==", ts[0], ts[1]);
SetStaticType(&op, arena->New<BoolType>());
SetStaticType(&op, arena_->New<BoolType>());
return TCResult(new_types);
case Operator::Deref:
ExpectPointerType(e->source_loc(), "*", ts[0]);
SetStaticType(&op, &cast<PointerType>(*ts[0]).type());
return TCResult(new_types);
case Operator::Ptr:
ExpectExactType(e->source_loc(), "*", arena->New<TypeType>(), ts[0]);
SetStaticType(&op, arena->New<TypeType>());
ExpectExactType(e->source_loc(), "*", arena_->New<TypeType>(), ts[0]);
SetStaticType(&op, arena_->New<TypeType>());
return TCResult(new_types);
}
break;
@@ -648,7 +648,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
Nonnull<const Value*> return_type = &fun_t.return_type();
if (!fun_t.deduced().empty()) {
auto deduced_args =
ArgumentDeduction(e->source_loc(), TypeEnv(arena), parameters,
ArgumentDeduction(e->source_loc(), TypeEnv(arena_), parameters,
&call.argument().static_type());
for (auto& deduced_param : fun_t.deduced()) {
// TODO: change the following to a CHECK once the real checking
@@ -679,14 +679,14 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
case Expression::Kind::FunctionTypeLiteral: {
auto& fn = cast<FunctionTypeLiteral>(*e);
ExpectIsConcreteType(fn.parameter().source_loc(),
interpreter.InterpExp(values, &fn.parameter()));
interpreter_.InterpExp(values, &fn.parameter()));
ExpectIsConcreteType(fn.return_type().source_loc(),
interpreter.InterpExp(values, &fn.return_type()));
SetStaticType(&fn, arena->New<TypeType>());
interpreter_.InterpExp(values, &fn.return_type()));
SetStaticType(&fn, arena_->New<TypeType>());
return TCResult(types);
}
case Expression::Kind::StringLiteral:
SetStaticType(e, arena->New<StringType>());
SetStaticType(e, arena_->New<StringType>());
return TCResult(types);
case Expression::Kind::IntrinsicExpression:
switch (cast<IntrinsicExpression>(*e).intrinsic()) {
@@ -699,7 +699,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
case Expression::Kind::StringTypeLiteral:
case Expression::Kind::TypeTypeLiteral:
case Expression::Kind::ContinuationTypeLiteral:
SetStaticType(e, arena->New<TypeType>());
SetStaticType(e, arena_->New<TypeType>());
return TCResult(types);
}
}
@@ -715,24 +715,24 @@ auto TypeChecker::TypeCheckPattern(
llvm::outs() << "\ntypes: ";
PrintTypeEnv(types, llvm::outs());
llvm::outs() << "\nvalues: ";
interpreter.PrintEnv(values, llvm::outs());
interpreter_.PrintEnv(values, llvm::outs());
llvm::outs() << "\n";
}
switch (p->kind()) {
case Pattern::Kind::AutoPattern: {
SetStaticType(p, arena->New<TypeType>());
SetStaticType(p, arena_->New<TypeType>());
return TCResult(types);
}
case Pattern::Kind::BindingPattern: {
auto& binding = cast<BindingPattern>(*p);
TypeCheckPattern(&binding.type(), types, values, std::nullopt);
Nonnull<const Value*> type =
interpreter.InterpPattern(values, &binding.type());
interpreter_.InterpPattern(values, &binding.type());
if (expected) {
if (IsConcreteType(type)) {
ExpectType(p->source_loc(), "name binding", type, *expected);
} else {
std::optional<Env> values = interpreter.PatternMatch(
std::optional<Env> values = interpreter_.PatternMatch(
type, *expected, binding.type().source_loc());
if (values == std::nullopt) {
FATAL_COMPILATION_ERROR(binding.type().source_loc())
@@ -774,13 +774,13 @@ auto TypeChecker::TypeCheckPattern(
new_types = field_result.types;
field_types.push_back(&field->static_type());
}
SetStaticType(&tuple, arena->New<TupleValue>(std::move(field_types)));
SetStaticType(&tuple, arena_->New<TupleValue>(std::move(field_types)));
return TCResult(new_types);
}
case Pattern::Kind::AlternativePattern: {
auto& alternative = cast<AlternativePattern>(*p);
Nonnull<const Value*> choice_type =
interpreter.InterpExp(values, &alternative.choice_type());
interpreter_.InterpExp(values, &alternative.choice_type());
if (choice_type->kind() != Value::Kind::ChoiceType) {
FATAL_COMPILATION_ERROR(alternative.source_loc())
<< "alternative pattern does not name a choice type.";
@@ -841,7 +841,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
auto& while_stmt = cast<While>(*s);
TypeCheckExp(&while_stmt.condition(), types, values);
ExpectType(s->source_loc(), "condition of `while`",
arena->New<BoolType>(), &while_stmt.condition().static_type());
arena_->New<BoolType>(),
&while_stmt.condition().static_type());
TypeCheckStmt(&while_stmt.body(), types, values, return_type_context);
return TCResult(types);
}
@@ -891,7 +892,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
case Statement::Kind::If: {
auto& if_stmt = cast<If>(*s);
TypeCheckExp(&if_stmt.condition(), types, values);
ExpectType(s->source_loc(), "condition of `if`", arena->New<BoolType>(),
ExpectType(s->source_loc(), "condition of `if`", arena_->New<BoolType>(),
&if_stmt.condition().static_type());
TypeCheckStmt(&if_stmt.then_statement(), types, values,
return_type_context);
@@ -931,14 +932,15 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
case Statement::Kind::Continuation: {
auto& cont = cast<Continuation>(*s);
TypeCheckStmt(&cont.body(), types, values, return_type_context);
types.Set(cont.continuation_variable(), arena->New<ContinuationType>());
types.Set(cont.continuation_variable(), arena_->New<ContinuationType>());
return TCResult(types);
}
case Statement::Kind::Run: {
auto& run = cast<Run>(*s);
TypeCheckExp(&run.argument(), types, values);
ExpectType(s->source_loc(), "argument of `run`",
arena->New<ContinuationType>(), &run.argument().static_type());
arena_->New<ContinuationType>(),
&run.argument().static_type());
return TCResult(types);
}
case Statement::Kind::Await: {
@@ -1030,18 +1032,18 @@ auto TypeChecker::TypeCheckFunDef(FunctionDeclaration* f, TypeEnv types,
Env values) -> TCResult {
// Bring the deduced parameters into scope
for (const auto& deduced : f->deduced_parameters()) {
// auto t = interpreter.InterpExp(values, deduced.type);
types.Set(deduced.name, arena->New<VariableType>(deduced.name));
Address a = interpreter.AllocateValue(*types.Get(deduced.name));
// auto t = interpreter_.InterpExp(values, deduced.type);
types.Set(deduced.name, arena_->New<VariableType>(deduced.name));
Address a = interpreter_.AllocateValue(*types.Get(deduced.name));
values.Set(deduced.name, a);
}
// Type check the parameter pattern
auto param_res =
TypeCheckPattern(&f->param_pattern(), types, values, std::nullopt);
// Evaluate the return type expression
auto return_type = interpreter.InterpPattern(values, &f->return_type());
auto return_type = interpreter_.InterpPattern(values, &f->return_type());
if (f->name() == "main") {
ExpectType(f->source_loc(), "return type of `main`", arena->New<IntType>(),
ExpectType(f->source_loc(), "return type of `main`", arena_->New<IntType>(),
return_type);
// TODO: Check that main doesn't have any parameters.
}
@@ -1060,9 +1062,9 @@ auto TypeChecker::TypeCheckFunDef(FunctionDeclaration* f, TypeEnv types,
ExpectReturnOnAllPaths(body_stmt, f->source_loc());
}
ExpectIsConcreteType(f->return_type().source_loc(), return_type);
SetStaticType(f, arena->New<FunctionType>(f->deduced_parameters(),
&f->param_pattern().static_type(),
return_type));
SetStaticType(f, arena_->New<FunctionType>(f->deduced_parameters(),
&f->param_pattern().static_type(),
return_type));
return TCResult(types);
}
@@ -1071,22 +1073,23 @@ auto TypeChecker::TypeOfFunDef(TypeEnv types, Env values,
-> Nonnull<const Value*> {
// Bring the deduced parameters into scope
for (const auto& deduced : fun_def->deduced_parameters()) {
// auto t = interpreter.InterpExp(values, deduced.type);
types.Set(deduced.name, arena->New<VariableType>(deduced.name));
Address a = interpreter.AllocateValue(*types.Get(deduced.name));
// auto t = interpreter_.InterpExp(values, deduced.type);
types.Set(deduced.name, arena_->New<VariableType>(deduced.name));
Address a = interpreter_.AllocateValue(*types.Get(deduced.name));
values.Set(deduced.name, a);
}
// Type check the parameter pattern
TypeCheckPattern(&fun_def->param_pattern(), types, values, std::nullopt);
// Evaluate the return type expression
auto ret = interpreter.InterpPattern(values, &fun_def->return_type());
auto ret = interpreter_.InterpPattern(values, &fun_def->return_type());
if (ret->kind() == Value::Kind::AutoType) {
// FIXME do this unconditionally?
TypeCheckFunDef(fun_def, types, values);
return &fun_def->static_type();
}
return arena->New<FunctionType>(fun_def->deduced_parameters(),
&fun_def->param_pattern().static_type(), ret);
return arena_->New<FunctionType>(fun_def->deduced_parameters(),
&fun_def->param_pattern().static_type(),
ret);
}
auto TypeChecker::TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/,
@@ -1106,14 +1109,14 @@ auto TypeChecker::TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/,
FATAL_COMPILATION_ERROR(binding.source_loc())
<< "Struct members must have explicit types";
}
auto type = interpreter.InterpExp(ct_top, &binding_type->expression());
auto type = interpreter_.InterpExp(ct_top, &binding_type->expression());
fields.push_back(std::make_pair(*binding.name(), type));
break;
}
}
}
return arena->New<NominalClassType>(sd->name(), std::move(fields),
std::move(methods));
return arena_->New<NominalClassType>(sd->name(), std::move(fields),
std::move(methods));
}
static auto GetName(const Declaration& d) -> const std::string& {
@@ -1163,7 +1166,7 @@ void TypeChecker::TypeCheck(Nonnull<Declaration*> d, const TypeEnv& types,
<< "Type of a top-level variable must be an expression.";
}
Nonnull<const Value*> declared_type =
interpreter.InterpExp(values, &binding_type->expression());
interpreter_.InterpExp(values, &binding_type->expression());
ExpectType(var.source_loc(), "initializer of variable", declared_type,
&var.initializer().static_type());
return;
@@ -1177,7 +1180,7 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
FunctionDeclaration& func_def = cast<FunctionDeclaration>(*d);
auto t = TypeOfFunDef(tops->types, tops->values, &func_def);
tops->types.Set(func_def.name(), t);
interpreter.InitEnv(*d, &tops->values);
interpreter_.InitEnv(*d, &tops->values);
break;
}
@@ -1185,7 +1188,7 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
const ClassDefinition& class_def =
cast<ClassDeclaration>(*d).definition();
auto st = TypeOfClassDef(&class_def, tops->types, tops->values);
Address a = interpreter.AllocateValue(st);
Address a = interpreter_.AllocateValue(st);
tops->values.Set(class_def.name(), a); // Is this obsolete?
tops->types.Set(class_def.name(), st);
break;
@@ -1195,11 +1198,11 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
const auto& choice = cast<ChoiceDeclaration>(*d);
VarValues alts;
for (const auto& alternative : choice.alternatives()) {
auto t = interpreter.InterpExp(tops->values, &alternative.signature());
auto t = interpreter_.InterpExp(tops->values, &alternative.signature());
alts.push_back(std::make_pair(alternative.name(), t));
}
auto ct = arena->New<ChoiceType>(choice.name(), std::move(alts));
Address a = interpreter.AllocateValue(ct);
auto ct = arena_->New<ChoiceType>(choice.name(), std::move(alts));
Address a = interpreter_.AllocateValue(ct);
tops->values.Set(choice.name(), a); // Is this obsolete?
tops->types.Set(choice.name(), ct);
break;
@@ -1212,7 +1215,7 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
Expression& type =
cast<ExpressionPattern>(var.binding().type()).expression();
Nonnull<const Value*> declared_type =
interpreter.InterpExp(tops->values, &type);
interpreter_.InterpExp(tops->values, &type);
tops->types.Set(*var.binding().name(), declared_type);
break;
}
@@ -1221,7 +1224,7 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
auto TypeChecker::TopLevel(std::vector<Nonnull<Declaration*>>* fs)
-> TypeCheckContext {
TypeCheckContext tops(arena);
TypeCheckContext tops(arena_);
bool found_main = false;
for (auto const& d : *fs) {
@@ -21,7 +21,7 @@ using TypeEnv = Dictionary<std::string, Nonnull<const Value*>>;
class TypeChecker {
public:
explicit TypeChecker(Nonnull<Arena*> arena, bool trace)
: arena(arena), interpreter(arena, trace), trace_(trace) {}
: arena_(arena), interpreter_(arena, trace), trace_(trace) {}
struct TypeCheckContext {
explicit TypeCheckContext(Nonnull<Arena*> arena)
@@ -137,8 +137,8 @@ class TypeChecker {
auto Substitute(TypeEnv dict, Nonnull<const Value*> type)
-> Nonnull<const Value*>;
Nonnull<Arena*> arena;
Interpreter interpreter;
Nonnull<Arena*> arena_;
Interpreter interpreter_;
bool trace_;
};
+2 -2
View File
@@ -94,7 +94,7 @@ auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
auto Value::GetField(Nonnull<Arena*> arena, const FieldPath& path,
SourceLocation source_loc) const -> Nonnull<const Value*> {
Nonnull<const Value*> value(this);
for (const std::string& field : path.components) {
for (const std::string& field : path.components_) {
value = GetMember(arena, value, field, source_loc);
}
return value;
@@ -154,7 +154,7 @@ auto Value::SetField(Nonnull<Arena*> arena, const FieldPath& path,
Nonnull<const Value*> field_value,
SourceLocation source_loc) const -> Nonnull<const Value*> {
return SetFieldImpl(arena, Nonnull<const Value*>(this),
path.components.begin(), path.components.end(),
path.components_.begin(), path.components_.end(),
field_value, source_loc);
}
+5 -5
View File
@@ -19,7 +19,7 @@ class BisonWrap {
public:
// Assigning a value initializes the wrapper.
auto operator=(T&& rhs) -> BisonWrap& {
val = std::move(rhs);
val_ = std::move(rhs);
return *this;
}
@@ -29,14 +29,14 @@ class BisonWrap {
// Deliberately releases the contained value. Errors if not initialized.
// Called directly in parser.ypp when releasing pairs.
auto Release() -> T {
CHECK(val.has_value());
T ret = std::move(*val);
val.reset();
CHECK(val_.has_value());
T ret = std::move(*val_);
val_.reset();
return ret;
}
private:
std::optional<T> val;
std::optional<T> val_;
};
} // namespace Carbon
@@ -18,13 +18,13 @@ class ParseAndLexContext {
public:
// Creates an instance analyzing the given input file.
ParseAndLexContext(Nonnull<const std::string*> input_file_name, bool trace)
: input_file_name(input_file_name), trace_(trace) {}
: input_file_name_(input_file_name), trace_(trace) {}
// Writes a syntax error diagnostic containing message to standard error.
auto PrintDiagnostic(const std::string& message) -> void;
auto source_loc() -> SourceLocation {
return SourceLocation(input_file_name,
return SourceLocation(input_file_name_,
static_cast<int>(current_token_position.begin.line));
}
@@ -36,7 +36,7 @@ class ParseAndLexContext {
private:
// A path to the file processed, relative to the current working directory
// when *this is called.
Nonnull<const std::string*> input_file_name;
Nonnull<const std::string*> input_file_name_;
bool trace_;
};