Remove vtables from objects (use __id__ only); Add static itemgetter

pull/363/head
Ibrahim Numanagić 2023-04-17 12:11:41 -07:00
parent 12c858970d
commit 710a38539f
8 changed files with 36 additions and 50 deletions

View File

@ -29,7 +29,7 @@
#define TYPE_SLICE "std.internal.types.slice.Slice"
#define FN_UNWRAP "std.internal.types.optional.unwrap"
#define VAR_ARGV "__argv__"
#define VAR_VTABLE ".__vtable__"
#define VAR_CLSID ".__id__"
#define MAX_INT_WIDTH 10000
#define MAX_REALIZATION_DEPTH 200

View File

@ -328,14 +328,12 @@ std::vector<ClassStmt *> SimplifyVisitor::parseBaseClasses(
E(Error::CLASS_NO_INHERIT, getSrcInfo(), "internal");
// Add __vtable__ to parent classes if it is not there already
auto var = format("{}.{}", VAR_VTABLE, name);
auto var = format("{}.{}", VAR_CLSID, name);
if (typeAst && (cachedCls->fields.empty() || cachedCls->fields[0].name != var)) {
// LOG("[virtual] vtable({}) := {}", name, var);
cachedCls->fields.insert(cachedCls->fields.begin(), {var, nullptr});
cachedCls->ast->args.insert(
cachedCls->ast->args.begin(),
Param{var, transformType(N<IndexExpr>(N<IdExpr>("Ptr"), N<IdExpr>("cobj"))),
nullptr});
cachedCls->ast->args.insert(cachedCls->ast->args.begin(),
Param{var, transformType(N<IdExpr>("int")), nullptr});
}
// Add generics first
@ -348,8 +346,8 @@ std::vector<ClassStmt *> SimplifyVisitor::parseBaseClasses(
if (si == subs.size())
E(Error::GENERICS_MISMATCH, cls, ctx->cache->rev(asts.back()->name),
nGenerics, subs.size());
args.emplace_back(Param{a.name, a.type, transformType(subs[si++], false),
Param::HiddenGeneric});
args.emplace_back(a.name, a.type, transformType(subs[si++], false),
Param::HiddenGeneric);
} else if (a.status == Param::HiddenGeneric) {
args.emplace_back(a);
}
@ -372,14 +370,12 @@ std::vector<ClassStmt *> SimplifyVisitor::parseBaseClasses(
for (auto &a : ast->args) {
if (a.status == Param::Normal && !ClassStmt::isClassVar(a)) {
auto name = a.name;
if (startswith(name, VAR_VTABLE)) { // prevent clashing names
int i = 0;
for (auto &aa : args)
i += bool(startswith(aa.name, a.name));
i += aa.name == a.name || startswith(aa.name, a.name + "#");
if (i)
name = format("{}#{}", name, i);
}
args.emplace_back(Param{name, a.type, a.defaultValue});
args.emplace_back(name, a.type, a.defaultValue);
}
}
}
@ -510,7 +506,7 @@ StmtPtr SimplifyVisitor::codegenMagic(const std::string &op, const ExprPtr &typE
std::vector<Param> args;
for (auto &a : allArgs)
if (!startswith(a.name, VAR_VTABLE))
if (!startswith(a.name, VAR_CLSID))
args.push_back(a);
if (op == "new") {

View File

@ -172,8 +172,8 @@ ExprPtr TypecheckVisitor::transformDot(DotExpr *expr,
return transform(N<BoolExpr>(expr->expr->isStatic()));
return nullptr;
}
// Special case: cls.__vtable_id__
if (expr->expr->isType() && expr->member == "__vtable_id__") {
// Special case: cls.__id__
if (expr->expr->isType() && expr->member == "__id__") {
if (auto c = realize(expr->expr->type))
return transform(N<IntExpr>(ctx->cache->classes[c->getClass()->name]
.realizations[c->getClass()->realizedTypeName()]
@ -195,11 +195,11 @@ ExprPtr TypecheckVisitor::transformDot(DotExpr *expr,
unify(expr->type, ctx->instantiate(bestMethod, typ));
// Handle virtual calls
auto vtableName = format("{}.{}", VAR_VTABLE, typ->name);
auto clsidName = format("{}.{}", VAR_CLSID, typ->name);
// A function is deemed virtual if it is marked as such and if a base class has a
// vtable
bool isVirtual = in(ctx->cache->classes[typ->name].virtuals, expr->member);
isVirtual &= ctx->findMember(typ->name, vtableName) != nullptr;
isVirtual &= ctx->findMember(typ->name, clsidName) != nullptr;
isVirtual &= !expr->expr->isType();
if (isVirtual && !bestMethod->ast->attributes.has(Attr::StaticMethod) &&
!bestMethod->ast->attributes.has(Attr::Property)) {
@ -217,9 +217,12 @@ ExprPtr TypecheckVisitor::transformDot(DotExpr *expr,
NT<IdExpr>("Function"),
std::vector<ExprPtr>{NT<InstantiateExpr>(NT<IdExpr>(name), ids),
NT<IdExpr>(fn->getRetType()->realizedName())});
// Function[Tuple[TArg1, TArg2, ...], TRet](expr.__vtable__T[VIRTUAL_ID])
// Function[Tuple[TArg1, TArg2, ...],
// TRet](__vtables__[expr.__id__][T[VIRTUAL_ID]])
auto e = N<CallExpr>(
fnType, N<IndexExpr>(N<DotExpr>(expr->expr, vtableName), N<IntExpr>(vid)));
fnType, N<IndexExpr>(N<IndexExpr>(N<IdExpr>("__vtables__"),
N<DotExpr>(expr->expr, clsidName)),
N<IntExpr>(vid)));
return transform(e);
}
}

View File

@ -488,12 +488,10 @@ StmtPtr TypecheckVisitor::prepareVTables() {
const auto &fields = ctx->cache->classes[clsTyp->name].fields;
auto suite = N<SuiteStmt>();
for (auto &f : fields)
if (startswith(f.name, VAR_VTABLE)) {
if (startswith(f.name, VAR_CLSID)) {
suite->stmts.push_back(N<AssignMemberStmt>(
N<IdExpr>(varName), f.name,
N<IndexExpr>(
N<IdExpr>("__vtables__"),
N<DotExpr>(N<IdExpr>(clsTyp->realizedName()), "__vtable_id__"))));
N<DotExpr>(N<IdExpr>(clsTyp->realizedName()), "__id__")));
}
LOG_REALIZE("[poly] {} : {}", t, *suite);
@ -516,7 +514,7 @@ StmtPtr TypecheckVisitor::prepareVTables() {
auto types = std::vector<ExprPtr>{};
auto found = false;
for (auto &f : fields) {
if (f.name == format("{}.{}", VAR_VTABLE, baseTyp->name)) {
if (endswith(f.name, format(".{}", baseTyp->name))) {
found = true;
break;
} else {

View File

@ -45,23 +45,6 @@ if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
file(DOWNLOAD https://github.com/TheLartians/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake ${CPM_DOWNLOAD_LOCATION})
endif()
include(${CPM_DOWNLOAD_LOCATION})
CPMAddPackage(
NAME libzmq
VERSION 4.3.4
URL https://github.com/zeromq/libzmq/releases/download/v4.3.4/zeromq-4.3.4.tar.gz
EXCLUDE_FROM_ALL YES
OPTIONS "WITH_PERF_TOOL OFF"
"ZMQ_BUILD_TESTS OFF"
"ENABLE_CPACK OFF"
"BUILD_SHARED ON"
"WITH_LIBSODIUM OFF"
"WITH_TLS OFF")
CPMAddPackage(
NAME cppzmq
URL https://github.com/zeromq/cppzmq/archive/refs/tags/v4.8.1.tar.gz
VERSION 4.8.1
EXCLUDE_FROM_ALL YES
OPTIONS "CPPZMQ_BUILD_TESTS OFF")
CPMAddPackage(
NAME xtl
GITHUB_REPOSITORY "xtensor-stack/xtl"
@ -76,8 +59,8 @@ CPMAddPackage(
CPMAddPackage(
NAME xeus
GITHUB_REPOSITORY "jupyter-xeus/xeus"
VERSION 2.2.0
GIT_TAG 2.2.0
VERSION 3.0.5
GIT_TAG 3.0.5
EXCLUDE_FROM_ALL YES
PATCH_COMMAND patch -N -u CMakeLists.txt --ignore-whitespace -b ${CMAKE_SOURCE_DIR}/xeus.patch || true
OPTIONS "BUILD_EXAMPLES OFF"

View File

@ -39,9 +39,9 @@ class __internal__:
def class_set_obj_vtable(pf: T, T: type) -> None:
"""
Initialize a vtable of a T() object. Compiler generated.
Initialize a vtable ID of a T() object. Compiler generated.
Corresponds to:
pf.__vtable__ = __vtables__[pf.__vtable_id___]
pf.__id__ = pf.__id__
"""
pass

View File

@ -175,6 +175,7 @@ def attrgetter(attr: Static[str]):
return getattr(obj, attr)
return getter
@overload
def itemgetter(*items):
if staticlen(items) == 1:
item = items[0]
@ -190,6 +191,10 @@ def itemgetter(*items):
return g
@overload
def itemgetter(item: Static[int]):
return lambda o: o[item]
def methodcaller(name: Static[str], *args, **kwargs):
def caller(obj):
return getattr(obj, name)(*args, **kwargs)

View File

@ -1132,7 +1132,8 @@ class Foo:
class Bar:
x: float
class FooBar(Static[Foo], Static[Bar]):
pass #! duplicate data attribute 'x' in class definition
pass
# right now works as we rename other fields
#%% keyword_prefix,barebones
def foo(return_, pass_, yield_, break_, continue_, print_, assert_):