Skip to content

Commit

Permalink
start adding Converter
Browse files Browse the repository at this point in the history
  • Loading branch information
24sharkS committed Jun 27, 2020
1 parent 309a011 commit 259d874
Show file tree
Hide file tree
Showing 6 changed files with 49,105 additions and 48 deletions.
135 changes: 93 additions & 42 deletions autowrap/ConversionProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,19 @@ def matching_python_type(self, cpp_type):
return ""

def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, (int, long))" % (argument_var,)
return "stopifnot(is_scalar_integer(%s))" % (argument_var,)
#return "isinstance(%s, (int, long))" % (argument_var,)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""
call_as = "(<%s>%s)" % (cpp_type, argument_var)
call_as = ""
#call_as = "(<%s>%s)" % (cpp_type, argument_var)
cleanup = ""
return code, call_as, cleanup

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = <%s>%s" % (output_py_var, cpp_type, input_cpp_var)
return None
#return "%s = <%s>%s" % (output_py_var, cpp_type, input_cpp_var)


# TODO: common base class for float, int, str conversion
Expand All @@ -289,17 +292,22 @@ def matches(self, cpp_type):
def matching_python_type(self, cpp_type):
return "double"

# def type_check_expression(self, cpp_type, argument_var):
# return "isinstance(%s, float)" % (argument_var,)

def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, float)" % (argument_var,)
return "stopifnot(is_scalar_double(%s))" % (argument_var,)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""
call_as = "(<%s>%s)" % (cpp_type, argument_var)
call_as = ""
#call_as = "(<%s>%s)" % (cpp_type, argument_var)
cleanup = ""
return code, call_as, cleanup

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = <%s>%s" % (output_py_var, cpp_type, input_cpp_var)
return None
#return "%s = <%s>%s" % (output_py_var, cpp_type, input_cpp_var)


class FloatConverter(TypeConverterBase):
Expand All @@ -311,19 +319,26 @@ def matches(self, cpp_type):
return not cpp_type.is_ptr

def matching_python_type(self, cpp_type):
return "float"
#return "float"
return "double"

# def type_check_expression(self, cpp_type, argument_var):
# return "isinstance(%s, float)" % (argument_var,)

def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, float)" % (argument_var,)
return "stopifnot(is_scalar_double(%s))" % (argument_var,)
#return "isinstance(%s, float)" % (argument_var,)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""
call_as = "(<%s>%s)" % (cpp_type, argument_var)
call_as = ""
#call_as = "(<%s>%s)" % (cpp_type, argument_var)
cleanup = ""
return code, call_as, cleanup

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = <%s>%s" % (output_py_var, cpp_type, input_cpp_var)
return None
#return "%s = <%s>%s" % (output_py_var, cpp_type, input_cpp_var)


class EnumConverter(TypeConverterBase):
Expand All @@ -342,16 +357,19 @@ def matching_python_type(self, cpp_type):

def type_check_expression(self, cpp_type, argument_var):
values = ", ".join(str(v) for (__, v) in self.enum.items)
return "%s in [%s]" % (argument_var, values)
return "{} %in% c({})".format(argument_var, values)
#return "%s in [%s]" % (argument_var, values)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""
call_as = "(<_%s>%s)" % (cpp_type.base_type, argument_var)
call_as = ""
# call_as = "(<_%s>%s)" % (cpp_type.base_type, argument_var)
cleanup = ""
return code, call_as, cleanup

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = <int>%s" % (output_py_var, input_cpp_var)
return None
#return "%s = <int>%s" % (output_py_var, input_cpp_var)


class CharConverter(TypeConverterBase):
Expand All @@ -362,23 +380,34 @@ def get_base_types(self):
def matches(self, cpp_type):
return not cpp_type.is_ptr

def matching_python_type(self, cpp_type):
def matching_r_type(self, cpp_type):
return "bytes"

# def matching_python_type(self, cpp_type):
# return "bytes"

