diff --git a/codon/cir/llvm/optimize.cpp b/codon/cir/llvm/optimize.cpp index 87a4aa6a..d87c5389 100644 --- a/codon/cir/llvm/optimize.cpp +++ b/codon/cir/llvm/optimize.cpp @@ -595,6 +595,11 @@ void runLLVMOptimizationPasses(llvm::Module *module, bool debug, bool jit, } void verify(llvm::Module *module) { + std::string s; + llvm::raw_string_ostream OS(s); + OS << *module; + OS.flush(); + LOG("--> {}", s); const bool broken = llvm::verifyModule(*module, &llvm::errs()); seqassertn(!broken, "module broken"); } diff --git a/codon/parser/ast/types/class.cpp b/codon/parser/ast/types/class.cpp index 5ff824ea..ff6f4dec 100644 --- a/codon/parser/ast/types/class.cpp +++ b/codon/parser/ast/types/class.cpp @@ -213,12 +213,11 @@ bool RecordType::isInstantiated() const { } std::string RecordType::debugString(char mode) const { - if (name == "Partial" && generics[0].type->canRealize() && false) { + if (name == "Partial" && generics[0].type->canRealize()) { auto func = getPartialFunc(); std::vector gs; - for (auto &a : func->generics) - if (!a.name.empty()) - gs.push_back(a.type->debugString(mode)); + for (auto &a : generics[2].type->getRecord()->args) + gs.push_back(a->debugString(mode)); std::vector as; int i = 0, gi = 0; auto known = getPartialMask(); @@ -238,7 +237,8 @@ std::string RecordType::debugString(char mode) const { fnname = func->debugString(mode); } return fmt::format("{}[{}{}]", fnname, join(as, ","), - mode == 2 ? fmt::format(";{}", join(gs, ",")) : ""); + // mode == 2 ? fmt::format(";{}", join(gs, ",")) : + ""); } return fmt::format("{}", this->ClassType::debugString(mode)); } diff --git a/codon/parser/visitors/typecheck/call.cpp b/codon/parser/visitors/typecheck/call.cpp index 8ecb9232..97a2d3f9 100644 --- a/codon/parser/visitors/typecheck/call.cpp +++ b/codon/parser/visitors/typecheck/call.cpp @@ -201,7 +201,8 @@ bool TypecheckVisitor::transformCallArgs(std::vector &args) { args.erase(args.begin() + ai); } else { if (auto el = args[ai].value->getEllipsis()) { - if (ai + 1 == args.size() && args[ai].name.empty()) + if (ai + 1 == args.size() && args[ai].name.empty() && + el->mode != EllipsisExpr::PIPE) el->mode = EllipsisExpr::PARTIAL; } // Case: normal argument (no expansion) @@ -358,8 +359,7 @@ ExprPtr TypecheckVisitor::callReorderArguments(FuncTypePtr calleeFn, CallExpr *e std::vector names; std::vector values; if (!part.known.empty()) { - auto e = - transform(N(N(N(part.var), "kwargs"), "args")); + auto e = transform(N(N(part.var), "kwargs"), "args"); for (auto &[n, ne] : extractNamedTuple(e)) { names.emplace_back(n); values.emplace_back(transform(ne)); @@ -623,7 +623,7 @@ ExprPtr TypecheckVisitor::transformTupleGenerator(CallExpr *expr) { E(Error::CALL_TUPLE_COMPREHENSION, expr->args[0].value->origExpr); auto g = CAST(expr->args[0].value->origExpr, GeneratorExpr); if (!g || g->kind != GeneratorExpr::Generator || g->loopCount() != 1) - E(Error::CALL_TUPLE_COMPREHENSION, expr->args[0].value->origExpr); + E(Error::CALL_TUPLE_COMPREHENSION, expr->args[0].value); g->kind = GeneratorExpr::TupleGenerator; return transform(g->shared_from_this()); } diff --git a/codon/parser/visitors/typecheck/infer.cpp b/codon/parser/visitors/typecheck/infer.cpp index 915592b4..d5dfa08c 100644 --- a/codon/parser/visitors/typecheck/infer.cpp +++ b/codon/parser/visitors/typecheck/infer.cpp @@ -964,6 +964,15 @@ TypecheckVisitor::generateSpecialAst(types::FuncType *type) { N(N("__internal__.union_get_data"), N(selfVar), NT(unionTypes[0]->realizedName())))); ast->suite = suite; + } else if (startswith(ast->name, "__internal__.namedkeys")) { + auto n = type->funcGenerics[0].type->getStatic()->evaluate().getInt(); + if (n < 0 || n >= ctx->cache->generatedTupleNames.size()) + error("bad namedkeys index"); + std::vector s; + for (auto &k : ctx->cache->generatedTupleNames[n]) + s.push_back(N(k)); + auto suite = N(N(N(s))); + ast->suite = suite; } return ast; } diff --git a/codon/parser/visitors/typecheck/op.cpp b/codon/parser/visitors/typecheck/op.cpp index a653ee16..63c30881 100644 --- a/codon/parser/visitors/typecheck/op.cpp +++ b/codon/parser/visitors/typecheck/op.cpp @@ -216,6 +216,7 @@ void TypecheckVisitor::visit(PipeExpr *expr) { // make sure to extract these layers and move them to the pipeline. // Example: `foo(...)` that is transformed to `foo(unwrap(...))` will become // `unwrap(...) |> foo(...)` + LOG("--> {}", (*ec)); transform(*ec); auto layers = findEllipsis(*ec); seqassert(!layers.empty(), "can't find the ellipsis"); diff --git a/stdlib/internal/core.codon b/stdlib/internal/core.codon index 1e450e0f..e1678df1 100644 --- a/stdlib/internal/core.codon +++ b/stdlib/internal/core.codon @@ -238,6 +238,15 @@ class NamedTuple: def __getitem__(self, key: Static[str]): return getattr(self, key) + def __keys__(self): + return __internal__.namedkeys(N) + + def __repr__(self): + keys = self.__keys__() + values = [v.__repr__() for v in self.args] + s = ', '.join(f"{keys[i]}: {values[i]}" for i in range(len(keys))) + return f"({s})" + @__internal__ @tuple diff --git a/stdlib/internal/internal.codon b/stdlib/internal/internal.codon index 130939b8..a0a7ce45 100644 --- a/stdlib/internal/internal.codon +++ b/stdlib/internal/internal.codon @@ -187,6 +187,9 @@ class __internal__: # Tuples + def namedkeys(N: Static[int]): + pass + @pure @derives @llvm