1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00

Merge simplify & typecheck [wip]

This commit is contained in:
Ibrahim Numanagić 2023-07-05 11:58:22 +02:00
parent 9cad341b25
commit 87419e9ac3
10 changed files with 27 additions and 16 deletions

View File

@ -198,7 +198,7 @@ void TranslateVisitor::visit(CallExpr *expr) {
expr->args[0].value->getId()->value); expr->args[0].value->getId()->value);
result = make<ir::PointerValue>(expr, val->getVar()); result = make<ir::PointerValue>(expr, val->getVar());
return; return;
} else if (expr->expr->isId("__array__.__new__:0")) { } else if (expr->expr->isId("__array__.__new__")) {
auto fnt = expr->expr->type->getFunc(); auto fnt = expr->expr->type->getFunc();
auto szt = fnt->funcGenerics[0].type->getStatic(); auto szt = fnt->funcGenerics[0].type->getStatic();
auto sz = szt->evaluate().getInt(); auto sz = szt->evaluate().getInt();
@ -209,7 +209,7 @@ void TranslateVisitor::visit(CallExpr *expr) {
result = make<ir::StackAllocInstr>(expr, arrayType, sz); result = make<ir::StackAllocInstr>(expr, arrayType, sz);
return; return;
} else if (expr->expr->getId() && startswith(expr->expr->getId()->value, } else if (expr->expr->getId() && startswith(expr->expr->getId()->value,
"__internal__.yield_in_no_suspend:0")) { "__internal__.yield_in_no_suspend")) {
result = make<ir::YieldInInstr>(expr, getType(expr->getType()), false); result = make<ir::YieldInInstr>(expr, getType(expr->getType()), false);
return; return;
} }

View File

@ -31,7 +31,7 @@ void TypecheckVisitor::visit(AssignExpr *expr) {
transform(expr->var); transform(expr->var);
leaveConditionalBlock(s); leaveConditionalBlock(s);
} else { } else {
s = transform(s); transform(s);
transform(expr->var); transform(expr->var);
} }
std::swap(avoidDomination, ctx->avoidDomination); std::swap(avoidDomination, ctx->avoidDomination);

View File