def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, bytes) and len(%s) == 1" % (argument_var, argument_var,)
return "stopifnot(is_scalar_character(%s))" % (argument_var,)
#return "isinstance(%s, bytes) and len(%s) == 1" % (argument_var, argument_var,)

# not final
def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""
call_as = "(<char>((%s)[0]))" % argument_var
cleanup = ""
code = "py_run_string(\"%s = bytes(%s)\")" % (argument_var, argument_var,)
call_as = "%s" % argument_var
cleanup = "py_run_string(\"del %s\")" % argument_var
#code = ""
#call_as = "(<char>((%s)[0]))" % argument_var
#cleanup = ""
return code, call_as, cleanup

def call_method(self, res_type, cy_call_str):
return "cdef char _r = %s" % cy_call_str

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = chr(<char>(%s))" % (output_py_var, input_cpp_var)
def output_conversion(self, cpp_type, input_py_var, output_r_var):
return "%s = as.character(%s)" % (output_r_var, input_py_var)

# def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
# return "%s = chr(<char>(%s))" % (output_py_var, input_cpp_var)


class ConstCharPtrConverter(TypeConverterBase):
Expand All @@ -389,23 +418,33 @@ def get_base_types(self):
def matches(self, cpp_type):
return cpp_type.is_ptr

def matching_python_type(self, cpp_type):
return "bytes"
def matching_r_type(self, cpp_type):
return "character"

# def matching_python_type(self, cpp_type):
# return "bytes"

def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, bytes)" % (argument_var,)
return "stopifnot(is_scalar_character(%s))" % (argument_var,)
#return "isinstance(%s, bytes)" % (argument_var,)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = Code().add("cdef const_char * input_%s = <const_char *> %s" % (argument_var, argument_var))
call_as = "input_%s" % argument_var
cleanup = ""
code = "py_run_string(\"%s = bytes(%s)\")" % (argument_var, argument_var,)
call_as = "%s" % argument_var
cleanup = "py_run_string(\"del %s\")" % argument_var
# code = Code().add("cdef const_char * input_%s = <const_char *> %s" % (argument_var, argument_var))
# call_as = "input_%s" % argument_var
# cleanup = ""
return code, call_as, cleanup

def call_method(self, res_type, cy_call_str):
return "cdef const_char * _r = _cast_const_away(%s)" % cy_call_str

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = <const_char *>(%s)" % (output_py_var, input_cpp_var)
def output_conversion(self, cpp_type, input_py_var, output_r_var):
return "%s = as.character(%s)" % (output_r_var, input_py_var)

# def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
# return "%s = <const_char *>(%s)" % (output_py_var, input_cpp_var)


class CharPtrConverter(TypeConverterBase):
Expand All @@ -416,23 +455,33 @@ def get_base_types(self):
def matches(self, cpp_type):
return cpp_type.is_ptr

def matching_python_type(self, cpp_type):
return "bytes"
def matching_r_type(self, cpp_type):
return "character"

# def matching_python_type(self, cpp_type):
# return "bytes"

def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, bytes)" % (argument_var,)
return "stopifnot(is_scalar_character(%s))" % (argument_var,)
#return "isinstance(%s, bytes)" % (argument_var,)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""
call_as = "(<char *>%s)" % argument_var
cleanup = ""
code = "py_run_string(\"%s = bytes(%s)\")" % (argument_var, argument_var,)
call_as = "%s" % argument_var
cleanup = "py_run_string(\"del %s\")" % argument_var
# code = ""
# call_as = "(<char *>%s)" % argument_var
# cleanup = ""
return code, call_as, cleanup

def call_method(self, res_type, cy_call_str):
return "cdef char * _r = _cast_const_away(%s)" % cy_call_str

def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
return "%s = <char *>(%s)" % (output_py_var, input_cpp_var)
def output_conversion(self, cpp_type, input_py_var, output_r_var):
return "%s = as.character(%s)" % (output_r_var, input_py_var)

