mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Refactor Value accessors (#892)
This commit is contained in:
@@ -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, ¶m_fn.parameters(),
|
||||
&arg_fn.parameters());
|
||||
deduced = ArgumentDeduction(source_loc, deduced, ¶m_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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user