@ -1217,6 +1217,7 @@ std::pair<bool, ExprPtr> TypecheckVisitor::transformInternalStaticFn(CallExpr *e
} }
idx++; idx++;
} }
LOG("-> {}", tupleItems);
return {true, transform(N<TupleExpr>(tupleItems))}; return {true, transform(N<TupleExpr>(tupleItems))};
} else if (expr->expr->isId("std.internal.static.tuple_type.0")) { } else if (expr->expr->isId("std.internal.static.tuple_type.0")) {
auto funcTyp = expr->expr->type->getFunc(); auto funcTyp = expr->expr->type->getFunc();

View File

@ -97,6 +97,7 @@ void TypecheckVisitor::visit(ClassStmt *stmt) {
generic->getUnbound()->id = val->type->getLink()->id; generic->getUnbound()->id = val->type->getLink()->id;
ctx->addType(ctx->cache->rev(val->canonicalName), val->canonicalName, generic) ctx->addType(ctx->cache->rev(val->canonicalName), val->canonicalName, generic)
->generic = true; ->generic = true;
args.emplace_back(val->canonicalName, nullptr, nullptr, a.status);
} }
} else { } else {
// Add all generics before parent classes, fields and methods // Add all generics before parent classes, fields and methods
@ -345,7 +346,8 @@ void TypecheckVisitor::visit(ClassStmt *stmt) {
for (auto &m : ctx->cache->classes[canonicalName].fields) for (auto &m : ctx->cache->classes[canonicalName].fields)
LOG(" - member: {}: {:D}", m.name, m.type); LOG(" - member: {}: {:D}", m.name, m.type);
for (auto &m : ctx->cache->classes[canonicalName].methods) for (auto &m : ctx->cache->classes[canonicalName].methods)
LOG(" - method: {}: {}", m.first, m.second); LOG(" - method: {}: {} ({:D})", m.first, m.second,
ctx->cache->functions[m.second].type);
} catch (const exc::ParserException &) { } catch (const exc::ParserException &) {
if (!stmt->attributes.has(Attr::Tuple)) if (!stmt->attributes.has(Attr::Tuple))
ctx->remove(name); ctx->remove(name);

View File

@ -33,8 +33,8 @@ TypeContext::TypeContext(Cache *cache, std::string filename)
void TypeContext::add(const std::string &name, const TypeContext::Item &var) { void TypeContext::add(const std::string &name, const TypeContext::Item &var) {
seqassert(!var->scope.empty(), "bad scope for '{}'", name); seqassert(!var->scope.empty(), "bad scope for '{}'", name);
// LOG("[ctx] {} @ {}: + {}: {} ({})", getModule(), getSrcInfo(), name, // LOG("[ctx] {} @ {}: + {}: {} ({:D})", getModule(), getSrcInfo(), name,
// var->canonicalName, var->scope); // var->canonicalName, var->type);
Context<TypecheckItem>::add(name, var); Context<TypecheckItem>::add(name, var);
} }
@ -86,6 +86,7 @@ TypeContext::Item TypeContext::addFunc(const std::string &name,
} }
TypeContext::Item TypeContext::addAlwaysVisible(const TypeContext::Item &item) { TypeContext::Item TypeContext::addAlwaysVisible(const TypeContext::Item &item) {
add(item->canonicalName, item);
if (!cache->typeCtx->Context<TypecheckItem>::find(item->canonicalName)) { if (!cache->typeCtx->Context<TypecheckItem>::find(item->canonicalName)) {
cache->typeCtx->add(item->canonicalName, item); cache->typeCtx->add(item->canonicalName, item);

View File

@ -268,8 +268,9 @@ void TypecheckVisitor::visit(FunctionStmt *stmt) {
// auto parentClassAST = // auto parentClassAST =
// ctx->cache->classes[stmt->attributes.parentClass].ast.get(); // ctx->cache->classes[stmt->attributes.parentClass].ast.get();
parentClass = ctx->forceFind(stmt->attributes.parentClass)->type->getClass(); parentClass = ctx->forceFind(stmt->attributes.parentClass)->type->getClass();
parentClass = parentClass->instantiate(ctx->typecheckLevel - 1, nullptr, nullptr) // parentClass = parentClass->instantiate(ctx->typecheckLevel - 1, nullptr,
->getClass(); // nullptr)
// ->getClass();
// seqassert(parentClass, "parent class not set"); // seqassert(parentClass, "parent class not set");
// for (int i = 0, j = 0, k = 0; i < parentClassAST->args.size(); i++) { // for (int i = 0, j = 0, k = 0; i < parentClassAST->args.size(); i++) {
// if (parentClassAST->args[i].status != Param::Normal) { // if (parentClassAST->args[i].status != Param::Normal) {
@ -439,7 +440,7 @@ void TypecheckVisitor::visit(FunctionStmt *stmt) {
} }
// Debug information // Debug information
LOG("[stmt] added func {}: {}", canonicalName, funcTyp->debugString(2)); // LOG("[stmt] added func {}: {}", canonicalName, funcTyp->debugString(2));
// Expression to be used if function binding is modified by captures or decorators // Expression to be used if function binding is modified by captures or decorators
ExprPtr finalExpr = nullptr; ExprPtr finalExpr = nullptr;

View File

@ -326,6 +326,7 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type, bool force)
trimStars(varName); trimStars(varName);
auto v = ctx->addVar(ctx->cache->rev(varName), varName, auto v = ctx->addVar(ctx->cache->rev(varName), varName,
std::make_shared<LinkType>(type->getArgTypes()[j++])); std::make_shared<LinkType>(type->getArgTypes()[j++]));
// LOG("[param] {} -> {}", v->canonicalName, v->type);
} }
// Populate realization table in advance to support recursive realizations // Populate realization table in advance to support recursive realizations
@ -342,10 +343,11 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type, bool force)
std::make_shared<TypecheckItem>(key, "", ctx->getModule(), type->getFunc()); std::make_shared<TypecheckItem>(key, "", ctx->getModule(), type->getFunc());
ctx->addAlwaysVisible(val); ctx->addAlwaysVisible(val);
auto ast_suite = clone(ast->suite);
if (hasAst) { if (hasAst) {
auto oldBlockLevel = ctx->blockLevel; auto oldBlockLevel = ctx->blockLevel;
ctx->blockLevel = 0; ctx->blockLevel = 0;
auto ret = inferTypes(ast->suite); auto ret = inferTypes(ast_suite);
ctx->blockLevel = oldBlockLevel; ctx->blockLevel = oldBlockLevel;
if (!ret) { if (!ret) {
@ -354,7 +356,7 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type, bool force)
// Lambda typecheck failures are "ignored" as they are treated as statements, // Lambda typecheck failures are "ignored" as they are treated as statements,
// not functions. // not functions.
// TODO: generalize this further. // TODO: generalize this further.
LOG("[error=>] {}", ast->suite->toString(2)); LOG("[error=>] {}", ast_suite->toString(2));
// inferTypes(ast->suite, ctx); // inferTypes(ast->suite, ctx);
error("cannot typecheck the program"); error("cannot typecheck the program");
} }
@ -364,6 +366,8 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type, bool force)
getLogger().level--; getLogger().level--;
this->ctx = oldCtx; this->ctx = oldCtx;
return nullptr; // inference must be delayed return nullptr; // inference must be delayed
} else {
ast_suite = ret;
} }
// Use NoneType as the return type when the return type is not specified and // Use NoneType as the return type when the return type is not specified and
@ -383,7 +387,7 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type, bool force)
args.emplace_back(varName, nullptr, nullptr, i.status); args.emplace_back(varName, nullptr, nullptr, i.status);
} }
r->ast = N<FunctionStmt>(ast->getSrcInfo(), r->type->realizedName(), nullptr, args, r->ast = N<FunctionStmt>(ast->getSrcInfo(), r->type->realizedName(), nullptr, args,
ast->suite); ast_suite);
r->ast->attributes = ast->attributes; r->ast->attributes = ast->attributes;
if (!in(ctx->cache->pendingRealizations, if (!in(ctx->cache->pendingRealizations,

View File

@ -30,8 +30,8 @@ void TypecheckVisitor::visit(UnaryExpr *expr) {
if (expr->op == "!") { if (expr->op == "!") {
// `not expr` -> `expr.__bool__().__invert__()` // `not expr` -> `expr.__bool__().__invert__()`
resultExpr = transform(N<CallExpr>(N<DotExpr>( resultExpr = transform(N<CallExpr>(
N<CallExpr>(N<DotExpr>(clone(expr->expr), "__bool__")), "__invert__"))); N<DotExpr>(N<CallExpr>(N<DotExpr>(expr->expr, "__bool__")), "__invert__")));
} else { } else {
std::string magic; std::string magic;
if (expr->op == "~") if (expr->op == "~")
@ -43,7 +43,7 @@ void TypecheckVisitor::visit(UnaryExpr *expr) {
else else
seqassert(false, "invalid unary operator '{}'", expr->op); seqassert(false, "invalid unary operator '{}'", expr->op);
resultExpr = resultExpr =
transform(N<CallExpr>(N<DotExpr>(clone(expr->expr), format("__{}__", magic)))); transform(N<CallExpr>(N<DotExpr>(expr->expr, format("__{}__", magic))));
} }
} }

View File

@ -293,6 +293,8 @@ void TypecheckVisitor::defaultVisit(Stmt *s) {
/// Typecheck statement expressions. /// Typecheck statement expressions.
void TypecheckVisitor::visit(StmtExpr *expr) { void TypecheckVisitor::visit(StmtExpr *expr) {
auto done = true; auto done = true;
if (expr->expr->isId("chain.0"))
LOG("--");
for (auto &s : expr->stmts) { for (auto &s : expr->stmts) {
transform(s); transform(s);
done &= s->isDone(); done &= s->isDone();

View File

@ -8,7 +8,7 @@ from internal.static import vars_types, tuple_type, vars as _vars
def vars(obj, with_index: Static[int] = 0): def vars(obj, with_index: Static[int] = 0):
__static_print__(with_index) __static_print__(obj, with_index)
return _vars(obj, with_index) return _vars(obj, with_index)