Skip to content

Commit

Permalink
Enable builtin.foreign to accept pointers or functions at type-checki…
Browse files Browse the repository at this point in the history
…ng time (implementation of foreign not yet done).
  • Loading branch information
asoffer committed Dec 23, 2023
1 parent a7cefab commit b306c5d
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 61 deletions.
5 changes: 3 additions & 2 deletions common/language/primitive_types.xmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@

#if not defined(IC_XMACRO_PRIMITIVE_TYPE_END_CATEGORY)
#define IC_XMACRO_PRIMITIVE_TYPE_END_CATEGORY(category)
#endif

#endif

IC_XMACRO_PRIMITIVE_TYPE(Bottom, Bottom, "bottom")
IC_XMACRO_PRIMITIVE_TYPE(Unit, Unit, "unit")
IC_XMACRO_PRIMITIVE_TYPE(Error, Error, "error")
IC_XMACRO_PRIMITIVE_TYPE(Bool, Bool, "bool")
IC_XMACRO_PRIMITIVE_TYPE(NullType, NullType, "nulltype")
Expand Down
32 changes: 24 additions & 8 deletions ir/builtin_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@

namespace ic {
namespace {
nth::NoDestructor<IrFunction> Function([] {

nth::NoDestructor<IrFunction> FunctionOrPointer([] {
IrFunction f(1, 1);
f.append<TypeKind>();
f.append<jasmin::Duplicate>();
f.append<jasmin::Push>(type::Type::Kind::Function);
f.append<jasmin::Equal<type::Type::Kind>>();
f.append<jasmin::JumpIf>(10);
f.append<jasmin::Push>(type::Type::Kind::Pointer);
f.append<jasmin::Equal<type::Type::Kind>>();
f.append<jasmin::JumpIf>(6);
f.append<PushType>(type::Bottom);
f.append<jasmin::Return>();
f.append<jasmin::Drop>();
f.append<PushType>(type::Unit);
f.append<jasmin::Return>();
return f;
}());
Expand Down Expand Up @@ -114,14 +124,20 @@ Module BuiltinModule() {

Register(
"foreign",
type::Dependent(type::DependentTerm::Function(
type::DependentTerm::Value(
TypeErasedValue(type::Type_, {type::Type_})),
type::DependentTerm::DeBruijnIndex(0)),
type::DependentParameterMapping(
{type::DependentParameterMapping::Index::Value(1)})),
type::Dependent(
type::DependentTerm::Function(
type::DependentTerm::Value(
TypeErasedValue(type::Type_, {type::Type_})),
type::DependentTerm::Function(
type::DependentTerm::Call(
type::DependentTerm::Value(TypeErasedValue(
type::Family(type::Type_), {&*FunctionOrPointer})),
type::DependentTerm::DeBruijnIndex(0)),
type::DependentTerm::DeBruijnIndex(1))),
type::DependentParameterMapping(
{type::DependentParameterMapping::Index::Value(1),
type::DependentParameterMapping::Index::Implicit()})),
*Foreign);

return m;
}

Expand Down
11 changes: 10 additions & 1 deletion ir/ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,17 @@ void HandleParseTreeNodeCallExpression(ParseNodeIndex index, IrContext& context,

auto dep = invocable_type.type().AsDependentFunction();
std::optional t = dep(arguments);
if (not t) {
diag.Consume({
diag::Header(diag::MessageKind::Error),
diag::Text(
"Unable to call dependent function with the given arguments."),
});
context.type_stack().push(
{type::QualifiedType::Unqualified(type::Error)});
return;
}
context.type_stack().push({type::QualifiedType::Constant(*t)});
NTH_REQUIRE((v.debug), t->kind() == type::Type::Kind::Function);

nth::stack<jasmin::Value> value_stack;
context.emit.Evaluate(context.emit.tree.subtree_range(index), value_stack,
Expand Down
12 changes: 0 additions & 12 deletions type/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ cc_library(
srcs = ["dependent.cc"],
deps = [
":basic",
":family",
"//ir:function",
"//ir:type_erased_value",
"@asoffer_jasmin//jasmin/core:execute",
Expand All @@ -94,16 +93,6 @@ cc_test(
]
)

cc_library(
name = "family",
hdrs = ["family.h"],
deps = [
":basic",
"//common/language:type_kind",
"@asoffer_nth//nth/debug",
],
)

cc_library(
name = "function",
hdrs = ["function.h"],
Expand Down Expand Up @@ -176,7 +165,6 @@ cc_library(
":basic",
":byte_width",
":dependent",
":family",
":function",
":opaque",
":parameters",
Expand Down
12 changes: 8 additions & 4 deletions type/dependent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ void DependentTerm::PartiallyEvaluate() {
case Node::Kind::FunctionCall: {
if ((write_iter - 1)->kind == Node::Kind::Value) {
if ((write_iter - 2)->kind == Node::Kind::Value) {
auto v = *--write_iter;
auto f = *--write_iter;
auto v = *--write_iter;
*write_iter++ = Node{
.kind = Node::Kind::Value,
.index = static_cast<uint16_t>(values_.index(
Expand All @@ -165,6 +165,9 @@ void DependentTerm::PartiallyEvaluate() {
std::make_reverse_iterator(nodes_.begin())));
}
}
else {
*write_iter++ = *read_iter;
}
} else {
*write_iter++ = *read_iter;
}
Expand All @@ -184,9 +187,6 @@ bool DependentTerm::bind(TypeErasedValue const &value) {
NTH_REQUIRE((v.harden), iter->kind == Node::Kind::Value);
NTH_REQUIRE((v.harden), values_.from_index(iter->index).type() == Type_);
if (value.type() != values_.from_index(iter->index).value()[0].as<Type>()) {
NTH_LOG("{} vs {}") <<={
value.type(), values_.from_index(iter->index).value()[0].as<Type>()
};
return false;
}
++iter;
Expand All @@ -208,4 +208,8 @@ DependentParameterMapping::Index DependentParameterMapping::Index::Value(
return Index(Kind::Value, n);
}

DependentParameterMapping::Index DependentParameterMapping::Index::Implicit() {
return Index(Kind::Implicit, 0);
}

} // namespace ic::type
3 changes: 2 additions & 1 deletion type/dependent.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ struct DependentParameterMapping {
struct Index {
static Index Type(uint16_t n);
static Index Value(uint16_t n);
static Index Implicit();

enum class Kind : uint8_t { Type, Value };
enum class Kind : uint8_t { Type, Value, Implicit };

constexpr Kind kind() const { return kind_; }
constexpr uint16_t index() const { return index_; }
Expand Down
31 changes: 0 additions & 31 deletions type/family.h

This file was deleted.

11 changes: 11 additions & 0 deletions type/type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ TypeContour Contour(Type t) {
case Type::Kind::Primitive:
switch (t.AsPrimitive().kind()) {
case PrimitiveType::Kind::Error:
case PrimitiveType::Kind::Bottom:
case PrimitiveType::Kind::Unit:
default: NTH_UNREACHABLE();
case PrimitiveType::Kind::NullType:
case PrimitiveType::Kind::Scope_:
Expand Down Expand Up @@ -216,10 +218,19 @@ std::optional<Type> DependentFunctionType::operator()(
if (not term_copy.bind(values[index.index()])) {
return std::nullopt; }
break;
case DependentParameterMapping::Index::Kind::Implicit:
if (not term_copy.bind(TypeErasedValue(Unit, {}))) {
return std::nullopt;
}
}
}
if (auto* v = term_copy.evaluate()) { return v->value()[0].as<Type>(); }
return std::nullopt;
}

Type Family(Type t) {
return Function(
Parameters(std::vector<ParametersType::Parameter>{{.type = t}}), {Type_});
}

} // namespace ic::type
4 changes: 2 additions & 2 deletions type/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "nth/container/flyweight_set.h"
#include "type/basic.h"
#include "type/dependent.h"
#include "type/family.h"
#include "type/function.h"
#include "type/opaque.h"
#include "type/parameters.h"
Expand Down Expand Up @@ -40,14 +39,15 @@ struct TypeSystem {
nth::flyweight_set<Type> slice_element_types;
nth::flyweight_set<Type> pointee_types;
nth::flyweight_set<Type> buffer_pointee_types;
nth::flyweight_set<Family> type_families;
nth::flyweight_set<DependentTerm> dependent_terms;
nth::flyweight_set<DependentParameterMapping> dependent_mapping;
nth::flyweight_set<std::pair<size_t, size_t>> dependent_term_mapping_pairs;
};

TypeSystem const& GlobalTypeSystem();

Type Family(Type t);

} // namespace ic::type

#endif // ICARUS_TYPE_TYPE_H

0 comments on commit b306c5d

Please sign in to comment.