Generic functions, first baby step (#658)

* generic functions: progress on parser and AST

* finished first baby step

* revisions based on reviews

* Update executable_semantics/interpreter/interpreter.cpp

Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>

* Symbol => VariableType

Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
This commit is contained in:
Jeremy G. Siek
2021-07-22 15:16:56 -04:00
committed by GitHub
co-authored by Jon Meow
parent cc56afb79e
commit 864b3bde02
27 changed files with 437 additions and 24 deletions
+35 -4
View File
@@ -64,6 +64,10 @@ auto Value::GetChoiceType() const -> const ChoiceType& {
return std::get<ChoiceType>(value);
}
auto Value::GetVariableType() const -> const VariableType& {
return std::get<VariableType>(value);
}
auto Value::GetContinuationValue() const -> const ContinuationValue& {
return std::get<ContinuationValue>(value);
}
@@ -207,10 +211,12 @@ auto Value::MakeAutoType() -> const Value* {
return v;
}
auto Value::MakeFunctionType(const Value* param, const Value* ret)
auto Value::MakeFunctionType(std::vector<GenericBinding> deduced_params,
const Value* param, const Value* ret)
-> const Value* {
auto* v = new Value();
v->value = FunctionType({.param = param, .ret = ret});
v->value = FunctionType(
{.deduced = std::move(deduced_params), .param = param, .ret = ret});
return v;
}
@@ -242,6 +248,12 @@ auto Value::MakeChoiceType(std::string name, VarValues alts) -> const Value* {
return v;
}
auto Value::MakeVariableType(std::string name) -> const Value* {
auto* v = new Value();
v->value = VariableType({.name = std::move(name)});
return v;
}
namespace {
auto GetMember(const Value* v, const std::string& f, int line_num)
@@ -405,8 +417,20 @@ void Value::Print(llvm::raw_ostream& out) const {
out << *GetPointerType().type << "*";
break;
case ValKind::FunctionType:
out << "fn " << *GetFunctionType().param << " -> "
<< *GetFunctionType().ret;
out << "fn ";
if (GetFunctionType().deduced.size() > 0) {
out << "[";
unsigned int i = 0;
for (const auto& deduced : GetFunctionType().deduced) {
if (i != 0) {
out << ", ";
}
out << deduced.name << ":! " << *deduced.type;
++i;
}
out << "]";
}
out << *GetFunctionType().param << " -> " << *GetFunctionType().ret;
break;
case ValKind::StructType:
out << "struct " << GetStructType().name;
@@ -414,6 +438,9 @@ void Value::Print(llvm::raw_ostream& out) const {
case ValKind::ChoiceType:
out << "choice " << GetChoiceType().name;
break;
case ValKind::VariableType:
out << GetVariableType().name;
break;
case ValKind::ContinuationValue:
out << "continuation";
// TODO: Find a way to print useful information about the continuation
@@ -457,6 +484,7 @@ auto CopyVal(const Value* val, int line_num) -> const Value* {
return val;
case ValKind::FunctionType:
return Value::MakeFunctionType(
val->GetFunctionType().deduced,
CopyVal(val->GetFunctionType().param, line_num),
CopyVal(val->GetFunctionType().ret, line_num));
@@ -473,6 +501,7 @@ auto CopyVal(const Value* val, int line_num) -> const Value* {
return Value::MakeAutoType();
case ValKind::ContinuationType:
return Value::MakeContinuationType();
case ValKind::VariableType:
case ValKind::StructType:
case ValKind::ChoiceType:
case ValKind::BindingPlaceholderValue:
@@ -519,6 +548,8 @@ auto TypeEqual(const Value* t1, const Value* t2) -> bool {
case ValKind::ContinuationType:
case ValKind::TypeType:
return true;
case ValKind::VariableType:
return t1->GetVariableType().name == t2->GetVariableType().name;
default:
llvm::errs() << "TypeEqual used to compare non-type values\n"
<< *t1 << "\n"