53 lines
1.4 KiB
Text
53 lines
1.4 KiB
Text
1. in parser we need.. type unification?
|
|
2. or perhaps just need to introduce type variables.
|
|
|
|
3. we can't resolve type for a recursive pair of functions until we've seen both of them..
|
|
tho we could require letrec
|
|
|
|
def foo = lambda (n : i64) { let (n == 0) then 1 else n * foo(n - 1); };
|
|
|
|
strategy:
|
|
--------
|
|
|
|
while parsing def, instead of creating DefineExpr with nullptr TypeDescr:
|
|
a. create DefineExpr with TypeVariable.
|
|
(We have to do this because can't tell nullptr's apart,..)
|
|
|
|
- generalize xo::reflect::TypeDescrBase
|
|
|
|
// compose these into Expressions.
|
|
//
|
|
struct type_ref {
|
|
bool is_concrete() const { return td_ && td_->is_concrete(); }
|
|
|
|
// generated name, so we can map between types. Don't want to create TypeDescr
|
|
// every time we have a typed location. there'd be a lot of them, and hard to collect
|
|
flatstring<11> id_;
|
|
// if TypeDescr is concrete (fully described), this describes it
|
|
TypeDescr td_;
|
|
};
|
|
|
|
// what we know about a type
|
|
//
|
|
struct TypeBlueprint : public Refcounted {
|
|
static bool equal(bp<TypeTemplate> lhs, bp<TypeTemplate> rhs);
|
|
|
|
type_ref ref_;
|
|
|
|
// additional descriptive info...
|
|
};
|
|
|
|
// effectively these are constraints?
|
|
//
|
|
using TypeSubstitutionMap = map<string, rp<TypeTemplate>>;
|
|
|
|
will have typeunifier in parserstatemachine
|
|
|
|
struct TypeUnifier {
|
|
// extend as unification proceeds
|
|
//
|
|
TypeSubstitutionMap substitutions_;
|
|
};
|
|
|
|
alt strategy
|
|
-------------
|