|
|
@@ -40,72 +40,75 @@ void PrintTypeEnv(TypeEnv types, llvm::raw_ostream& out) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void ExpectType(SourceLocation loc, const std::string& context,
|
|
|
+static void ExpectType(SourceLocation source_loc, const std::string& context,
|
|
|
Nonnull<const Value*> expected,
|
|
|
Nonnull<const Value*> actual) {
|
|
|
if (!TypeEqual(expected, actual)) {
|
|
|
- FATAL_COMPILATION_ERROR(loc) << "type error in " << context << "\n"
|
|
|
- << "expected: " << *expected << "\n"
|
|
|
- << "actual: " << *actual;
|
|
|
+ FATAL_COMPILATION_ERROR(source_loc) << "type error in " << context << "\n"
|
|
|
+ << "expected: " << *expected << "\n"
|
|
|
+ << "actual: " << *actual;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void ExpectPointerType(SourceLocation loc, const std::string& context,
|
|
|
+static void ExpectPointerType(SourceLocation source_loc,
|
|
|
+ const std::string& context,
|
|
|
Nonnull<const Value*> actual) {
|
|
|
- if (actual->Tag() != Value::Kind::PointerType) {
|
|
|
- FATAL_COMPILATION_ERROR(loc) << "type error in " << context << "\n"
|
|
|
- << "expected a pointer type\n"
|
|
|
- << "actual: " << *actual;
|
|
|
+ if (actual->kind() != Value::Kind::PointerType) {
|
|
|
+ FATAL_COMPILATION_ERROR(source_loc) << "type error in " << context << "\n"
|
|
|
+ << "expected a pointer type\n"
|
|
|
+ << "actual: " << *actual;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-auto TypeChecker::ReifyType(Nonnull<const Value*> t, SourceLocation loc)
|
|
|
+auto TypeChecker::ReifyType(Nonnull<const Value*> t, SourceLocation source_loc)
|
|
|
-> Nonnull<Expression*> {
|
|
|
- switch (t->Tag()) {
|
|
|
+ switch (t->kind()) {
|
|
|
case Value::Kind::IntType:
|
|
|
- return arena->New<IntTypeLiteral>(loc);
|
|
|
+ return arena->New<IntTypeLiteral>(source_loc);
|
|
|
case Value::Kind::BoolType:
|
|
|
- return arena->New<BoolTypeLiteral>(loc);
|
|
|
+ return arena->New<BoolTypeLiteral>(source_loc);
|
|
|
case Value::Kind::TypeType:
|
|
|
- return arena->New<TypeTypeLiteral>(loc);
|
|
|
+ return arena->New<TypeTypeLiteral>(source_loc);
|
|
|
case Value::Kind::ContinuationType:
|
|
|
- return arena->New<ContinuationTypeLiteral>(loc);
|
|
|
+ return arena->New<ContinuationTypeLiteral>(source_loc);
|
|
|
case Value::Kind::FunctionType: {
|
|
|
const auto& fn_type = cast<FunctionType>(*t);
|
|
|
return arena->New<FunctionTypeLiteral>(
|
|
|
- loc, ReifyType(fn_type.Param(), loc), ReifyType(fn_type.Ret(), loc),
|
|
|
+ source_loc, ReifyType(fn_type.Param(), source_loc),
|
|
|
+ ReifyType(fn_type.Ret(), source_loc),
|
|
|
/*is_omitted_return_type=*/false);
|
|
|
}
|
|
|
case Value::Kind::TupleValue: {
|
|
|
std::vector<FieldInitializer> args;
|
|
|
for (const TupleElement& field : cast<TupleValue>(*t).Elements()) {
|
|
|
args.push_back(
|
|
|
- FieldInitializer(field.name, ReifyType(field.value, loc)));
|
|
|
+ FieldInitializer(field.name, ReifyType(field.value, source_loc)));
|
|
|
}
|
|
|
- return arena->New<TupleLiteral>(loc, args);
|
|
|
+ return arena->New<TupleLiteral>(source_loc, args);
|
|
|
}
|
|
|
case Value::Kind::StructType: {
|
|
|
std::vector<FieldInitializer> args;
|
|
|
for (const auto& [name, type] : cast<StructType>(*t).fields()) {
|
|
|
- args.push_back(FieldInitializer(name, ReifyType(type, loc)));
|
|
|
+ args.push_back(FieldInitializer(name, ReifyType(type, source_loc)));
|
|
|
}
|
|
|
- return arena->New<StructTypeLiteral>(loc, args);
|
|
|
+ return arena->New<StructTypeLiteral>(source_loc, args);
|
|
|
}
|
|
|
case Value::Kind::NominalClassType:
|
|
|
return arena->New<IdentifierExpression>(
|
|
|
- loc, cast<NominalClassType>(*t).Name());
|
|
|
+ source_loc, cast<NominalClassType>(*t).Name());
|
|
|
case Value::Kind::ChoiceType:
|
|
|
- return arena->New<IdentifierExpression>(loc, cast<ChoiceType>(*t).Name());
|
|
|
+ return arena->New<IdentifierExpression>(source_loc,
|
|
|
+ cast<ChoiceType>(*t).Name());
|
|
|
case Value::Kind::PointerType:
|
|
|
return arena->New<PrimitiveOperatorExpression>(
|
|
|
- loc, Operator::Ptr,
|
|
|
+ source_loc, Operator::Ptr,
|
|
|
std::vector<Nonnull<Expression*>>(
|
|
|
- {ReifyType(cast<PointerType>(*t).Type(), loc)}));
|
|
|
+ {ReifyType(cast<PointerType>(*t).Type(), source_loc)}));
|
|
|
case Value::Kind::VariableType:
|
|
|
- return arena->New<IdentifierExpression>(loc,
|
|
|
+ return arena->New<IdentifierExpression>(source_loc,
|
|
|
cast<VariableType>(*t).Name());
|
|
|
case Value::Kind::StringType:
|
|
|
- return arena->New<StringTypeLiteral>(loc);
|
|
|
+ return arena->New<StringTypeLiteral>(source_loc);
|
|
|
case Value::Kind::AlternativeConstructorValue:
|
|
|
case Value::Kind::AlternativeValue:
|
|
|
case Value::Kind::AutoType:
|
|
|
@@ -128,78 +131,81 @@ auto TypeChecker::ReifyType(Nonnull<const Value*> t, SourceLocation loc)
|
|
|
// inside the argument type.
|
|
|
// The `deduced` parameter is an accumulator, that is, it holds the
|
|
|
// results so-far.
|
|
|
-static auto ArgumentDeduction(SourceLocation loc, TypeEnv deduced,
|
|
|
+static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
|
|
|
Nonnull<const Value*> param,
|
|
|
Nonnull<const Value*> arg) -> TypeEnv {
|
|
|
- switch (param->Tag()) {
|
|
|
+ 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());
|
|
|
if (!d) {
|
|
|
deduced.Set(var_type.Name(), arg);
|
|
|
} else {
|
|
|
- ExpectType(loc, "argument deduction", *d, arg);
|
|
|
+ ExpectType(source_loc, "argument deduction", *d, arg);
|
|
|
}
|
|
|
return deduced;
|
|
|
}
|
|
|
case Value::Kind::TupleValue: {
|
|
|
- if (arg->Tag() != Value::Kind::TupleValue) {
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ if (arg->kind() != Value::Kind::TupleValue) {
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
}
|
|
|
const auto& param_tup = cast<TupleValue>(*param);
|
|
|
const auto& arg_tup = cast<TupleValue>(*arg);
|
|
|
if (param_tup.Elements().size() != arg_tup.Elements().size()) {
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
}
|
|
|
for (size_t i = 0; i < param_tup.Elements().size(); ++i) {
|
|
|
if (param_tup.Elements()[i].name != arg_tup.Elements()[i].name) {
|
|
|
- FATAL_COMPILATION_ERROR(loc)
|
|
|
+ FATAL_COMPILATION_ERROR(source_loc)
|
|
|
<< "mismatch in tuple names, " << param_tup.Elements()[i].name
|
|
|
<< " != " << arg_tup.Elements()[i].name;
|
|
|
}
|
|
|
- deduced = ArgumentDeduction(loc, deduced, param_tup.Elements()[i].value,
|
|
|
+ deduced = ArgumentDeduction(source_loc, deduced,
|
|
|
+ param_tup.Elements()[i].value,
|
|
|
arg_tup.Elements()[i].value);
|
|
|
}
|
|
|
return deduced;
|
|
|
}
|
|
|
case Value::Kind::StructType: {
|
|
|
- if (arg->Tag() != Value::Kind::StructType) {
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ if (arg->kind() != Value::Kind::StructType) {
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
}
|
|
|
const auto& param_struct = cast<StructType>(*param);
|
|
|
const auto& arg_struct = cast<StructType>(*arg);
|
|
|
if (param_struct.fields().size() != arg_struct.fields().size()) {
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
}
|
|
|
for (size_t i = 0; i < param_struct.fields().size(); ++i) {
|
|
|
if (param_struct.fields()[i].first != arg_struct.fields()[i].first) {
|
|
|
- FATAL_COMPILATION_ERROR(loc)
|
|
|
+ FATAL_COMPILATION_ERROR(source_loc)
|
|
|
<< "mismatch in field names, " << param_struct.fields()[i].first
|
|
|
<< " != " << arg_struct.fields()[i].first;
|
|
|
}
|
|
|
- deduced =
|
|
|
- ArgumentDeduction(loc, deduced, param_struct.fields()[i].second,
|
|
|
- arg_struct.fields()[i].second);
|
|
|
+ deduced = ArgumentDeduction(source_loc, deduced,
|
|
|
+ param_struct.fields()[i].second,
|
|
|
+ arg_struct.fields()[i].second);
|
|
|
}
|
|
|
return deduced;
|
|
|
}
|
|
|
case Value::Kind::FunctionType: {
|
|
|
- if (arg->Tag() != Value::Kind::FunctionType) {
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ if (arg->kind() != Value::Kind::FunctionType) {
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
}
|
|
|
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(loc, deduced, param_fn.Param(), arg_fn.Param());
|
|
|
- deduced = ArgumentDeduction(loc, deduced, param_fn.Ret(), arg_fn.Ret());
|
|
|
+ ArgumentDeduction(source_loc, deduced, param_fn.Ret(), arg_fn.Ret());
|
|
|
return deduced;
|
|
|
}
|
|
|
case Value::Kind::PointerType: {
|
|
|
- if (arg->Tag() != Value::Kind::PointerType) {
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ if (arg->kind() != Value::Kind::PointerType) {
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
}
|
|
|
- return ArgumentDeduction(loc, deduced, cast<PointerType>(*param).Type(),
|
|
|
+ return ArgumentDeduction(source_loc, deduced,
|
|
|
+ cast<PointerType>(*param).Type(),
|
|
|
cast<PointerType>(*arg).Type());
|
|
|
}
|
|
|
// Nothing to do in the case for `auto`.
|
|
|
@@ -214,7 +220,7 @@ static auto ArgumentDeduction(SourceLocation loc, TypeEnv deduced,
|
|
|
case Value::Kind::BoolType:
|
|
|
case Value::Kind::TypeType:
|
|
|
case Value::Kind::StringType:
|
|
|
- ExpectType(loc, "argument deduction", param, arg);
|
|
|
+ ExpectType(source_loc, "argument deduction", param, arg);
|
|
|
return deduced;
|
|
|
// The rest of these cases should never happen.
|
|
|
case Value::Kind::IntValue:
|
|
|
@@ -234,7 +240,7 @@ static auto ArgumentDeduction(SourceLocation loc, TypeEnv deduced,
|
|
|
|
|
|
auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
|
|
|
-> Nonnull<const Value*> {
|
|
|
- switch (type->Tag()) {
|
|
|
+ switch (type->kind()) {
|
|
|
case Value::Kind::VariableType: {
|
|
|
std::optional<Nonnull<const Value*>> t =
|
|
|
dict.Get(cast<VariableType>(*type).Name());
|
|
|
@@ -305,12 +311,12 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
interpreter.PrintEnv(values, llvm::outs());
|
|
|
llvm::outs() << "\n";
|
|
|
}
|
|
|
- switch (e->Tag()) {
|
|
|
+ switch (e->kind()) {
|
|
|
case Expression::Kind::IndexExpression: {
|
|
|
auto& index = cast<IndexExpression>(*e);
|
|
|
auto res = TypeCheckExp(index.Aggregate(), types, values);
|
|
|
auto t = res.type;
|
|
|
- switch (t->Tag()) {
|
|
|
+ switch (t->kind()) {
|
|
|
case Value::Kind::TupleValue: {
|
|
|
auto i =
|
|
|
cast<IntValue>(*interpreter.InterpExp(values, index.Offset()))
|
|
|
@@ -319,16 +325,16 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
std::optional<Nonnull<const Value*>> field_t =
|
|
|
cast<TupleValue>(*t).FindField(f);
|
|
|
if (!field_t) {
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "field " << f << " is not in the tuple " << *t;
|
|
|
}
|
|
|
auto new_e = arena->New<IndexExpression>(
|
|
|
- e->SourceLoc(), res.exp,
|
|
|
- arena->New<IntLiteral>(e->SourceLoc(), i));
|
|
|
+ e->source_loc(), res.exp,
|
|
|
+ arena->New<IntLiteral>(e->source_loc(), i));
|
|
|
return TCExpression(new_e, *field_t, res.types);
|
|
|
}
|
|
|
default:
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc()) << "expected a tuple";
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc()) << "expected a tuple";
|
|
|
}
|
|
|
}
|
|
|
case Expression::Kind::TupleLiteral: {
|
|
|
@@ -341,7 +347,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
new_args.push_back(FieldInitializer(arg.name, arg_res.exp));
|
|
|
arg_types.push_back({.name = arg.name, .value = arg_res.type});
|
|
|
}
|
|
|
- auto tuple_e = arena->New<TupleLiteral>(e->SourceLoc(), new_args);
|
|
|
+ auto tuple_e = arena->New<TupleLiteral>(e->source_loc(), new_args);
|
|
|
auto tuple_t = arena->New<TupleValue>(std::move(arg_types));
|
|
|
return TCExpression(tuple_e, tuple_t, new_types);
|
|
|
}
|
|
|
@@ -355,7 +361,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
new_args.push_back(FieldInitializer(arg.name, arg_res.exp));
|
|
|
arg_types.push_back({arg.name, arg_res.type});
|
|
|
}
|
|
|
- auto new_e = arena->New<StructLiteral>(e->SourceLoc(), new_args);
|
|
|
+ auto new_e = arena->New<StructLiteral>(e->source_loc(), new_args);
|
|
|
auto type = arena->New<StructType>(std::move(arg_types));
|
|
|
return TCExpression(new_e, type, new_types);
|
|
|
}
|
|
|
@@ -368,9 +374,9 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
new_types = arg_res.types;
|
|
|
Nonnull<const Value*> type = interpreter.InterpExp(values, arg_res.exp);
|
|
|
new_args.push_back(
|
|
|
- FieldInitializer(arg.name, ReifyType(type, e->SourceLoc())));
|
|
|
+ FieldInitializer(arg.name, ReifyType(type, e->source_loc())));
|
|
|
}
|
|
|
- auto new_e = arena->New<StructTypeLiteral>(e->SourceLoc(), new_args);
|
|
|
+ auto new_e = arena->New<StructTypeLiteral>(e->source_loc(), new_args);
|
|
|
Nonnull<const Value*> type;
|
|
|
if (struct_type.fields().empty()) {
|
|
|
// `{}` is the type of `{}`, just as `()` is the type of `()`.
|
|
|
@@ -387,17 +393,17 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
auto& access = cast<FieldAccessExpression>(*e);
|
|
|
auto res = TypeCheckExp(access.Aggregate(), types, values);
|
|
|
auto t = res.type;
|
|
|
- switch (t->Tag()) {
|
|
|
+ switch (t->kind()) {
|
|
|
case Value::Kind::StructType: {
|
|
|
const auto& struct_type = cast<StructType>(*t);
|
|
|
for (const auto& [field_name, field_type] : struct_type.fields()) {
|
|
|
if (access.Field() == field_name) {
|
|
|
Nonnull<Expression*> new_e = arena->New<FieldAccessExpression>(
|
|
|
- access.SourceLoc(), res.exp, access.Field());
|
|
|
+ access.source_loc(), res.exp, access.Field());
|
|
|
return TCExpression(new_e, field_type, res.types);
|
|
|
}
|
|
|
}
|
|
|
- FATAL_COMPILATION_ERROR(access.SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(access.source_loc())
|
|
|
<< "struct " << struct_type << " does not have a field named "
|
|
|
<< access.Field();
|
|
|
}
|
|
|
@@ -407,7 +413,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
for (auto& field : t_class.Fields()) {
|
|
|
if (access.Field() == field.first) {
|
|
|
Nonnull<Expression*> new_e = arena->New<FieldAccessExpression>(
|
|
|
- e->SourceLoc(), res.exp, access.Field());
|
|
|
+ e->source_loc(), res.exp, access.Field());
|
|
|
return TCExpression(new_e, field.second, res.types);
|
|
|
}
|
|
|
}
|
|
|
@@ -415,11 +421,11 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
for (auto& method : t_class.Methods()) {
|
|
|
if (access.Field() == method.first) {
|
|
|
Nonnull<Expression*> new_e = arena->New<FieldAccessExpression>(
|
|
|
- e->SourceLoc(), res.exp, access.Field());
|
|
|
+ e->source_loc(), res.exp, access.Field());
|
|
|
return TCExpression(new_e, method.second, res.types);
|
|
|
}
|
|
|
}
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "class " << t_class.Name() << " does not have a field named "
|
|
|
<< access.Field();
|
|
|
}
|
|
|
@@ -428,11 +434,11 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
for (const TupleElement& field : tup.Elements()) {
|
|
|
if (access.Field() == field.name) {
|
|
|
auto new_e = arena->New<FieldAccessExpression>(
|
|
|
- e->SourceLoc(), res.exp, access.Field());
|
|
|
+ e->source_loc(), res.exp, access.Field());
|
|
|
return TCExpression(new_e, field.value, res.types);
|
|
|
}
|
|
|
}
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "tuple " << tup << " does not have a field named "
|
|
|
<< access.Field();
|
|
|
}
|
|
|
@@ -441,18 +447,18 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
for (const auto& vt : choice.Alternatives()) {
|
|
|
if (access.Field() == vt.first) {
|
|
|
Nonnull<Expression*> new_e = arena->New<FieldAccessExpression>(
|
|
|
- e->SourceLoc(), res.exp, access.Field());
|
|
|
+ e->source_loc(), res.exp, access.Field());
|
|
|
auto fun_ty = arena->New<FunctionType>(
|
|
|
std::vector<GenericBinding>(), vt.second, t);
|
|
|
return TCExpression(new_e, fun_ty, res.types);
|
|
|
}
|
|
|
}
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "choice " << choice.Name() << " does not have a field named "
|
|
|
<< access.Field();
|
|
|
}
|
|
|
default:
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "field access, expected a struct\n"
|
|
|
<< *e;
|
|
|
}
|
|
|
@@ -463,7 +469,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
if (type) {
|
|
|
return TCExpression(e, *type, types);
|
|
|
} else {
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "could not find `" << ident.Name() << "`";
|
|
|
}
|
|
|
}
|
|
|
@@ -483,49 +489,49 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
ts.push_back(res.type);
|
|
|
}
|
|
|
auto new_e =
|
|
|
- arena->New<PrimitiveOperatorExpression>(e->SourceLoc(), op.Op(), es);
|
|
|
+ arena->New<PrimitiveOperatorExpression>(e->source_loc(), op.Op(), es);
|
|
|
switch (op.Op()) {
|
|
|
case Operator::Neg:
|
|
|
- ExpectType(e->SourceLoc(), "negation", arena->New<IntType>(), ts[0]);
|
|
|
+ ExpectType(e->source_loc(), "negation", arena->New<IntType>(), ts[0]);
|
|
|
return TCExpression(new_e, arena->New<IntType>(), new_types);
|
|
|
case Operator::Add:
|
|
|
- ExpectType(e->SourceLoc(), "addition(1)", arena->New<IntType>(),
|
|
|
+ ExpectType(e->source_loc(), "addition(1)", arena->New<IntType>(),
|
|
|
ts[0]);
|
|
|
- ExpectType(e->SourceLoc(), "addition(2)", arena->New<IntType>(),
|
|
|
+ ExpectType(e->source_loc(), "addition(2)", arena->New<IntType>(),
|
|
|
ts[1]);
|
|
|
return TCExpression(new_e, arena->New<IntType>(), new_types);
|
|
|
case Operator::Sub:
|
|
|
- ExpectType(e->SourceLoc(), "subtraction(1)", arena->New<IntType>(),
|
|
|
+ ExpectType(e->source_loc(), "subtraction(1)", arena->New<IntType>(),
|
|
|
ts[0]);
|
|
|
- ExpectType(e->SourceLoc(), "subtraction(2)", arena->New<IntType>(),
|
|
|
+ ExpectType(e->source_loc(), "subtraction(2)", arena->New<IntType>(),
|
|
|
ts[1]);
|
|
|
return TCExpression(new_e, arena->New<IntType>(), new_types);
|
|
|
case Operator::Mul:
|
|
|
- ExpectType(e->SourceLoc(), "multiplication(1)", arena->New<IntType>(),
|
|
|
- ts[0]);
|
|
|
- ExpectType(e->SourceLoc(), "multiplication(2)", arena->New<IntType>(),
|
|
|
- ts[1]);
|
|
|
+ ExpectType(e->source_loc(), "multiplication(1)",
|
|
|
+ arena->New<IntType>(), ts[0]);
|
|
|
+ ExpectType(e->source_loc(), "multiplication(2)",
|
|
|
+ arena->New<IntType>(), ts[1]);
|
|
|
return TCExpression(new_e, arena->New<IntType>(), new_types);
|
|
|
case Operator::And:
|
|
|
- ExpectType(e->SourceLoc(), "&&(1)", arena->New<BoolType>(), ts[0]);
|
|
|
- ExpectType(e->SourceLoc(), "&&(2)", arena->New<BoolType>(), ts[1]);
|
|
|
+ ExpectType(e->source_loc(), "&&(1)", arena->New<BoolType>(), ts[0]);
|
|
|
+ ExpectType(e->source_loc(), "&&(2)", arena->New<BoolType>(), ts[1]);
|
|
|
return TCExpression(new_e, arena->New<BoolType>(), new_types);
|
|
|
case Operator::Or:
|
|
|
- ExpectType(e->SourceLoc(), "||(1)", arena->New<BoolType>(), ts[0]);
|
|
|
- ExpectType(e->SourceLoc(), "||(2)", arena->New<BoolType>(), ts[1]);
|
|
|
+ ExpectType(e->source_loc(), "||(1)", arena->New<BoolType>(), ts[0]);
|
|
|
+ ExpectType(e->source_loc(), "||(2)", arena->New<BoolType>(), ts[1]);
|
|
|
return TCExpression(new_e, arena->New<BoolType>(), new_types);
|
|
|
case Operator::Not:
|
|
|
- ExpectType(e->SourceLoc(), "!", arena->New<BoolType>(), ts[0]);
|
|
|
+ ExpectType(e->source_loc(), "!", arena->New<BoolType>(), ts[0]);
|
|
|
return TCExpression(new_e, arena->New<BoolType>(), new_types);
|
|
|
case Operator::Eq:
|
|
|
- ExpectType(e->SourceLoc(), "==", ts[0], ts[1]);
|
|
|
+ ExpectType(e->source_loc(), "==", ts[0], ts[1]);
|
|
|
return TCExpression(new_e, arena->New<BoolType>(), new_types);
|
|
|
case Operator::Deref:
|
|
|
- ExpectPointerType(e->SourceLoc(), "*", ts[0]);
|
|
|
+ ExpectPointerType(e->source_loc(), "*", ts[0]);
|
|
|
return TCExpression(new_e, cast<PointerType>(*ts[0]).Type(),
|
|
|
new_types);
|
|
|
case Operator::Ptr:
|
|
|
- ExpectType(e->SourceLoc(), "*", arena->New<TypeType>(), ts[0]);
|
|
|
+ ExpectType(e->source_loc(), "*", arena->New<TypeType>(), ts[0]);
|
|
|
return TCExpression(new_e, arena->New<TypeType>(), new_types);
|
|
|
}
|
|
|
break;
|
|
|
@@ -533,7 +539,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
case Expression::Kind::CallExpression: {
|
|
|
auto& call = cast<CallExpression>(*e);
|
|
|
auto fun_res = TypeCheckExp(call.Function(), types, values);
|
|
|
- switch (fun_res.type->Tag()) {
|
|
|
+ switch (fun_res.type->kind()) {
|
|
|
case Value::Kind::FunctionType: {
|
|
|
const auto& fun_t = cast<FunctionType>(*fun_res.type);
|
|
|
auto arg_res = TypeCheckExp(call.Argument(), fun_res.types, values);
|
|
|
@@ -541,12 +547,12 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
auto return_type = fun_t.Ret();
|
|
|
if (!fun_t.Deduced().empty()) {
|
|
|
auto deduced_args = ArgumentDeduction(
|
|
|
- e->SourceLoc(), TypeEnv(arena), parameter_type, arg_res.type);
|
|
|
+ e->source_loc(), TypeEnv(arena), parameter_type, arg_res.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)) {
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "could not deduce type argument for type parameter "
|
|
|
<< deduced_param.name;
|
|
|
}
|
|
|
@@ -554,14 +560,14 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
parameter_type = Substitute(deduced_args, parameter_type);
|
|
|
return_type = Substitute(deduced_args, return_type);
|
|
|
} else {
|
|
|
- ExpectType(e->SourceLoc(), "call", parameter_type, arg_res.type);
|
|
|
+ ExpectType(e->source_loc(), "call", parameter_type, arg_res.type);
|
|
|
}
|
|
|
- auto new_e = arena->New<CallExpression>(e->SourceLoc(), fun_res.exp,
|
|
|
+ auto new_e = arena->New<CallExpression>(e->source_loc(), fun_res.exp,
|
|
|
arg_res.exp);
|
|
|
return TCExpression(new_e, return_type, arg_res.types);
|
|
|
}
|
|
|
default: {
|
|
|
- FATAL_COMPILATION_ERROR(e->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(e->source_loc())
|
|
|
<< "in call, expected a function\n"
|
|
|
<< *e;
|
|
|
}
|
|
|
@@ -573,8 +579,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
|
|
auto pt = interpreter.InterpExp(values, fn.Parameter());
|
|
|
auto rt = interpreter.InterpExp(values, fn.ReturnType());
|
|
|
auto new_e = arena->New<FunctionTypeLiteral>(
|
|
|
- e->SourceLoc(), ReifyType(pt, e->SourceLoc()),
|
|
|
- ReifyType(rt, e->SourceLoc()),
|
|
|
+ e->source_loc(), ReifyType(pt, e->source_loc()),
|
|
|
+ ReifyType(rt, e->source_loc()),
|
|
|
/*is_omitted_return_type=*/false);
|
|
|
return TCExpression(new_e, arena->New<TypeType>(), types);
|
|
|
}
|
|
|
@@ -608,7 +614,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
interpreter.PrintEnv(values, llvm::outs());
|
|
|
llvm::outs() << "\n";
|
|
|
}
|
|
|
- switch (p->Tag()) {
|
|
|
+ switch (p->kind()) {
|
|
|
case Pattern::Kind::AutoPattern: {
|
|
|
return {.pattern = p, .type = arena->New<TypeType>(), .types = types};
|
|
|
}
|
|
|
@@ -620,9 +626,9 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
interpreter.InterpPattern(values, binding_type_result.pattern);
|
|
|
if (expected) {
|
|
|
std::optional<Env> values = interpreter.PatternMatch(
|
|
|
- type, *expected, binding.Type()->SourceLoc());
|
|
|
+ type, *expected, binding.Type()->source_loc());
|
|
|
if (values == std::nullopt) {
|
|
|
- FATAL_COMPILATION_ERROR(binding.Type()->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(binding.Type()->source_loc())
|
|
|
<< "Type pattern '" << *type << "' does not match actual type '"
|
|
|
<< **expected << "'";
|
|
|
}
|
|
|
@@ -631,8 +637,8 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
type = *expected;
|
|
|
}
|
|
|
auto new_p = arena->New<BindingPattern>(
|
|
|
- binding.SourceLoc(), binding.Name(),
|
|
|
- arena->New<ExpressionPattern>(ReifyType(type, binding.SourceLoc())));
|
|
|
+ binding.source_loc(), binding.Name(),
|
|
|
+ arena->New<ExpressionPattern>(ReifyType(type, binding.source_loc())));
|
|
|
if (binding.Name().has_value()) {
|
|
|
types.Set(*binding.Name(), type);
|
|
|
}
|
|
|
@@ -643,12 +649,12 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
std::vector<TuplePattern::Field> new_fields;
|
|
|
std::vector<TupleElement> field_types;
|
|
|
auto new_types = types;
|
|
|
- if (expected && (*expected)->Tag() != Value::Kind::TupleValue) {
|
|
|
- FATAL_COMPILATION_ERROR(p->SourceLoc()) << "didn't expect a tuple";
|
|
|
+ if (expected && (*expected)->kind() != Value::Kind::TupleValue) {
|
|
|
+ FATAL_COMPILATION_ERROR(p->source_loc()) << "didn't expect a tuple";
|
|
|
}
|
|
|
if (expected && tuple.Fields().size() !=
|
|
|
cast<TupleValue>(**expected).Elements().size()) {
|
|
|
- FATAL_COMPILATION_ERROR(tuple.SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(tuple.source_loc())
|
|
|
<< "tuples of different length";
|
|
|
}
|
|
|
for (size_t i = 0; i < tuple.Fields().size(); ++i) {
|
|
|
@@ -658,7 +664,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
const TupleElement& expected_element =
|
|
|
cast<TupleValue>(**expected).Elements()[i];
|
|
|
if (expected_element.name != field.name) {
|
|
|
- FATAL_COMPILATION_ERROR(tuple.SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(tuple.source_loc())
|
|
|
<< "field names do not match, expected "
|
|
|
<< expected_element.name << " but got " << field.name;
|
|
|
}
|
|
|
@@ -671,7 +677,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
TuplePattern::Field(field.name, field_result.pattern));
|
|
|
field_types.push_back({.name = field.name, .value = field_result.type});
|
|
|
}
|
|
|
- auto new_tuple = arena->New<TuplePattern>(tuple.SourceLoc(), new_fields);
|
|
|
+ auto new_tuple = arena->New<TuplePattern>(tuple.source_loc(), new_fields);
|
|
|
auto tuple_t = arena->New<TupleValue>(std::move(field_types));
|
|
|
return {.pattern = new_tuple, .type = tuple_t, .types = new_types};
|
|
|
}
|
|
|
@@ -679,19 +685,19 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
auto& alternative = cast<AlternativePattern>(*p);
|
|
|
Nonnull<const Value*> choice_type =
|
|
|
interpreter.InterpExp(values, alternative.ChoiceType());
|
|
|
- if (choice_type->Tag() != Value::Kind::ChoiceType) {
|
|
|
- FATAL_COMPILATION_ERROR(alternative.SourceLoc())
|
|
|
+ if (choice_type->kind() != Value::Kind::ChoiceType) {
|
|
|
+ FATAL_COMPILATION_ERROR(alternative.source_loc())
|
|
|
<< "alternative pattern does not name a choice type.";
|
|
|
}
|
|
|
if (expected) {
|
|
|
- ExpectType(alternative.SourceLoc(), "alternative pattern", *expected,
|
|
|
+ ExpectType(alternative.source_loc(), "alternative pattern", *expected,
|
|
|
choice_type);
|
|
|
}
|
|
|
std::optional<Nonnull<const Value*>> parameter_types =
|
|
|
FindInVarValues(alternative.AlternativeName(),
|
|
|
cast<ChoiceType>(*choice_type).Alternatives());
|
|
|
if (parameter_types == std::nullopt) {
|
|
|
- FATAL_COMPILATION_ERROR(alternative.SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(alternative.source_loc())
|
|
|
<< "'" << alternative.AlternativeName()
|
|
|
<< "' is not an alternative of " << *choice_type;
|
|
|
}
|
|
|
@@ -702,8 +708,8 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
auto arguments =
|
|
|
Nonnull<TuplePattern*>(cast<const TuplePattern>(arg_results.pattern));
|
|
|
return {.pattern = arena->New<AlternativePattern>(
|
|
|
- alternative.SourceLoc(),
|
|
|
- ReifyType(choice_type, alternative.SourceLoc()),
|
|
|
+ alternative.source_loc(),
|
|
|
+ ReifyType(choice_type, alternative.source_loc()),
|
|
|
alternative.AlternativeName(), arguments),
|
|
|
.type = choice_type,
|
|
|
.types = arg_results.types};
|
|
|
@@ -732,7 +738,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
Env values,
|
|
|
Nonnull<ReturnTypeContext*> return_type_context)
|
|
|
-> TCStatement {
|
|
|
- switch (s->Tag()) {
|
|
|
+ switch (s->kind()) {
|
|
|
case Statement::Kind::Match: {
|
|
|
auto& match = cast<Match>(*s);
|
|
|
auto res = TypeCheckExp(&match.expression(), types, values);
|
|
|
@@ -743,18 +749,18 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
&clause.statement(), types, values,
|
|
|
return_type_context));
|
|
|
}
|
|
|
- auto new_s = arena->New<Match>(s->SourceLoc(), res.exp, new_clauses);
|
|
|
+ auto new_s = arena->New<Match>(s->source_loc(), res.exp, new_clauses);
|
|
|
return TCStatement(new_s, types);
|
|
|
}
|
|
|
case Statement::Kind::While: {
|
|
|
auto& while_stmt = cast<While>(*s);
|
|
|
auto cnd_res = TypeCheckExp(while_stmt.Cond(), types, values);
|
|
|
- ExpectType(s->SourceLoc(), "condition of `while`", arena->New<BoolType>(),
|
|
|
- cnd_res.type);
|
|
|
+ ExpectType(s->source_loc(), "condition of `while`",
|
|
|
+ arena->New<BoolType>(), cnd_res.type);
|
|
|
auto body_res =
|
|
|
TypeCheckStmt(while_stmt.Body(), types, values, return_type_context);
|
|
|
auto new_s =
|
|
|
- arena->New<While>(s->SourceLoc(), cnd_res.exp, body_res.stmt);
|
|
|
+ arena->New<While>(s->source_loc(), cnd_res.exp, body_res.stmt);
|
|
|
return TCStatement(new_s, types);
|
|
|
}
|
|
|
case Statement::Kind::Break:
|
|
|
@@ -765,7 +771,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
if (block.Stmt()) {
|
|
|
auto stmt_res =
|
|
|
TypeCheckStmt(*block.Stmt(), types, values, return_type_context);
|
|
|
- return TCStatement(arena->New<Block>(s->SourceLoc(), stmt_res.stmt),
|
|
|
+ return TCStatement(arena->New<Block>(s->source_loc(), stmt_res.stmt),
|
|
|
types);
|
|
|
} else {
|
|
|
return TCStatement(s, types);
|
|
|
@@ -777,7 +783,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
Nonnull<const Value*> rhs_ty = res.type;
|
|
|
auto lhs_res = TypeCheckPattern(var.Pat(), types, values, rhs_ty);
|
|
|
auto new_s =
|
|
|
- arena->New<VariableDefinition>(s->SourceLoc(), var.Pat(), res.exp);
|
|
|
+ arena->New<VariableDefinition>(s->source_loc(), var.Pat(), res.exp);
|
|
|
return TCStatement(new_s, lhs_res.types);
|
|
|
}
|
|
|
case Statement::Kind::Sequence: {
|
|
|
@@ -793,7 +799,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
checked_types = next_res.types;
|
|
|
}
|
|
|
return TCStatement(
|
|
|
- arena->New<Sequence>(s->SourceLoc(), stmt_res.stmt, next_stmt),
|
|
|
+ arena->New<Sequence>(s->source_loc(), stmt_res.stmt, next_stmt),
|
|
|
checked_types);
|
|
|
}
|
|
|
case Statement::Kind::Assign: {
|
|
|
@@ -802,20 +808,21 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
auto rhs_t = rhs_res.type;
|
|
|
auto lhs_res = TypeCheckExp(assign.Lhs(), types, values);
|
|
|
auto lhs_t = lhs_res.type;
|
|
|
- ExpectType(s->SourceLoc(), "assign", lhs_t, rhs_t);
|
|
|
- auto new_s = arena->New<Assign>(s->SourceLoc(), lhs_res.exp, rhs_res.exp);
|
|
|
+ ExpectType(s->source_loc(), "assign", lhs_t, rhs_t);
|
|
|
+ auto new_s =
|
|
|
+ arena->New<Assign>(s->source_loc(), lhs_res.exp, rhs_res.exp);
|
|
|
return TCStatement(new_s, lhs_res.types);
|
|
|
}
|
|
|
case Statement::Kind::ExpressionStatement: {
|
|
|
auto res =
|
|
|
TypeCheckExp(cast<ExpressionStatement>(*s).Exp(), types, values);
|
|
|
- auto new_s = arena->New<ExpressionStatement>(s->SourceLoc(), res.exp);
|
|
|
+ auto new_s = arena->New<ExpressionStatement>(s->source_loc(), res.exp);
|
|
|
return TCStatement(new_s, types);
|
|
|
}
|
|
|
case Statement::Kind::If: {
|
|
|
auto& if_stmt = cast<If>(*s);
|
|
|
auto cnd_res = TypeCheckExp(if_stmt.Cond(), types, values);
|
|
|
- ExpectType(s->SourceLoc(), "condition of `if`", arena->New<BoolType>(),
|
|
|
+ ExpectType(s->source_loc(), "condition of `if`", arena->New<BoolType>(),
|
|
|
cnd_res.type);
|
|
|
auto then_res =
|
|
|
TypeCheckStmt(if_stmt.ThenStmt(), types, values, return_type_context);
|
|
|
@@ -825,8 +832,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
return_type_context);
|
|
|
else_stmt = else_res.stmt;
|
|
|
}
|
|
|
- auto new_s =
|
|
|
- arena->New<If>(s->SourceLoc(), cnd_res.exp, then_res.stmt, else_stmt);
|
|
|
+ auto new_s = arena->New<If>(s->source_loc(), cnd_res.exp, then_res.stmt,
|
|
|
+ else_stmt);
|
|
|
return TCStatement(new_s, types);
|
|
|
}
|
|
|
case Statement::Kind::Return: {
|
|
|
@@ -835,7 +842,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
if (return_type_context->is_auto()) {
|
|
|
if (return_type_context->deduced_return_type()) {
|
|
|
// Only one return is allowed when the return type is `auto`.
|
|
|
- FATAL_COMPILATION_ERROR(s->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(s->source_loc())
|
|
|
<< "Only one return is allowed in a function with an `auto` "
|
|
|
"return type.";
|
|
|
} else {
|
|
|
@@ -843,17 +850,17 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
return_type_context->set_deduced_return_type(res.type);
|
|
|
}
|
|
|
} else {
|
|
|
- ExpectType(s->SourceLoc(), "return",
|
|
|
+ ExpectType(s->source_loc(), "return",
|
|
|
*return_type_context->deduced_return_type(), res.type);
|
|
|
}
|
|
|
if (ret.IsOmittedExp() != return_type_context->is_omitted()) {
|
|
|
- FATAL_COMPILATION_ERROR(s->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(s->source_loc())
|
|
|
<< *s << " should"
|
|
|
<< (return_type_context->is_omitted() ? " not" : "")
|
|
|
<< " provide a return value, to match the function's signature.";
|
|
|
}
|
|
|
return TCStatement(
|
|
|
- arena->New<Return>(s->SourceLoc(), res.exp, ret.IsOmittedExp()),
|
|
|
+ arena->New<Return>(s->source_loc(), res.exp, ret.IsOmittedExp()),
|
|
|
types);
|
|
|
}
|
|
|
case Statement::Kind::Continuation: {
|
|
|
@@ -861,16 +868,16 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
TCStatement body_result =
|
|
|
TypeCheckStmt(cont.Body(), types, values, return_type_context);
|
|
|
auto new_continuation = arena->New<Continuation>(
|
|
|
- s->SourceLoc(), cont.ContinuationVariable(), body_result.stmt);
|
|
|
+ s->source_loc(), cont.ContinuationVariable(), body_result.stmt);
|
|
|
types.Set(cont.ContinuationVariable(), arena->New<ContinuationType>());
|
|
|
return TCStatement(new_continuation, types);
|
|
|
}
|
|
|
case Statement::Kind::Run: {
|
|
|
TCExpression argument_result =
|
|
|
TypeCheckExp(cast<Run>(*s).Argument(), types, values);
|
|
|
- ExpectType(s->SourceLoc(), "argument of `run`",
|
|
|
+ ExpectType(s->source_loc(), "argument of `run`",
|
|
|
arena->New<ContinuationType>(), argument_result.type);
|
|
|
- auto new_run = arena->New<Run>(s->SourceLoc(), argument_result.exp);
|
|
|
+ auto new_run = arena->New<Run>(s->source_loc(), argument_result.exp);
|
|
|
return TCStatement(new_run, types);
|
|
|
}
|
|
|
case Statement::Kind::Await: {
|
|
|
@@ -882,42 +889,42 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
|
|
|
|
|
auto TypeChecker::CheckOrEnsureReturn(
|
|
|
std::optional<Nonnull<Statement*>> opt_stmt, bool omitted_ret_type,
|
|
|
- SourceLocation loc) -> Nonnull<Statement*> {
|
|
|
+ SourceLocation source_loc) -> Nonnull<Statement*> {
|
|
|
if (!opt_stmt) {
|
|
|
if (omitted_ret_type) {
|
|
|
- return arena->New<Return>(arena, loc);
|
|
|
+ return arena->New<Return>(arena, source_loc);
|
|
|
} else {
|
|
|
- FATAL_COMPILATION_ERROR(loc)
|
|
|
+ FATAL_COMPILATION_ERROR(source_loc)
|
|
|
<< "control-flow reaches end of function that provides a `->` return "
|
|
|
"type without reaching a return statement";
|
|
|
}
|
|
|
}
|
|
|
Nonnull<Statement*> stmt = *opt_stmt;
|
|
|
- switch (stmt->Tag()) {
|
|
|
+ switch (stmt->kind()) {
|
|
|
case Statement::Kind::Match: {
|
|
|
auto& match = cast<Match>(*stmt);
|
|
|
std::vector<Match::Clause> new_clauses;
|
|
|
for (auto& clause : match.clauses()) {
|
|
|
auto s = CheckOrEnsureReturn(&clause.statement(), omitted_ret_type,
|
|
|
- stmt->SourceLoc());
|
|
|
+ stmt->source_loc());
|
|
|
new_clauses.push_back(Match::Clause(&clause.pattern(), s));
|
|
|
}
|
|
|
- return arena->New<Match>(stmt->SourceLoc(), &match.expression(),
|
|
|
+ return arena->New<Match>(stmt->source_loc(), &match.expression(),
|
|
|
new_clauses);
|
|
|
}
|
|
|
case Statement::Kind::Block:
|
|
|
return arena->New<Block>(
|
|
|
- stmt->SourceLoc(),
|
|
|
+ stmt->source_loc(),
|
|
|
CheckOrEnsureReturn(cast<Block>(*stmt).Stmt(), omitted_ret_type,
|
|
|
- stmt->SourceLoc()));
|
|
|
+ stmt->source_loc()));
|
|
|
case Statement::Kind::If: {
|
|
|
auto& if_stmt = cast<If>(*stmt);
|
|
|
return arena->New<If>(
|
|
|
- stmt->SourceLoc(), if_stmt.Cond(),
|
|
|
+ stmt->source_loc(), if_stmt.Cond(),
|
|
|
CheckOrEnsureReturn(if_stmt.ThenStmt(), omitted_ret_type,
|
|
|
- stmt->SourceLoc()),
|
|
|
+ stmt->source_loc()),
|
|
|
CheckOrEnsureReturn(if_stmt.ElseStmt(), omitted_ret_type,
|
|
|
- stmt->SourceLoc()));
|
|
|
+ stmt->source_loc()));
|
|
|
}
|
|
|
case Statement::Kind::Return:
|
|
|
return stmt;
|
|
|
@@ -925,12 +932,12 @@ auto TypeChecker::CheckOrEnsureReturn(
|
|
|
auto& seq = cast<Sequence>(*stmt);
|
|
|
if (seq.Next()) {
|
|
|
return arena->New<Sequence>(
|
|
|
- stmt->SourceLoc(), seq.Stmt(),
|
|
|
+ stmt->source_loc(), seq.Stmt(),
|
|
|
CheckOrEnsureReturn(seq.Next(), omitted_ret_type,
|
|
|
- stmt->SourceLoc()));
|
|
|
+ stmt->source_loc()));
|
|
|
} else {
|
|
|
return CheckOrEnsureReturn(seq.Stmt(), omitted_ret_type,
|
|
|
- stmt->SourceLoc());
|
|
|
+ stmt->source_loc());
|
|
|
}
|
|
|
}
|
|
|
case Statement::Kind::Continuation:
|
|
|
@@ -944,10 +951,10 @@ auto TypeChecker::CheckOrEnsureReturn(
|
|
|
case Statement::Kind::Continue:
|
|
|
case Statement::Kind::VariableDefinition:
|
|
|
if (omitted_ret_type) {
|
|
|
- return arena->New<Sequence>(stmt->SourceLoc(), stmt,
|
|
|
- arena->New<Return>(arena, loc));
|
|
|
+ return arena->New<Sequence>(stmt->source_loc(), stmt,
|
|
|
+ arena->New<Return>(arena, source_loc));
|
|
|
} else {
|
|
|
- FATAL_COMPILATION_ERROR(stmt->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(stmt->source_loc())
|
|
|
<< "control-flow reaches end of function that provides a `->` "
|
|
|
"return type without reaching a return statement";
|
|
|
}
|
|
|
@@ -1010,7 +1017,7 @@ auto TypeChecker::TypeOfFunDef(TypeEnv types, Env values,
|
|
|
TypeCheckPattern(&fun_def->param_pattern(), types, values, std::nullopt);
|
|
|
// Evaluate the return type expression
|
|
|
auto ret = interpreter.InterpPattern(values, &fun_def->return_type());
|
|
|
- if (ret->Tag() == Value::Kind::AutoType) {
|
|
|
+ if (ret->kind() == Value::Kind::AutoType) {
|
|
|
auto f = TypeCheckFunDef(fun_def, types, values);
|
|
|
ret = interpreter.InterpPattern(values, &f->return_type());
|
|
|
}
|
|
|
@@ -1023,17 +1030,17 @@ auto TypeChecker::TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/,
|
|
|
VarValues fields;
|
|
|
VarValues methods;
|
|
|
for (Nonnull<const Member*> m : sd->members()) {
|
|
|
- switch (m->Tag()) {
|
|
|
+ switch (m->kind()) {
|
|
|
case Member::Kind::FieldMember: {
|
|
|
Nonnull<const BindingPattern*> binding =
|
|
|
cast<FieldMember>(*m).Binding();
|
|
|
if (!binding->Name().has_value()) {
|
|
|
- FATAL_COMPILATION_ERROR(binding->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(binding->source_loc())
|
|
|
<< "Struct members must have names";
|
|
|
}
|
|
|
const auto* binding_type = dyn_cast<ExpressionPattern>(binding->Type());
|
|
|
if (binding_type == nullptr) {
|
|
|
- FATAL_COMPILATION_ERROR(binding->SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(binding->source_loc())
|
|
|
<< "Struct members must have explicit types";
|
|
|
}
|
|
|
auto type = interpreter.InterpExp(ct_top, binding_type->Expression());
|
|
|
@@ -1057,7 +1064,7 @@ static auto GetName(const Declaration& d) -> const std::string& {
|
|
|
case Declaration::Kind::VariableDeclaration: {
|
|
|
const BindingPattern& binding = cast<VariableDeclaration>(d).binding();
|
|
|
if (!binding.Name().has_value()) {
|
|
|
- FATAL_COMPILATION_ERROR(binding.SourceLoc())
|
|
|
+ FATAL_COMPILATION_ERROR(binding.source_loc())
|
|
|
<< "Top-level variable declarations must have names";
|
|
|
}
|
|
|
return *binding.Name();
|
|
|
@@ -1077,7 +1084,7 @@ auto TypeChecker::MakeTypeChecked(Nonnull<Declaration*> d, const TypeEnv& types,
|
|
|
cast<ClassDeclaration>(*d).definition();
|
|
|
std::vector<Nonnull<Member*>> fields;
|
|
|
for (Nonnull<Member*> m : class_def.members()) {
|
|
|
- switch (m->Tag()) {
|
|
|
+ switch (m->kind()) {
|
|
|
case Member::Kind::FieldMember:
|
|
|
// TODO: Interpret the type expression and store the result.
|
|
|
fields.push_back(m);
|