xo-expression xo-reader: parser improvements, prep type inf/unify
This commit is contained in:
parent
22e2b40ffe
commit
9172fcdc27
9 changed files with 147 additions and 31 deletions
|
|
@ -64,6 +64,7 @@ namespace xo {
|
|||
DefineExpr::pretty_print(const ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii, "Define",
|
||||
//refrtag("type", this->valuetype()), // need pretty
|
||||
refrtag("name", lhs_var_->name()),
|
||||
refrtag("rhs", rhs_));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,43 @@
|
|||
|
||||
namespace xo {
|
||||
namespace ast {
|
||||
namespace {
|
||||
using xo::scm::prefix_type;
|
||||
|
||||
prefix_type exprtype2prefix(exprtype x)
|
||||
{
|
||||
switch (x) {
|
||||
case exprtype::invalid: assert(false); break;
|
||||
case exprtype::constant: return prefix_type::from_chars("k");
|
||||
case exprtype::primitive: return prefix_type::from_chars("pm");
|
||||
case exprtype::define: return prefix_type::from_chars("def");
|
||||
case exprtype::assign: return prefix_type::from_chars("=");
|
||||
case exprtype::apply: return prefix_type::from_chars("@");
|
||||
case exprtype::lambda: return prefix_type::from_chars("lm");
|
||||
case exprtype::variable: return prefix_type::from_chars("var");
|
||||
case exprtype::ifexpr: return prefix_type::from_chars("if");
|
||||
case exprtype::sequence: return prefix_type::from_chars("seq");
|
||||
case exprtype::convert: return prefix_type::from_chars("cvt");
|
||||
case exprtype::n_expr: assert(false); break;
|
||||
}
|
||||
|
||||
return prefix_type::from_chars("?expr");
|
||||
}
|
||||
}
|
||||
|
||||
GeneralizedExpression::GeneralizedExpression(exprtype extype,
|
||||
TypeDescr valuetype)
|
||||
: extype_{extype},
|
||||
valuetype_ref_{type_ref::dwim(exprtype2prefix(extype), valuetype)}
|
||||
{}
|
||||
|
||||
GeneralizedExpression::GeneralizedExpression(exprtype extype,
|
||||
prefix_type prefix,
|
||||
TypeDescr valuetype)
|
||||
: extype_{extype},
|
||||
valuetype_ref_{type_ref::dwim(prefix, valuetype)}
|
||||
{}
|
||||
|
||||
std::string
|
||||
GeneralizedExpression::display_string() const {
|
||||
return tostr(*this);
|
||||
|
|
|
|||
|
|
@ -20,16 +20,9 @@ namespace xo {
|
|||
namespace ast {
|
||||
TypeDescr
|
||||
Lambda::assemble_lambda_td(const std::vector<rp<Variable>> & argv,
|
||||
TypeDescr explicit_return_td,
|
||||
const rp<Expression> & body)
|
||||
TypeDescr return_td)
|
||||
{
|
||||
if (!body)
|
||||
return nullptr;
|
||||
|
||||
/** assemble function type.
|
||||
*
|
||||
* NOTE: need this to be unique!
|
||||
**/
|
||||
assert(return_td != nullptr);
|
||||
|
||||
std::vector<TypeDescr> arg_td_v;
|
||||
{
|
||||
|
|
@ -40,6 +33,25 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
auto function_info
|
||||
= FunctionTdxInfo(return_td,
|
||||
arg_td_v,
|
||||
false /*!is_noexcept*/);
|
||||
|
||||
TypeDescr lambda_td
|
||||
= TypeDescrBase::require_by_fn_info(function_info);
|
||||
|
||||
return lambda_td;
|
||||
}
|
||||
|
||||
TypeDescr
|
||||
Lambda::assemble_lambda_td(const std::vector<rp<Variable>> & argv,
|
||||
TypeDescr explicit_return_td,
|
||||
const rp<Expression> & body)
|
||||
{
|
||||
if (!body)
|
||||
return nullptr;
|
||||
|
||||
if (explicit_return_td && body->valuetype() && (explicit_return_td != body->valuetype())) {
|
||||
throw std::runtime_error(tostr("explicit lambda return type T1 conflicts with lambda body T2",
|
||||
xtag("T1", explicit_return_td),
|
||||
|
|
@ -48,15 +60,9 @@ namespace xo {
|
|||
|
||||
// TODO: unify(explicit_return_td, body->valuetype())
|
||||
|
||||
auto function_info
|
||||
= FunctionTdxInfo(explicit_return_td ? explicit_return_td : body->valuetype(),
|
||||
arg_td_v,
|
||||
false /*!is_noexcept*/);
|
||||
TypeDescr return_td = explicit_return_td ? explicit_return_td : body->valuetype();
|
||||
|
||||
TypeDescr lambda_td
|
||||
= TypeDescrBase::require_by_fn_info(function_info);
|
||||
|
||||
return lambda_td;
|
||||
return assemble_lambda_td(argv, return_td);
|
||||
}
|
||||
|
||||
std::string
|
||||
|
|
@ -78,6 +84,15 @@ namespace xo {
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
rp<Lambda>
|
||||
Lambda::make(const std::string & name,
|
||||
TypeDescr lambda_td,
|
||||
const rp<LocalEnv> & env,
|
||||
const rp<Expression> & body)
|
||||
{
|
||||
return new Lambda(name, lambda_td, env, body);
|
||||
}
|
||||
|
||||
rp<Lambda>
|
||||
Lambda::make_from_env(const std::string & name,
|
||||
const rp<LocalEnv> & env,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,18 @@ namespace xo {
|
|||
|
||||
bool type_ref::is_concrete() const { return td_ != nullptr; }
|
||||
|
||||
type_ref
|
||||
type_ref::dwim(prefix_type prefix, TypeDescr td)
|
||||
{
|
||||
if (td) {
|
||||
/** type resolved, type variable not needed **/
|
||||
return type_ref(type_var(), td);
|
||||
} else {
|
||||
/** type not resolved, assign a unique type variable **/
|
||||
return type_ref(generate_unique(prefix), td);
|
||||
}
|
||||
}
|
||||
|
||||
auto
|
||||
type_ref::generate_unique(xo::scm::prefix_type prefix) -> xo::scm::type_var
|
||||
{
|
||||
|
|
|
|||
|
|
@ -212,6 +212,18 @@ namespace xo {
|
|||
};
|
||||
}
|
||||
|
||||
rp<TypeBlueprint>
|
||||
type_unifier::lookup(const type_var & name) const
|
||||
{
|
||||
auto ix = constraint_map_.find(name);
|
||||
|
||||
if (ix != constraint_map_.end()) {
|
||||
return ix->second;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue