Skip to content

Commit

Permalink
add =default/delete declarations + macro making empty canonical destr…
Browse files Browse the repository at this point in the history
…uctors (body consists only of 'pass') the same as =default
  • Loading branch information
ehren committed Sep 14, 2024
1 parent c284ee9 commit 1ed18bf
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 7 deletions.
8 changes: 3 additions & 5 deletions ceto/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,7 @@ def is_template_test(expr):

rhs = defnode.parent.rhs

if name == "init" and rhs.name in ["default", "delete"]:
# return class_name + "() = " + defnode.parent.rhs.name
raise CodeGenError("TODO decide best way to express = default/delete", defnode)

if return_type_node is None:
if return_type_node is None and not is_destructor:
raise CodeGenError("declarations must specify a return type", defnode)

if isinstance(rhs, IntegerLiteral) and rhs.integer_string == "0":
Expand All @@ -365,6 +361,8 @@ def is_template_test(expr):

# pure virtual function (codegen_assign handles the "= 0" part)
return indt + funcdef
elif rhs.name in ["default", "delete"]:
return indt + funcdef
else:
raise CodeGenError("bad assignment to function declaration", defnode)
else:
Expand Down
23 changes: 22 additions & 1 deletion include/convenience.cth
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# def (foo<T> -> def (foo:template<typename:T>
defmacro(def (func_name<T>:specifier, args), func_name, T: Identifier, specifier: Node|None, args: [Node]:
template_header: Node = quote(template<typename:unquote(T)>)
Expand All @@ -12,3 +11,25 @@ defmacro(def (func_name<T>:specifier, args), func_name, T: Identifier, specifier
new_args.insert(new_args.end(), args.begin(), args.end())
return Call(quote(def), new_args)
)

# canonical empty destructor to default destructor:
# e.g.
# def (destruct:virtual:
# pass
# )
# goes to
# def (destruct:virtual) = default
# For an empty non-default destructor
# use pass; pass
defmacro (def (destruct:specifier:
pass
), specifier: Node|None:
name: Node = quote(destruct)
destructor = if (specifier:
specified: Node = quote(unquote(name): unquote(specifier))
specified
else:
name
)
return quote(def (unquote(destructor)) = default)
)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def _post_install():
print(f)
subprocess.run([sys.executable, "-m", "ceto", "--_nostandardlibmacros", os.path.join(main_dir, "ceto_private_" + f)])

for f in [os.path.join(rootdir, "tests", "regression", "bounds_check.ctp"), os.path.join(rootdir, "tests", "macros_list_comprehension.ctp"), os.path.join(rootdir, "tests", "regression", "template_func_builtin_macro_convenience.ctp")]:
for f in [os.path.join(rootdir, "tests", "regression", "bounds_check.ctp"), os.path.join(rootdir, "tests", "macros_list_comprehension.ctp"), os.path.join(rootdir, "tests", "regression", "template_func_builtin_macro_convenience.ctp"), os.path.join(rootdir, "tests", "regression", "default_destructor_builtin_macro.ctp")]:
print(f)
subprocess.run([sys.executable, "-m", "ceto", f])

Expand Down
20 changes: 20 additions & 0 deletions tests/regression/default_destructor_builtin_macro.ctp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
struct (Foo1:
pass
)

struct (Foo2:
def (destruct:virtual) = default
)

struct (Foo3:
# this is actually defaulted like Foo2 (use pass; pass for non-defaulted but empty)
def (destruct:virtual:
pass
)
)

def (main:
static_assert(not std.has_virtual_destructor_v<Foo1>)
static_assert(std.has_virtual_destructor_v<Foo2>)
static_assert(std.has_virtual_destructor_v<Foo3>)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <functional>
#include <cassert>
#include <compare> // for <=>
#include <thread>
#include <optional>


#include "ceto.h"
//#include "ceto_private_boundscheck.donotedit.autogenerated.h"

#include "ceto_private_listcomp.donotedit.autogenerated.h"
;
#include "ceto_private_boundscheck.donotedit.autogenerated.h"
;
#include "ceto_private_convenience.donotedit.autogenerated.h"
;
struct Foo1 : public ceto::object {

};

struct Foo2 : public ceto::object {

virtual ~Foo2() = default;

};

struct Foo3 : public ceto::object {

virtual ~Foo3() = default;

};

auto main() -> int {
static_assert(!std::has_virtual_destructor_v<Foo1>);
static_assert(std::has_virtual_destructor_v<Foo2>);
static_assert(std::has_virtual_destructor_v<Foo3>);
}

7 changes: 7 additions & 0 deletions tests/regression/template_func_builtin_macro_convenience.ctp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def (foo<T>, x: T:
return x
)

def (main:
foo(5)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <functional>
#include <cassert>
#include <compare> // for <=>
#include <thread>
#include <optional>


#include "ceto.h"
//#include "ceto_private_boundscheck.donotedit.autogenerated.h"

#include "ceto_private_listcomp.donotedit.autogenerated.h"
;
#include "ceto_private_boundscheck.donotedit.autogenerated.h"
;
#include "ceto_private_convenience.donotedit.autogenerated.h"
;
template<typename T> inline auto foo(const T x) -> auto {
return x;
}

auto main() -> int {
foo(5);
}

0 comments on commit 1ed18bf

Please sign in to comment.