Refactor Value accessors (#892)

This commit is contained in:
Jon Meow
2021-10-18 10:50:56 -07:00
committed by GitHub
parent 8bda2ca432
commit eeed6301d6
4 changed files with 248 additions and 243 deletions
@@ -79,24 +79,24 @@ auto Interpreter::EvalPrim(Operator op,
SourceLocation source_loc) -> Nonnull<const Value*> {
switch (op) {
case Operator::Neg:
return arena->New<IntValue>(-cast<IntValue>(*args[0]).Val());
return arena->New<IntValue>(-cast<IntValue>(*args[0]).value());
case Operator::Add:
return arena->New<IntValue>(cast<IntValue>(*args[0]).Val() +
cast<IntValue>(*args[1]).Val());
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]).Val() -
cast<IntValue>(*args[1]).Val());
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]).Val() *
cast<IntValue>(*args[1]).Val());
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]).Val());
return arena->New<BoolValue>(!cast<BoolValue>(*args[0]).value());
case Operator::And:
return arena->New<BoolValue>(cast<BoolValue>(*args[0]).Val() &&
cast<BoolValue>(*args[1]).Val());
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]).Val() ||
cast<BoolValue>(*args[1]).Val());
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));
case Operator::Ptr:
@@ -222,9 +222,9 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
case Value::Kind::BindingPlaceholderValue: {
const auto& placeholder = cast<BindingPlaceholderValue>(*p);
Env values(arena);
if (placeholder.Name().has_value()) {
if (placeholder.name().has_value()) {
Address a = heap.AllocateValue(CopyVal(arena, v, source_loc));
values.Set(*placeholder.Name(), a);
values.Set(*placeholder.name(), a);
}
return values;
}
@@ -233,15 +233,15 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
case Value::Kind::TupleValue: {
const auto& p_tup = cast<TupleValue>(*p);
const auto& v_tup = cast<TupleValue>(*v);
if (p_tup.Elements().size() != v_tup.Elements().size()) {
if (p_tup.elements().size() != v_tup.elements().size()) {
FATAL_PROGRAM_ERROR(source_loc)
<< "arity mismatch in tuple pattern match:\n pattern: "
<< p_tup << "\n value: " << v_tup;
}
Env values(arena);
for (size_t i = 0; i < p_tup.Elements().size(); ++i) {
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);
p_tup.elements()[i], v_tup.elements()[i], source_loc);
if (!matches) {
return std::nullopt;
}
@@ -278,11 +278,11 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
case Value::Kind::AlternativeValue: {
const auto& p_alt = cast<AlternativeValue>(*p);
const auto& v_alt = cast<AlternativeValue>(*v);
if (p_alt.ChoiceName() != v_alt.ChoiceName() ||
p_alt.AltName() != v_alt.AltName()) {
if (p_alt.choice_name() != v_alt.choice_name() ||
p_alt.alt_name() != v_alt.alt_name()) {
return std::nullopt;
}
return PatternMatch(p_alt.Argument(), v_alt.Argument(), source_loc);
return PatternMatch(&p_alt.argument(), &v_alt.argument(), source_loc);
}
default:
FATAL() << "expected a choice alternative in pattern, not " << *v;
@@ -293,12 +293,12 @@ auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
const auto& p_fn = cast<FunctionType>(*p);
const auto& v_fn = cast<FunctionType>(*v);
std::optional<Env> param_matches =
PatternMatch(p_fn.Param(), v_fn.Param(), source_loc);
PatternMatch(&p_fn.parameters(), &v_fn.parameters(), source_loc);
if (!param_matches) {
return std::nullopt;
}
std::optional<Env> ret_matches =
PatternMatch(p_fn.Ret(), v_fn.Ret(), source_loc);
std::optional<Env> ret_matches = PatternMatch(
&p_fn.return_type(), &v_fn.return_type(), source_loc);
if (!ret_matches) {
return std::nullopt;
}
@@ -329,7 +329,7 @@ void Interpreter::PatternAssignment(Nonnull<const Value*> pat,
SourceLocation source_loc) {
switch (pat->kind()) {
case Value::Kind::PointerValue:
heap.Write(cast<PointerValue>(*pat).Val(),
heap.Write(cast<PointerValue>(*pat).value(),
CopyVal(arena, val, source_loc), source_loc);
break;
case Value::Kind::TupleValue: {
@@ -337,13 +337,13 @@ void Interpreter::PatternAssignment(Nonnull<const Value*> pat,
case Value::Kind::TupleValue: {
const auto& pat_tup = cast<TupleValue>(*pat);
const auto& val_tup = cast<TupleValue>(*val);
if (pat_tup.Elements().size() != val_tup.Elements().size()) {
if (pat_tup.elements().size() != val_tup.elements().size()) {
FATAL_RUNTIME_ERROR(source_loc)
<< "arity mismatch in tuple pattern assignment:\n pattern: "
<< pat_tup << "\n value: " << val_tup;
}
for (size_t i = 0; i < pat_tup.Elements().size(); ++i) {
PatternAssignment(pat_tup.Elements()[i], val_tup.Elements()[i],
for (size_t i = 0; i < pat_tup.elements().size(); ++i) {
PatternAssignment(pat_tup.elements()[i], val_tup.elements()[i],
source_loc);
}
break;
@@ -358,10 +358,11 @@ void Interpreter::PatternAssignment(Nonnull<const Value*> pat,
case Value::Kind::AlternativeValue: {
const auto& pat_alt = cast<AlternativeValue>(*pat);
const auto& val_alt = cast<AlternativeValue>(*val);
CHECK(val_alt.ChoiceName() == pat_alt.ChoiceName() &&
val_alt.AltName() == pat_alt.AltName())
CHECK(val_alt.choice_name() == pat_alt.choice_name() &&
val_alt.alt_name() == pat_alt.alt_name())
<< "internal error in pattern assignment";
PatternAssignment(pat_alt.Argument(), val_alt.Argument(), source_loc);
PatternAssignment(&pat_alt.argument(), &val_alt.argument(),
source_loc);
break;
}
default:
@@ -400,7 +401,7 @@ auto Interpreter::StepLvalue() -> Transition {
} else {
// { v :: [].f :: C, E, F} :: S, H}
// -> { { &v.f :: C, E, F} :: S, H }
Address aggregate = cast<PointerValue>(*act->results()[0]).Val();
Address aggregate = cast<PointerValue>(*act->results()[0]).value();
Address field = aggregate.SubobjectAddress(
cast<FieldAccessExpression>(*exp).field());
return Done{arena->New<PointerValue>(field)};
@@ -419,9 +420,9 @@ auto Interpreter::StepLvalue() -> Transition {
} else {
// { v :: [][i] :: C, E, F} :: S, H}
// -> { { &v[i] :: C, E, F} :: S, H }
Address aggregate = cast<PointerValue>(*act->results()[0]).Val();
Address aggregate = cast<PointerValue>(*act->results()[0]).value();
std::string f =
std::to_string(cast<IntValue>(*act->results()[1]).Val());
std::to_string(cast<IntValue>(*act->results()[1]).value());
Address field = aggregate.SubobjectAddress(f);
return Done{arena->New<PointerValue>(field)};
}
@@ -479,12 +480,12 @@ auto Interpreter::StepExp() -> Transition {
// { { v :: [][i] :: C, E, F} :: S, H}
// -> { { v_i :: C, E, F} : S, H}
const auto& tuple = cast<TupleValue>(*act->results()[0]);
int i = cast<IntValue>(*act->results()[1]).Val();
if (i < 0 || i >= static_cast<int>(tuple.Elements().size())) {
int i = cast<IntValue>(*act->results()[1]).value();
if (i < 0 || i >= static_cast<int>(tuple.elements().size())) {
FATAL_RUNTIME_ERROR_NO_LINE()
<< "index " << i << " out of range in " << tuple;
}
return Done{tuple.Elements()[i]};
return Done{tuple.elements()[i]};
}
}
case Expression::Kind::TupleLiteral: {
@@ -583,8 +584,8 @@ auto Interpreter::StepExp() -> Transition {
cast<AlternativeConstructorValue>(*act->results()[0]);
Nonnull<const Value*> arg =
CopyVal(arena, act->results()[1], exp->source_loc());
return Done{arena->New<AlternativeValue>(alt.AltName(),
alt.ChoiceName(), arg)};
return Done{arena->New<AlternativeValue>(alt.alt_name(),
alt.choice_name(), arg)};
}
case Value::Kind::FunctionValue:
return CallFunction{
@@ -610,7 +611,7 @@ auto Interpreter::StepExp() -> Transition {
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).Val();
llvm::outs() << cast<StringValue>(*pointee).value();
return Done{TupleValue::Empty()};
}
@@ -701,7 +702,7 @@ auto Interpreter::StepPattern() -> Transition {
CHECK(act->pos() == 2);
const auto& choice_type = cast<ChoiceType>(*act->results()[0]);
return Done{arena->New<AlternativeValue>(alternative.alternative_name(),
choice_type.Name(),
choice_type.name(),
act->results()[1])};
}
}
@@ -806,7 +807,7 @@ auto Interpreter::StepStmt() -> Transition {
act->Clear();
return Spawn{
arena->New<ExpressionAction>(&cast<While>(*stmt).condition())};
} else if (cast<BoolValue>(*act->results().back()).Val()) {
} 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())};
@@ -913,7 +914,7 @@ auto Interpreter::StepStmt() -> Transition {
// -> { { e :: (if ([]) then_stmt else else_stmt) :: C, E, F} :: S, H}
return Spawn{
arena->New<ExpressionAction>(&cast<If>(*stmt).condition())};
} else if (cast<BoolValue>(*act->results()[0]).Val()) {
} 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}
@@ -997,7 +998,7 @@ auto Interpreter::StepStmt() -> Transition {
frame->todo.Push(ignore_result);
// Push the continuation onto the current stack.
std::vector<Nonnull<Frame*>>& continuation_vector =
*cast<ContinuationValue>(*act->results()[0]).Stack();
cast<ContinuationValue>(*act->results()[0]).stack();
while (!continuation_vector.empty()) {
stack.Push(continuation_vector.back());
continuation_vector.pop_back();
@@ -1015,8 +1016,8 @@ auto Interpreter::StepStmt() -> Transition {
// Update the continuation with the paused stack.
const auto& continuation = cast<ContinuationValue>(
*heap.Read(*paused.back()->continuation, stmt->source_loc()));
CHECK(continuation.Stack()->empty());
*continuation.Stack() = std::move(paused);
CHECK(continuation.stack().empty());
continuation.stack() = std::move(paused);
return ManualTransition{};
}
}
@@ -1084,7 +1085,7 @@ class Interpreter::DoTransition {
void operator()(const CallFunction& call) {
interpreter->stack.Top()->todo.Pop();
std::optional<Env> matches = interpreter->PatternMatch(
call.function->Param(), call.args, call.source_loc);
&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
@@ -1096,11 +1097,11 @@ class Interpreter::DoTransition {
}
auto scopes =
Stack<Nonnull<Scope*>>(interpreter->arena->New<Scope>(values, params));
CHECK(call.function->Body()) << "Calling a function that's missing a body";
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->arena->New<Frame>(call.function->name(), scopes, todo);
interpreter->stack.Push(frame);
}
@@ -1163,7 +1164,7 @@ auto Interpreter::InterpProgram(llvm::ArrayRef<Nonnull<Declaration*>> fs,
PrintState(llvm::outs());
}
}
return cast<IntValue>(**program_value).Val();
return cast<IntValue>(**program_value).value();
}
auto Interpreter::InterpExp(Env values, Nonnull<const Expression*> e)
@@ -126,7 +126,7 @@ static auto IsConcreteType(Nonnull<const Value*> value) -> bool {
// `auto` isn't a concrete type, it's a pattern that matches types.
return false;
case Value::Kind::TupleValue:
for (Nonnull<const Value*> field : cast<TupleValue>(*value).Elements()) {
for (Nonnull<const Value*> field : cast<TupleValue>(*value).elements()) {
if (!IsConcreteType(field)) {
return false;
}
@@ -185,7 +185,7 @@ static auto IsImplicitlyConvertible(Nonnull<const Value*> source,
case Value::Kind::NominalClassType:
return FieldTypesImplicitlyConvertible(
cast<StructType>(*source).fields(),
cast<NominalClassType>(*destination).Fields());
cast<NominalClassType>(*destination).fields());
default:
return false;
}
@@ -193,9 +193,9 @@ static auto IsImplicitlyConvertible(Nonnull<const Value*> source,
switch (destination->kind()) {
case Value::Kind::TupleValue: {
const std::vector<Nonnull<const Value*>>& source_elements =
cast<TupleValue>(*source).Elements();
cast<TupleValue>(*source).elements();
const std::vector<Nonnull<const Value*>>& destination_elements =
cast<TupleValue>(*destination).Elements();
cast<TupleValue>(*destination).elements();
if (source_elements.size() != destination_elements.size()) {
return false;
}
@@ -238,9 +238,9 @@ static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
switch (param->kind()) {
case Value::Kind::VariableType: {
const auto& var_type = cast<VariableType>(*param);
std::optional<Nonnull<const Value*>> d = deduced.Get(var_type.Name());
std::optional<Nonnull<const Value*>> d = deduced.Get(var_type.name());
if (!d) {
deduced.Set(var_type.Name(), arg);
deduced.Set(var_type.name(), arg);
} else {
// TODO: can we allow implicit conversions here?
ExpectExactType(source_loc, "argument deduction", *d, arg);
@@ -256,16 +256,16 @@ static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
}
const auto& param_tup = cast<TupleValue>(*param);
const auto& arg_tup = cast<TupleValue>(*arg);
if (param_tup.Elements().size() != arg_tup.Elements().size()) {
if (param_tup.elements().size() != arg_tup.elements().size()) {
FATAL_COMPILATION_ERROR(source_loc)
<< "mismatch in tuple sizes, expected "
<< param_tup.Elements().size() << " but got "
<< arg_tup.Elements().size();
<< param_tup.elements().size() << " but got "
<< arg_tup.elements().size();
}
for (size_t i = 0; i < param_tup.Elements().size(); ++i) {
for (size_t i = 0; i < param_tup.elements().size(); ++i) {
deduced =
ArgumentDeduction(source_loc, deduced, param_tup.Elements()[i],
arg_tup.Elements()[i]);
ArgumentDeduction(source_loc, deduced, param_tup.elements()[i],
arg_tup.elements()[i]);
}
return deduced;
}
@@ -306,10 +306,10 @@ static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
const auto& param_fn = cast<FunctionType>(*param);
const auto& arg_fn = cast<FunctionType>(*arg);
// TODO: handle situation when arg has deduced parameters.
deduced = ArgumentDeduction(source_loc, deduced, param_fn.Param(),
arg_fn.Param());
deduced =
ArgumentDeduction(source_loc, deduced, param_fn.Ret(), arg_fn.Ret());
deduced = ArgumentDeduction(source_loc, deduced, &param_fn.parameters(),
&arg_fn.parameters());
deduced = ArgumentDeduction(source_loc, deduced, &param_fn.return_type(),
&arg_fn.return_type());
return deduced;
}
case Value::Kind::PointerType: {
@@ -320,8 +320,8 @@ static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
<< "actual: " << *arg;
}
return ArgumentDeduction(source_loc, deduced,
cast<PointerType>(*param).Type(),
cast<PointerType>(*arg).Type());
&cast<PointerType>(*param).type(),
&cast<PointerType>(*arg).type());
}
// Nothing to do in the case for `auto`.
case Value::Kind::AutoType: {
@@ -358,7 +358,7 @@ auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
switch (type->kind()) {
case Value::Kind::VariableType: {
std::optional<Nonnull<const Value*>> t =
dict.Get(cast<VariableType>(*type).Name());
dict.Get(cast<VariableType>(*type).name());
if (!t) {
return type;
} else {
@@ -367,7 +367,7 @@ auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
}
case Value::Kind::TupleValue: {
std::vector<Nonnull<const Value*>> elts;
for (const auto& elt : cast<TupleValue>(*type).Elements()) {
for (const auto& elt : cast<TupleValue>(*type).elements()) {
elts.push_back(Substitute(dict, elt));
}
return arena->New<TupleValue>(elts);
@@ -382,14 +382,14 @@ auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
}
case Value::Kind::FunctionType: {
const auto& fn_type = cast<FunctionType>(*type);
auto param = Substitute(dict, fn_type.Param());
auto ret = Substitute(dict, fn_type.Ret());
auto param = Substitute(dict, &fn_type.parameters());
auto ret = Substitute(dict, &fn_type.return_type());
return arena->New<FunctionType>(std::vector<GenericBinding>(), param,
ret);
}
case Value::Kind::PointerType: {
return arena->New<PointerType>(
Substitute(dict, cast<PointerType>(*type).Type()));
Substitute(dict, &cast<PointerType>(*type).type()));
}
case Value::Kind::AutoType:
case Value::Kind::IntType:
@@ -435,12 +435,12 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
const auto& tuple_type = cast<TupleValue>(aggregate_type);
int i =
cast<IntValue>(*interpreter.InterpExp(values, &index.offset()))
.Val();
if (i < 0 || i >= static_cast<int>(tuple_type.Elements().size())) {
.value();
if (i < 0 || i >= static_cast<int>(tuple_type.elements().size())) {
FATAL_COMPILATION_ERROR(e->source_loc())
<< "index " << i << " is out of range for type " << tuple_type;
}
SetStaticType(&index, tuple_type.Elements()[i]);
SetStaticType(&index, tuple_type.elements()[i]);
return TCResult(res.types);
}
default:
@@ -513,26 +513,26 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
case Value::Kind::NominalClassType: {
const auto& t_class = cast<NominalClassType>(aggregate_type);
// Search for a field
for (auto& field : t_class.Fields()) {
for (auto& field : t_class.fields()) {
if (access.field() == field.first) {
SetStaticType(&access, field.second);
return TCResult(res.types);
}
}
// Search for a method
for (auto& method : t_class.Methods()) {
for (auto& method : t_class.methods()) {
if (access.field() == method.first) {
SetStaticType(&access, method.second);
return TCResult(res.types);
}
}
FATAL_COMPILATION_ERROR(e->source_loc())
<< "class " << t_class.Name() << " does not have a field named "
<< "class " << t_class.name() << " does not have a field named "
<< access.field();
}
case Value::Kind::ChoiceType: {
const auto& choice = cast<ChoiceType>(aggregate_type);
for (const auto& vt : choice.Alternatives()) {
for (const auto& vt : choice.alternatives()) {
if (access.field() == vt.first) {
SetStaticType(&access, arena->New<FunctionType>(
std::vector<GenericBinding>(),
@@ -541,7 +541,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
}
}
FATAL_COMPILATION_ERROR(e->source_loc())
<< "choice " << choice.Name() << " does not have a field named "
<< "choice " << choice.name() << " does not have a field named "
<< access.field();
}
default:
@@ -629,7 +629,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
return TCResult(new_types);
case Operator::Deref:
ExpectPointerType(e->source_loc(), "*", ts[0]);
SetStaticType(&op, cast<PointerType>(*ts[0]).Type());
SetStaticType(&op, &cast<PointerType>(*ts[0]).type());
return TCResult(new_types);
case Operator::Ptr:
ExpectExactType(e->source_loc(), "*", arena->New<TypeType>(), ts[0]);
@@ -645,13 +645,13 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
case Value::Kind::FunctionType: {
const auto& fun_t = cast<FunctionType>(call.function().static_type());
auto arg_res = TypeCheckExp(&call.argument(), fun_res.types, values);
auto parameter_type = fun_t.Param();
auto return_type = fun_t.Ret();
if (!fun_t.Deduced().empty()) {
auto deduced_args = ArgumentDeduction(
e->source_loc(), TypeEnv(arena), parameter_type,
&call.argument().static_type());
for (auto& deduced_param : fun_t.Deduced()) {
Nonnull<const Value*> parameters = &fun_t.parameters();
Nonnull<const Value*> return_type = &fun_t.return_type();
if (!fun_t.deduced().empty()) {
auto deduced_args =
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
// has been added to the type checking of function signatures.
if (!deduced_args.Get(deduced_param.name)) {
@@ -660,10 +660,10 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
<< deduced_param.name;
}
}
parameter_type = Substitute(deduced_args, parameter_type);
parameters = Substitute(deduced_args, parameters);
return_type = Substitute(deduced_args, return_type);
} else {
ExpectType(e->source_loc(), "call", parameter_type,
ExpectType(e->source_loc(), "call", parameters,
&call.argument().static_type());
}
SetStaticType(&call, return_type);
@@ -760,7 +760,7 @@ auto TypeChecker::TypeCheckPattern(
FATAL_COMPILATION_ERROR(p->source_loc()) << "didn't expect a tuple";
}
if (expected && tuple.fields().size() !=
cast<TupleValue>(**expected).Elements().size()) {
cast<TupleValue>(**expected).elements().size()) {
FATAL_COMPILATION_ERROR(tuple.source_loc())
<< "tuples of different length";
}
@@ -768,7 +768,7 @@ auto TypeChecker::TypeCheckPattern(
Nonnull<Pattern*> field = tuple.fields()[i];
std::optional<Nonnull<const Value*>> expected_field_type;
if (expected) {
expected_field_type = cast<TupleValue>(**expected).Elements()[i];
expected_field_type = cast<TupleValue>(**expected).elements()[i];
}
auto field_result =
TypeCheckPattern(field, new_types, values, expected_field_type);
@@ -792,7 +792,7 @@ auto TypeChecker::TypeCheckPattern(
}
std::optional<Nonnull<const Value*>> parameter_types =
FindInVarValues(alternative.alternative_name(),
cast<ChoiceType>(*choice_type).Alternatives());
cast<ChoiceType>(*choice_type).alternatives());
if (parameter_types == std::nullopt) {
FATAL_COMPILATION_ERROR(alternative.source_loc())
<< "'" << alternative.alternative_name()
+61 -60
View File
@@ -70,7 +70,7 @@ auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
}
case Value::Kind::NominalClassValue: {
std::optional<Nonnull<const Value*>> field =
cast<StructValue>(*cast<NominalClassValue>(*v).Inits()).FindField(f);
cast<StructValue>(cast<NominalClassValue>(*v).inits()).FindField(f);
if (field == std::nullopt) {
FATAL_RUNTIME_ERROR(source_loc) << "member " << f << " not in " << *v;
}
@@ -78,11 +78,11 @@ auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
}
case Value::Kind::ChoiceType: {
const auto& choice = cast<ChoiceType>(*v);
if (!FindInVarValues(f, choice.Alternatives())) {
if (!FindInVarValues(f, choice.alternatives())) {
FATAL_RUNTIME_ERROR(source_loc)
<< "alternative " << f << " not in " << *v;
}
return arena->New<AlternativeConstructorValue>(f, choice.Name());
return arena->New<AlternativeConstructorValue>(f, choice.name());
}
default:
FATAL() << "field access not allowed for value " << *v;
@@ -127,12 +127,12 @@ auto SetFieldImpl(Nonnull<Arena*> arena, Nonnull<const Value*> value,
return arena->New<StructValue>(elements);
}
case Value::Kind::NominalClassValue: {
return SetFieldImpl(arena, cast<NominalClassValue>(*value).Inits(),
return SetFieldImpl(arena, &cast<NominalClassValue>(*value).inits(),
path_begin, path_end, field_value, source_loc);
}
case Value::Kind::TupleValue: {
std::vector<Nonnull<const Value*>> elements =
cast<TupleValue>(*value).Elements();
cast<TupleValue>(*value).elements();
// TODO(geoffromer): update FieldPath to hold integers as well as strings.
int index = std::stoi(*path_begin);
if (index < 0 || static_cast<size_t>(index) >= elements.size()) {
@@ -162,23 +162,23 @@ void Value::Print(llvm::raw_ostream& out) const {
switch (kind()) {
case Value::Kind::AlternativeConstructorValue: {
const auto& alt = cast<AlternativeConstructorValue>(*this);
out << alt.ChoiceName() << "." << alt.AltName();
out << alt.choice_name() << "." << alt.alt_name();
break;
}
case Value::Kind::BindingPlaceholderValue: {
const auto& placeholder = cast<BindingPlaceholderValue>(*this);
if (placeholder.Name().has_value()) {
out << *placeholder.Name();
if (placeholder.name().has_value()) {
out << *placeholder.name();
} else {
out << "_";
}
out << ": " << *placeholder.Type();
out << ": " << placeholder.type();
break;
}
case Value::Kind::AlternativeValue: {
const auto& alt = cast<AlternativeValue>(*this);
out << "alt " << alt.ChoiceName() << "." << alt.AltName() << " "
<< *alt.Argument();
out << "alt " << alt.choice_name() << "." << alt.alt_name() << " "
<< alt.argument();
break;
}
case Value::Kind::StructValue: {
@@ -193,29 +193,29 @@ void Value::Print(llvm::raw_ostream& out) const {
}
case Value::Kind::NominalClassValue: {
const auto& s = cast<NominalClassValue>(*this);
out << cast<NominalClassType>(*s.Type()).Name() << *s.Inits();
out << cast<NominalClassType>(s.type()).name() << s.inits();
break;
}
case Value::Kind::TupleValue: {
out << "(";
llvm::ListSeparator sep;
for (Nonnull<const Value*> element : cast<TupleValue>(*this).Elements()) {
for (Nonnull<const Value*> element : cast<TupleValue>(*this).elements()) {
out << sep << *element;
}
out << ")";
break;
}
case Value::Kind::IntValue:
out << cast<IntValue>(*this).Val();
out << cast<IntValue>(*this).value();
break;
case Value::Kind::BoolValue:
out << (cast<BoolValue>(*this).Val() ? "true" : "false");
out << (cast<BoolValue>(*this).value() ? "true" : "false");
break;
case Value::Kind::FunctionValue:
out << "fun<" << cast<FunctionValue>(*this).Name() << ">";
out << "fun<" << cast<FunctionValue>(*this).name() << ">";
break;
case Value::Kind::PointerValue:
out << "ptr<" << cast<PointerValue>(*this).Val() << ">";
out << "ptr<" << cast<PointerValue>(*this).value() << ">";
break;
case Value::Kind::BoolType:
out << "Bool";
@@ -233,15 +233,15 @@ void Value::Print(llvm::raw_ostream& out) const {
out << "Continuation";
break;
case Value::Kind::PointerType:
out << *cast<PointerType>(*this).Type() << "*";
out << cast<PointerType>(*this).type() << "*";
break;
case Value::Kind::FunctionType: {
const auto& fn_type = cast<FunctionType>(*this);
out << "fn ";
if (fn_type.Deduced().size() > 0) {
if (fn_type.deduced().size() > 0) {
out << "[";
unsigned int i = 0;
for (const auto& deduced : fn_type.Deduced()) {
for (const auto& deduced : fn_type.deduced()) {
if (i != 0) {
out << ", ";
}
@@ -250,7 +250,7 @@ void Value::Print(llvm::raw_ostream& out) const {
}
out << "]";
}
out << *fn_type.Param() << " -> " << *fn_type.Ret();
out << fn_type.parameters() << " -> " << fn_type.return_type();
break;
}
case Value::Kind::StructType: {
@@ -263,18 +263,18 @@ void Value::Print(llvm::raw_ostream& out) const {
break;
}
case Value::Kind::NominalClassType:
out << "class " << cast<NominalClassType>(*this).Name();
out << "class " << cast<NominalClassType>(*this).name();
break;
case Value::Kind::ChoiceType:
out << "choice " << cast<ChoiceType>(*this).Name();
out << "choice " << cast<ChoiceType>(*this).name();
break;
case Value::Kind::VariableType:
out << cast<VariableType>(*this).Name();
out << cast<VariableType>(*this).name();
break;
case Value::Kind::ContinuationValue: {
out << "{";
llvm::ListSeparator sep(" :: ");
for (Nonnull<Frame*> frame : *cast<ContinuationValue>(*this).Stack()) {
for (Nonnull<Frame*> frame : cast<ContinuationValue>(*this).stack()) {
out << sep << *frame;
}
out << "}";
@@ -285,7 +285,7 @@ void Value::Print(llvm::raw_ostream& out) const {
break;
case Value::Kind::StringValue:
out << "\"";
out.write_escaped(cast<StringValue>(*this).Val());
out.write_escaped(cast<StringValue>(*this).value());
out << "\"";
break;
}
@@ -296,15 +296,16 @@ auto CopyVal(Nonnull<Arena*> arena, Nonnull<const Value*> val,
switch (val->kind()) {
case Value::Kind::TupleValue: {
std::vector<Nonnull<const Value*>> elements;
for (Nonnull<const Value*> element : cast<TupleValue>(*val).Elements()) {
for (Nonnull<const Value*> element : cast<TupleValue>(*val).elements()) {
elements.push_back(CopyVal(arena, element, source_loc));
}
return arena->New<TupleValue>(std::move(elements));
}
case Value::Kind::AlternativeValue: {
const auto& alt = cast<AlternativeValue>(*val);
Nonnull<const Value*> arg = CopyVal(arena, alt.Argument(), source_loc);
return arena->New<AlternativeValue>(alt.AltName(), alt.ChoiceName(), arg);
Nonnull<const Value*> arg = CopyVal(arena, &alt.argument(), source_loc);
return arena->New<AlternativeValue>(alt.alt_name(), alt.choice_name(),
arg);
}
case Value::Kind::StructValue: {
std::vector<StructElement> elements;
@@ -317,32 +318,32 @@ auto CopyVal(Nonnull<Arena*> arena, Nonnull<const Value*> val,
}
case Value::Kind::NominalClassValue: {
const auto& s = cast<NominalClassValue>(*val);
Nonnull<const Value*> inits = CopyVal(arena, s.Inits(), source_loc);
return arena->New<NominalClassValue>(s.Type(), inits);
Nonnull<const Value*> inits = CopyVal(arena, &s.inits(), source_loc);
return arena->New<NominalClassValue>(&s.type(), inits);
}
case Value::Kind::IntValue:
return arena->New<IntValue>(cast<IntValue>(*val).Val());
return arena->New<IntValue>(cast<IntValue>(*val).value());
case Value::Kind::BoolValue:
return arena->New<BoolValue>(cast<BoolValue>(*val).Val());
return arena->New<BoolValue>(cast<BoolValue>(*val).value());
case Value::Kind::FunctionValue: {
const auto& fn_value = cast<FunctionValue>(*val);
return arena->New<FunctionValue>(fn_value.Name(), fn_value.Param(),
fn_value.Body());
return arena->New<FunctionValue>(fn_value.name(), &fn_value.parameters(),
fn_value.body());
}
case Value::Kind::PointerValue:
return arena->New<PointerValue>(cast<PointerValue>(*val).Val());
return arena->New<PointerValue>(cast<PointerValue>(*val).value());
case Value::Kind::ContinuationValue:
return arena->New<ContinuationValue>(
cast<ContinuationValue>(*val).Stack());
&cast<ContinuationValue>(*val).stack());
case Value::Kind::FunctionType: {
const auto& fn_type = cast<FunctionType>(*val);
return arena->New<FunctionType>(
fn_type.Deduced(), CopyVal(arena, fn_type.Param(), source_loc),
CopyVal(arena, fn_type.Ret(), source_loc));
fn_type.deduced(), CopyVal(arena, &fn_type.parameters(), source_loc),
CopyVal(arena, &fn_type.return_type(), source_loc));
}
case Value::Kind::PointerType:
return arena->New<PointerType>(
CopyVal(arena, cast<PointerType>(*val).Type(), source_loc));
CopyVal(arena, &cast<PointerType>(*val).type(), source_loc));
case Value::Kind::IntType:
return arena->New<IntType>();
case Value::Kind::BoolType:
@@ -356,7 +357,7 @@ auto CopyVal(Nonnull<Arena*> arena, Nonnull<const Value*> val,
case Value::Kind::StringType:
return arena->New<StringType>();
case Value::Kind::StringValue:
return arena->New<StringValue>(cast<StringValue>(*val).Val());
return arena->New<StringValue>(cast<StringValue>(*val).value());
case Value::Kind::StructType: {
VarValues fields;
for (const auto& [name, type] : cast<StructType>(*val).fields()) {
@@ -380,13 +381,13 @@ auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2) -> bool {
}
switch (t1->kind()) {
case Value::Kind::PointerType:
return TypeEqual(cast<PointerType>(*t1).Type(),
cast<PointerType>(*t2).Type());
return TypeEqual(&cast<PointerType>(*t1).type(),
&cast<PointerType>(*t2).type());
case Value::Kind::FunctionType: {
const auto& fn1 = cast<FunctionType>(*t1);
const auto& fn2 = cast<FunctionType>(*t2);
return TypeEqual(fn1.Param(), fn2.Param()) &&
TypeEqual(fn1.Ret(), fn2.Ret());
return TypeEqual(&fn1.parameters(), &fn2.parameters()) &&
TypeEqual(&fn1.return_type(), &fn2.return_type());
}
case Value::Kind::StructType: {
const auto& struct1 = cast<StructType>(*t1);
@@ -404,18 +405,18 @@ auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2) -> bool {
return true;
}
case Value::Kind::NominalClassType:
return cast<NominalClassType>(*t1).Name() ==
cast<NominalClassType>(*t2).Name();
return cast<NominalClassType>(*t1).name() ==
cast<NominalClassType>(*t2).name();
case Value::Kind::ChoiceType:
return cast<ChoiceType>(*t1).Name() == cast<ChoiceType>(*t2).Name();
return cast<ChoiceType>(*t1).name() == cast<ChoiceType>(*t2).name();
case Value::Kind::TupleValue: {
const auto& tup1 = cast<TupleValue>(*t1);
const auto& tup2 = cast<TupleValue>(*t2);
if (tup1.Elements().size() != tup2.Elements().size()) {
if (tup1.elements().size() != tup2.elements().size()) {
return false;
}
for (size_t i = 0; i < tup1.Elements().size(); ++i) {
if (!TypeEqual(tup1.Elements()[i], tup2.Elements()[i])) {
for (size_t i = 0; i < tup1.elements().size(); ++i) {
if (!TypeEqual(tup1.elements()[i], tup2.elements()[i])) {
return false;
}
}
@@ -428,7 +429,7 @@ auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2) -> bool {
case Value::Kind::StringType:
return true;
case Value::Kind::VariableType:
return cast<VariableType>(*t1).Name() == cast<VariableType>(*t2).Name();
return cast<VariableType>(*t1).name() == cast<VariableType>(*t2).name();
default:
FATAL() << "TypeEqual used to compare non-type values\n"
<< *t1 << "\n"
@@ -468,24 +469,24 @@ auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2,
}
switch (v1->kind()) {
case Value::Kind::IntValue:
return cast<IntValue>(*v1).Val() == cast<IntValue>(*v2).Val();
return cast<IntValue>(*v1).value() == cast<IntValue>(*v2).value();
case Value::Kind::BoolValue:
return cast<BoolValue>(*v1).Val() == cast<BoolValue>(*v2).Val();
return cast<BoolValue>(*v1).value() == cast<BoolValue>(*v2).value();
case Value::Kind::PointerValue:
return cast<PointerValue>(*v1).Val() == cast<PointerValue>(*v2).Val();
return cast<PointerValue>(*v1).value() == cast<PointerValue>(*v2).value();
case Value::Kind::FunctionValue: {
std::optional<Nonnull<const Statement*>> body1 =
cast<FunctionValue>(*v1).Body();
cast<FunctionValue>(*v1).body();
std::optional<Nonnull<const Statement*>> body2 =
cast<FunctionValue>(*v2).Body();
cast<FunctionValue>(*v2).body();
return body1.has_value() == body2.has_value() &&
(!body1.has_value() || *body1 == *body2);
}
case Value::Kind::TupleValue: {
const std::vector<Nonnull<const Value*>>& elements1 =
cast<TupleValue>(*v1).Elements();
cast<TupleValue>(*v1).elements();
const std::vector<Nonnull<const Value*>>& elements2 =
cast<TupleValue>(*v2).Elements();
cast<TupleValue>(*v2).elements();
if (elements1.size() != elements2.size()) {
return false;
}
@@ -500,7 +501,7 @@ auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2,
return FieldsValueEqual(cast<StructValue>(*v1).elements(),
cast<StructValue>(*v2).elements(), source_loc);
case Value::Kind::StringValue:
return cast<StringValue>(*v1).Val() == cast<StringValue>(*v2).Val();
return cast<StringValue>(*v1).value() == cast<StringValue>(*v2).value();
case Value::Kind::IntType:
case Value::Kind::BoolType:
case Value::Kind::TypeType:
+92 -89
View File
@@ -111,71 +111,73 @@ struct Frame; // Used by continuation.
// An integer value.
class IntValue : public Value {
public:
explicit IntValue(int val) : Value(Kind::IntValue), val(val) {}
explicit IntValue(int value) : Value(Kind::IntValue), value_(value) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::IntValue;
}
auto Val() const -> int { return val; }
auto value() const -> int { return value_; }
private:
int val;
int value_;
};
// A function value.
class FunctionValue : public Value {
public:
FunctionValue(std::string name, Nonnull<const Value*> param,
FunctionValue(std::string name, Nonnull<const Value*> parameters,
std::optional<Nonnull<const Statement*>> body)
: Value(Kind::FunctionValue),
name(std::move(name)),
param(param),
body(body) {}
name_(std::move(name)),
parameters_(parameters),
body_(body) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::FunctionValue;
}
auto Name() const -> const std::string& { return name; }
auto Param() const -> Nonnull<const Value*> { return param; }
auto Body() const -> std::optional<Nonnull<const Statement*>> { return body; }
auto name() const -> const std::string& { return name_; }
auto parameters() const -> const Value& { return *parameters_; }
auto body() const -> std::optional<Nonnull<const Statement*>> {
return body_;
}
private:
std::string name;
Nonnull<const Value*> param;
std::optional<Nonnull<const Statement*>> body;
std::string name_;
Nonnull<const Value*> parameters_;
std::optional<Nonnull<const Statement*>> body_;
};
// A pointer value.
class PointerValue : public Value {
public:
explicit PointerValue(Address val)
: Value(Kind::PointerValue), val(std::move(val)) {}
explicit PointerValue(Address value)
: Value(Kind::PointerValue), value_(std::move(value)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::PointerValue;
}
auto Val() const -> const Address& { return val; }
auto value() const -> const Address& { return value_; }
private:
Address val;
Address value_;
};
// A bool value.
class BoolValue : public Value {
public:
explicit BoolValue(bool val) : Value(Kind::BoolValue), val(val) {}
explicit BoolValue(bool value) : Value(Kind::BoolValue), value_(value) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::BoolValue;
}
auto Val() const -> bool { return val; }
auto value() const -> bool { return value_; }
private:
bool val;
bool value_;
};
// A non-empty value of a struct type.
@@ -214,18 +216,18 @@ class StructValue : public Value {
class NominalClassValue : public Value {
public:
NominalClassValue(Nonnull<const Value*> type, Nonnull<const Value*> inits)
: Value(Kind::NominalClassValue), type(type), inits(inits) {}
: Value(Kind::NominalClassValue), type_(type), inits_(inits) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::NominalClassValue;
}
auto Type() const -> Nonnull<const Value*> { return type; }
auto Inits() const -> Nonnull<const Value*> { return inits; }
auto type() const -> const Value& { return *type_; }
auto inits() const -> const Value& { return *inits_; }
private:
Nonnull<const Value*> type;
Nonnull<const Value*> inits;
Nonnull<const Value*> type_;
Nonnull<const Value*> inits_;
};
// An alternative constructor value.
@@ -233,19 +235,19 @@ class AlternativeConstructorValue : public Value {
public:
AlternativeConstructorValue(std::string alt_name, std::string choice_name)
: Value(Kind::AlternativeConstructorValue),
alt_name(std::move(alt_name)),
choice_name(std::move(choice_name)) {}
alt_name_(std::move(alt_name)),
choice_name_(std::move(choice_name)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::AlternativeConstructorValue;
}
auto AltName() const -> const std::string& { return alt_name; }
auto ChoiceName() const -> const std::string& { return choice_name; }
auto alt_name() const -> const std::string& { return alt_name_; }
auto choice_name() const -> const std::string& { return choice_name_; }
private:
std::string alt_name;
std::string choice_name;
std::string alt_name_;
std::string choice_name_;
};
// An alternative value.
@@ -254,22 +256,22 @@ class AlternativeValue : public Value {
AlternativeValue(std::string alt_name, std::string choice_name,
Nonnull<const Value*> argument)
: Value(Kind::AlternativeValue),
alt_name(std::move(alt_name)),
choice_name(std::move(choice_name)),
argument(argument) {}
alt_name_(std::move(alt_name)),
choice_name_(std::move(choice_name)),
argument_(argument) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::AlternativeValue;
}
auto AltName() const -> const std::string& { return alt_name; }
auto ChoiceName() const -> const std::string& { return choice_name; }
auto Argument() const -> Nonnull<const Value*> { return argument; }
auto alt_name() const -> const std::string& { return alt_name_; }
auto choice_name() const -> const std::string& { return choice_name_; }
auto argument() const -> const Value& { return *argument_; }
private:
std::string alt_name;
std::string choice_name;
Nonnull<const Value*> argument;
std::string alt_name_;
std::string choice_name_;
Nonnull<const Value*> argument_;
};
// A function value.
@@ -283,18 +285,18 @@ class TupleValue : public Value {
}
explicit TupleValue(std::vector<Nonnull<const Value*>> elements)
: Value(Kind::TupleValue), elements(std::move(elements)) {}
: Value(Kind::TupleValue), elements_(std::move(elements)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::TupleValue;
}
auto Elements() const -> const std::vector<Nonnull<const Value*>>& {
return elements;
auto elements() const -> llvm::ArrayRef<Nonnull<const Value*>> {
return elements_;
}
private:
std::vector<Nonnull<const Value*>> elements;
std::vector<Nonnull<const Value*>> elements_;
};
// A binding placeholder value.
@@ -304,19 +306,19 @@ class BindingPlaceholderValue : public Value {
BindingPlaceholderValue(std::optional<std::string> name,
Nonnull<const Value*> type)
: Value(Kind::BindingPlaceholderValue),
name(std::move(name)),
type(type) {}
name_(std::move(name)),
type_(type) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::BindingPlaceholderValue;
}
auto Name() const -> const std::optional<std::string>& { return name; }
auto Type() const -> Nonnull<const Value*> { return type; }
auto name() const -> const std::optional<std::string>& { return name_; }
auto type() const -> const Value& { return *type_; }
private:
std::optional<std::string> name;
Nonnull<const Value*> type;
std::optional<std::string> name_;
Nonnull<const Value*> type_;
};
// The int type.
@@ -352,41 +354,42 @@ class TypeType : public Value {
// A function type.
class FunctionType : public Value {
public:
FunctionType(std::vector<GenericBinding> deduced, Nonnull<const Value*> param,
Nonnull<const Value*> ret)
FunctionType(std::vector<GenericBinding> deduced,
Nonnull<const Value*> parameters,
Nonnull<const Value*> return_type)
: Value(Kind::FunctionType),
deduced(std::move(deduced)),
param(param),
ret(ret) {}
deduced_(std::move(deduced)),
parameters_(parameters),
return_type_(return_type) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::FunctionType;
}
auto Deduced() const -> const std::vector<GenericBinding>& { return deduced; }
auto Param() const -> Nonnull<const Value*> { return param; }
auto Ret() const -> Nonnull<const Value*> { return ret; }
auto deduced() const -> llvm::ArrayRef<GenericBinding> { return deduced_; }
auto parameters() const -> const Value& { return *parameters_; }
auto return_type() const -> const Value& { return *return_type_; }
private:
std::vector<GenericBinding> deduced;
Nonnull<const Value*> param;
Nonnull<const Value*> ret;
std::vector<GenericBinding> deduced_;
Nonnull<const Value*> parameters_;
Nonnull<const Value*> return_type_;
};
// A pointer type.
class PointerType : public Value {
public:
explicit PointerType(Nonnull<const Value*> type)
: Value(Kind::PointerType), type(type) {}
: Value(Kind::PointerType), type_(type) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::PointerType;
}
auto Type() const -> Nonnull<const Value*> { return type; }
auto type() const -> const Value& { return *type_; }
private:
Nonnull<const Value*> type;
Nonnull<const Value*> type_;
};
// The `auto` type.
@@ -425,22 +428,22 @@ class NominalClassType : public Value {
public:
NominalClassType(std::string name, VarValues fields, VarValues methods)
: Value(Kind::NominalClassType),
name(std::move(name)),
fields(std::move(fields)),
methods(std::move(methods)) {}
name_(std::move(name)),
fields_(std::move(fields)),
methods_(std::move(methods)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::NominalClassType;
}
auto Name() const -> const std::string& { return name; }
auto Fields() const -> const VarValues& { return fields; }
auto Methods() const -> const VarValues& { return methods; }
auto name() const -> const std::string& { return name_; }
auto fields() const -> const VarValues& { return fields_; }
auto methods() const -> const VarValues& { return methods_; }
private:
std::string name;
VarValues fields;
VarValues methods;
std::string name_;
VarValues fields_;
VarValues methods_;
};
// A choice type.
@@ -448,19 +451,19 @@ class ChoiceType : public Value {
public:
ChoiceType(std::string name, VarValues alternatives)
: Value(Kind::ChoiceType),
name(std::move(name)),
alternatives(std::move(alternatives)) {}
name_(std::move(name)),
alternatives_(std::move(alternatives)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::ChoiceType;
}
auto Name() const -> const std::string& { return name; }
auto Alternatives() const -> const VarValues& { return alternatives; }
auto name() const -> const std::string& { return name_; }
auto alternatives() const -> const VarValues& { return alternatives_; }
private:
std::string name;
VarValues alternatives;
std::string name_;
VarValues alternatives_;
};
// A continuation type.
@@ -477,16 +480,16 @@ class ContinuationType : public Value {
class VariableType : public Value {
public:
explicit VariableType(std::string name)
: Value(Kind::VariableType), name(std::move(name)) {}
: Value(Kind::VariableType), name_(std::move(name)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::VariableType;
}
auto Name() const -> const std::string& { return name; }
auto name() const -> const std::string& { return name_; }
private:
std::string name;
std::string name_;
};
// A first-class continuation representation of a fragment of the stack.
@@ -495,7 +498,7 @@ class VariableType : public Value {
class ContinuationValue : public Value {
public:
explicit ContinuationValue(Nonnull<std::vector<Nonnull<Frame*>>*> stack)
: Value(Kind::ContinuationValue), stack(stack) {}
: Value(Kind::ContinuationValue), stack_(stack) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::ContinuationValue;
@@ -505,10 +508,10 @@ class ContinuationValue : public Value {
// frame (the reverse of the usual order). Note that this provides mutable
// access, even when *this is const, because of the reference-like semantics
// of ContinuationValue.
auto Stack() const -> Nonnull<std::vector<Nonnull<Frame*>>*> { return stack; }
auto stack() const -> std::vector<Nonnull<Frame*>>& { return *stack_; }
private:
Nonnull<std::vector<Nonnull<Frame*>>*> stack;
Nonnull<std::vector<Nonnull<Frame*>>*> stack_;
};
// The String type.
@@ -524,17 +527,17 @@ class StringType : public Value {
// A string value.
class StringValue : public Value {
public:
explicit StringValue(std::string val)
: Value(Kind::StringValue), val(std::move(val)) {}
explicit StringValue(std::string value)
: Value(Kind::StringValue), value_(std::move(value)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::StringValue;
}
auto Val() const -> const std::string& { return val; }
auto value() const -> const std::string& { return value_; }
private:
std::string val;
std::string value_;
};
auto CopyVal(Nonnull<Arena*> arena, Nonnull<const Value*> val,