# def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
# return "%s = <char *>(%s)" % (output_py_var, input_cpp_var)


class TypeToWrapConverter(TypeConverterBase):
Expand All @@ -449,17 +498,19 @@ def matches(self, cpp_type):
def matching_python_type(self, cpp_type):
return cpp_type.base_type

#not final
def type_check_expression(self, cpp_type, argument_var):
return "isinstance(%s, %s)" % (argument_var, cpp_type.base_type)
return "stopifnot(all(class({}) == c(\"R6\",\"{}\")))".format(argument_var,cpp_type)
#return "isinstance(%s, %s)" % (argument_var, cpp_type.base_type)

def input_conversion(self, cpp_type, argument_var, arg_num):
code = ""

call_as = "(%s\$get_py_object())" % (argument_var, )
cy_type = self.converters.cython_type(cpp_type)
if cpp_type.is_ptr:
call_as = "(%s.inst.get())" % (argument_var, )
else:
call_as = "(deref(%s.inst.get()))" % (argument_var, )
# if cpp_type.is_ptr:
# call_as = "(%s.inst.get())" % (argument_var, )
# else:
# call_as = "(deref(%s.inst.get()))" % (argument_var, )

cleanup = ""
return code, call_as, cleanup
Expand Down
7 changes: 5 additions & 2 deletions autowrap/Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ def _main(argv):
out = options.out
__, out_ext = os.path.splitext(out)

if out_ext != ".pyx":
parser.exit(1, "\nout file has wrong extension: '.pyx' required\n")
#if out_ext != ".pyx":
# parser.exit(1, "\nout file has wrong extension: '.pyx' required\n")

if out_ext not in (".r",".R"):
parser.exit(1,"\nout file has wrong extension: '.R/r' required\n")

def collect(from_, extension):
collected = []
Expand Down
4 changes: 4 additions & 0 deletions autowrap/Types.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ def __init__(self, base_type, template_args=None, is_ptr=False, is_ref=False,
self.set_is_const_rec()
self.topmost_is_const = True

#recursive
def set_is_const_rec(self):
self.topmost_is_const = True
if self.template_args is None:
return
for t in self.template_args:
t.set_is_const_rec()

# recursive
def set_is_ref_rec(self):
self.topmost_is_ref = True
if self.template_args is None:
Expand All @@ -81,6 +83,7 @@ def transformed(self, typemap):
copied.check_for_recursion()
return copied

# recursive
def _transform(self, typemap, indent):

aliased_t = typemap.get(self.base_type)
Expand All @@ -97,6 +100,7 @@ def _transform(self, typemap, indent):
for t in self.template_args or []:
t._transform(typemap, indent + 1)

# returns object with removed flags.
def _rm_flags(self):
rv = self.copy()
rv.is_ptr = rv.is_ref = False
Expand Down
2 changes: 1 addition & 1 deletion example/libcpp_test.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ cdef extern from "libcpp_test.hpp":
void process21(libcpp_map[int, float] & in_, libcpp_map[int,int] & arg2)
void process211(libcpp_map[int, float] & in_, libcpp_map[libcpp_string, libcpp_vector[int] ] & arg2)
void process212(libcpp_map[int, float] & in_, libcpp_map[libcpp_string, libcpp_vector[ libcpp_vector[int] ] ] & arg2)
#void process213(libcpp_map[int, float] & in_, libcpp_map[libcpp_string, libcpp_vector[ libcpp_vector[Int] ] ] & arg2)
void process213(libcpp_map[int, float] & in_, libcpp_map[libcpp_string, libcpp_vector[ libcpp_vector[Int] ] ] & arg2)
void process214(libcpp_map[int, float] & in_, libcpp_map[libcpp_string, libcpp_vector[ libcpp_pair[int, int] ] ] & arg2)
void process22(libcpp_set[int] &, libcpp_set[float] &)
void process23(libcpp_vector[int] &, libcpp_vector[float] &)
Expand Down
Loading

0 comments on commit 259d874

Please sign in to comment.