Commits

Yosuke Onoue committed 02a9fce

fix packaging

Comments (0)

Files changed (9)

otypes.py

-import imp
-import sys
-import ctypes
-import template
-
-def load_lib(name):
-    lib = ctypes.CDLL(name)
-    ArgArray = ctypes.c_char_p * (len(sys.argv) + 1)
-    args = ArgArray()
-    for i,arg in enumerate(sys.argv):
-        args[i] = ctypes.c_char_p(arg)
-    args[len(sys.argv)] = None
-    lib.caml_startup(args)
-    return lib
-
-def create_module(name, src_name, context, path=None):
-    file, pathname, description = imp.find_module(src_name, path)
-    mod = imp.load_module(name, file, pathname, description)
-    mod.__dict__['context'] = context
-    return mod
-
-def make(name, module_name):
-    lib = load_lib(name)
-    path = template.__path__
-    mod = create_module(module_name, 'otypes', lib, path)
-    util = create_module(module_name + '.util', 'util', lib, path)
-    util.__dict__['otypes'] = mod
-    mod.__dict__['util'] = util
-
-    # alloc.h
-    mod.context.caml_alloc.restype = mod.ml_value
-    mod.context.caml_alloc_small.restype = mod.ml_value
-    mod.context.caml_alloc_tuple.restype = mod.ml_value
-    mod.context.caml_alloc_string.restype = mod.ml_value
-    mod.context.caml_copy_string.restype = mod.ml_value
-    mod.context.caml_copy_string_array.restype = mod.ml_value
-    mod.context.caml_copy_double.restype = mod.ml_value
-    mod.context.caml_copy_int32.restype = mod.ml_value
-    mod.context.caml_copy_int64.restype = mod.ml_value
-    mod.context.caml_copy_nativeint.restype = mod.ml_value
-    mod.context.caml_alloc_array.restype = mod.ml_value
-    mod.context.caml_alloc_final.restype = mod.ml_value
-    mod.context.caml_convert_flag_list = ctypes.c_int
-
-    # callback.h
-    mod.context.caml_callback.restype = mod.ml_value
-    mod.context.caml_callback2.restype = mod.ml_value
-    mod.context.caml_callback3.restype = mod.ml_value
-    mod.context.caml_callbackN.restype = mod.ml_value
-    mod.context.caml_callback_exn.restype = mod.ml_value
-    mod.context.caml_callback2_exn.restype = mod.ml_value
-    mod.context.caml_callback3_exn.restype = mod.ml_value
-    mod.context.caml_callbackN_exn.restype = mod.ml_value
-    mod.context.caml_named_value.restype = mod.ml_value_p
-    mod.context.caml_main.restype = None
-    mod.context.caml_startup.restype = None
-
-    # custom.h
-    mod.context.caml_alloc_custom.restype = mod.ml_value
-    mod.context.caml_register_custom_operations.restype = None
-    #mod.context.caml_compare_unordered.restype = ctypes.c_int
-
-    # fail.h
-    mod.context.caml_raise.restype = None
-    mod.context.caml_raise_constant.restype = None
-    mod.context.caml_raise_with_arg.restype = None
-    mod.context.caml_raise_with_args.restype = None
-    mod.context.caml_raise_with_string.restype = None
-    mod.context.caml_failwith.restype = None
-    mod.context.caml_invalid_argument.restype = None
-    mod.context.caml_raise_out_of_memory.restype = None
-    mod.context.caml_raise_stack_overflow.restype = None
-    mod.context.caml_raise_sys_error.restype = None
-    mod.context.caml_raise_end_of_file.restype = None
-    mod.context.caml_raise_zero_divide.restype = None
-    mod.context.caml_raise_not_found.restype = None
-    #mod.context.caml_init_exceptions.restype = None
-    mod.context.caml_array_bound_error.restype = None
-    mod.context.caml_raise_sys_blocked_io.restype = None
-
-    # intext.h
-    # TODO
-
-    # memory.h
-    mod.context.caml_alloc_shr.restype = mod.ml_value
-    mod.context.caml_adjust_gc_speed.restype = None
-    mod.context.caml_alloc_dependent_memory.restype = None
-    mod.context.caml_free_dependent_memory.restype = None
-    mod.context.caml_modify.restype = None
-    mod.context.caml_initialize.restype = None
-    mod.context.caml_check_urgent_gc.restype = mod.ml_value
-    mod.context.caml_stat_alloc.restype = ctypes.c_void_p
-    mod.context.caml_stat_free.restype = None
-    mod.context.caml_stat_resize.restype = ctypes.c_void_p
-    mod.context.caml_register_global_root.restype = None
-    mod.context.caml_remove_global_root.restype = None
-    #mod.context.caml_register_generation_global_root.restype = None
-    #mod.context.caml_remove_generation_global_root.restype = None
-    #mod.context.caml_modify_generation_global_root.restype = None
-
-    # mlvalues.h
-    mod.context.caml_get_public_method.restype = mod.ml_value
-    #mod.context.caml_hash_variant.restype = mod.ml_value
-    mod.context.caml_string_length.restype = mod.ml_mlsize_t
-    #mod.context.caml_Double_val.restype = ctypes.c_double
-    #mod.context.caml_Store_double_val.restype = None
-    #mod.context.caml_Int64_val.restype = mod.ml_int64
-

otypes/__init__.py

Empty file added.

otypes/bootstrap.py

+import imp
+import sys
+import ctypes
+import otypes
+
+def load_lib(name):
+    lib = ctypes.CDLL(name)
+    ArgArray = ctypes.c_char_p * (len(sys.argv) + 1)
+    args = ArgArray()
+    for i,arg in enumerate(sys.argv):
+        args[i] = ctypes.c_char_p(arg)
+    args[len(sys.argv)] = None
+    lib.caml_startup(args)
+    return lib
+
+def create_module(name, src_name, context, path=None):
+    file, pathname, description = imp.find_module(src_name, path)
+    mod = imp.load_module(name, file, pathname, description)
+    mod.__dict__['context'] = context
+    return mod
+
+def make(name, module_name):
+    lib = load_lib(name)
+    path = otypes.__path__
+    mod = create_module(module_name, 'template', lib, path)
+    util = create_module(module_name + '.util', 'util', lib, path)
+    util.__dict__['otypes'] = mod
+    mod.__dict__['util'] = util
+
+    # alloc.h
+    mod.context.caml_alloc.restype = mod.ml_value
+    mod.context.caml_alloc_small.restype = mod.ml_value
+    mod.context.caml_alloc_tuple.restype = mod.ml_value
+    mod.context.caml_alloc_string.restype = mod.ml_value
+    mod.context.caml_copy_string.restype = mod.ml_value
+    mod.context.caml_copy_string_array.restype = mod.ml_value
+    mod.context.caml_copy_double.restype = mod.ml_value
+    mod.context.caml_copy_int32.restype = mod.ml_value
+    mod.context.caml_copy_int64.restype = mod.ml_value
+    mod.context.caml_copy_nativeint.restype = mod.ml_value
+    mod.context.caml_alloc_array.restype = mod.ml_value
+    mod.context.caml_alloc_final.restype = mod.ml_value
+    mod.context.caml_convert_flag_list = ctypes.c_int
+
+    # callback.h
+    mod.context.caml_callback.restype = mod.ml_value
+    mod.context.caml_callback2.restype = mod.ml_value
+    mod.context.caml_callback3.restype = mod.ml_value
+    mod.context.caml_callbackN.restype = mod.ml_value
+    mod.context.caml_callback_exn.restype = mod.ml_value
+    mod.context.caml_callback2_exn.restype = mod.ml_value
+    mod.context.caml_callback3_exn.restype = mod.ml_value
+    mod.context.caml_callbackN_exn.restype = mod.ml_value
+    mod.context.caml_named_value.restype = mod.ml_value_p
+    mod.context.caml_main.restype = None
+    mod.context.caml_startup.restype = None
+
+    # custom.h
+    mod.context.caml_alloc_custom.restype = mod.ml_value
+    mod.context.caml_register_custom_operations.restype = None
+    #mod.context.caml_compare_unordered.restype = ctypes.c_int
+
+    # fail.h
+    mod.context.caml_raise.restype = None
+    mod.context.caml_raise_constant.restype = None
+    mod.context.caml_raise_with_arg.restype = None
+    mod.context.caml_raise_with_args.restype = None
+    mod.context.caml_raise_with_string.restype = None
+    mod.context.caml_failwith.restype = None
+    mod.context.caml_invalid_argument.restype = None
+    mod.context.caml_raise_out_of_memory.restype = None
+    mod.context.caml_raise_stack_overflow.restype = None
+    mod.context.caml_raise_sys_error.restype = None
+    mod.context.caml_raise_end_of_file.restype = None
+    mod.context.caml_raise_zero_divide.restype = None
+    mod.context.caml_raise_not_found.restype = None
+    #mod.context.caml_init_exceptions.restype = None
+    mod.context.caml_array_bound_error.restype = None
+    mod.context.caml_raise_sys_blocked_io.restype = None
+
+    # intext.h
+    # TODO
+
+    # memory.h
+    mod.context.caml_alloc_shr.restype = mod.ml_value
+    mod.context.caml_adjust_gc_speed.restype = None
+    mod.context.caml_alloc_dependent_memory.restype = None
+    mod.context.caml_free_dependent_memory.restype = None
+    mod.context.caml_modify.restype = None
+    mod.context.caml_initialize.restype = None
+    mod.context.caml_check_urgent_gc.restype = mod.ml_value
+    mod.context.caml_stat_alloc.restype = ctypes.c_void_p
+    mod.context.caml_stat_free.restype = None
+    mod.context.caml_stat_resize.restype = ctypes.c_void_p
+    mod.context.caml_register_global_root.restype = None
+    mod.context.caml_remove_global_root.restype = None
+    #mod.context.caml_register_generation_global_root.restype = None
+    #mod.context.caml_remove_generation_global_root.restype = None
+    #mod.context.caml_modify_generation_global_root.restype = None
+
+    # mlvalues.h
+    mod.context.caml_get_public_method.restype = mod.ml_value
+    #mod.context.caml_hash_variant.restype = mod.ml_value
+    mod.context.caml_string_length.restype = mod.ml_mlsize_t
+    #mod.context.caml_Double_val.restype = ctypes.c_double
+    #mod.context.caml_Store_double_val.restype = None
+    #mod.context.caml_Int64_val.restype = mod.ml_int64
+

otypes/template.py

+import sys
+import ctypes
+from functools import wraps
+
+#define No_scan_tag 251
+NO_SCAN_TAG = 251
+
+#define Closure_tag 247
+CLOSURE_TAG = 247
+
+#define String_tag 252
+STRING_TAG = 252
+
+#define Double_tag 253
+DOUBLE_TAG = 253
+
+#define Double_array_tag 254
+DOUBLE_ARRAY_TAG = 254
+
+#define Abstract_tag 251
+ABSTRACT_TAG = 251
+
+#define Custom_tag 255
+CUSTOM_TAG = 255
+
+#define Max_young_wosize 256
+MAX_YOUNG_WOSIZE = 256
+
+class ml_intnat(ctypes.c_long):
+    '''
+    typedef long intnat;
+    '''
+
+    def __repr__(self):
+        return 'ml_intnat({})'.format(self.value)
+
+ml_intnat_p = ctypes.POINTER(ml_intnat)
+
+class ml_uintnat(ctypes.c_ulong):
+    '''
+    typedef unsigned long uintnat;
+    '''
+
+    def __repr__(self):
+        return 'ml_uintnat({})'.format(self.value)
+
+class ml_value(ml_intnat):
+    '''
+    typedef intnat value;
+    '''
+
+    def __repr__(self):
+        return 'ml_value({})'.format(self.value)
+
+ml_value_p = ctypes.POINTER(ml_value)
+
+class ml_header_t(ml_uintnat):
+    '''
+    typedef uintnat header_t;
+    '''
+
+    def __repr__(self):
+        return 'ml_header_t({})'.format(self.value)
+
+ml_header_t_p = ctypes.POINTER(ml_header_t)
+
+class ml_mlsize_t(ml_uintnat):
+    '''
+    typedef uintnat mlsize_t;
+    '''
+
+    def __repr__(self):
+        return 'ml_size_t({})'.format(self.value)
+
+class ml_int32(ctypes.c_int):
+    '''
+    typedef int int32;
+    '''
+    
+    def __repr__(self):
+        return 'int32({})'.format(self.value)
+
+ml_int32_p = ctypes.POINTER(ml_int32)
+
+class ml_int64(ctypes.c_int64):
+    '''
+    '''
+
+    def __repr__(self):
+        return 'int64({})'.format(self.value)
+
+ml_int64_p = ctypes.POINTER(ml_int64)
+
+class ml_opcode_t(ml_int32):
+    '''
+    typedef int32 opcode_t;
+    '''
+    
+    def __repr__(self):
+        return 'opcode_t({})'.format(self.value)
+
+ml_code_t = ctypes.POINTER(ml_opcode_t)
+
+class caml__roots_block(ctypes.Structure):
+    pass
+
+caml__roots_block._fields_ = [
+    ('next', ctypes.POINTER(caml__roots_block)),
+    ('ntables', ml_intnat),
+    ('nitems', ml_intnat),
+    ('tables', ml_value_p * 5),
+]
+
+caml__roots_block_p = ctypes.POINTER(caml__roots_block)
+
+def caml_named_value(name):
+    '''
+    CAMLextern value * caml_named_value (char const * name);
+    '''
+    return context.caml_named_value(ctypes.c_char_p(name)).contents
+
+def caml_callback(*args):
+    '''
+    CAMLextern value caml_callback (value closure, value arg);
+    CAMLextern value caml_callback2 (value closure, value arg1, value arg2);
+    CAMLextern value caml_callback3 (value closure, value arg1, value arg2, value arg3);
+    CAMLextern value caml_callbackN (value closure, int narg, value args[]);
+    '''
+    narg = len(args) - 1
+    if narg == 1:
+        return context.caml_callback(*args)
+    elif narg == 2:
+        return context.caml_callback2(*args)
+    elif narg == 3:
+        return context.caml_callback3(*args)
+    elif narg > 3:
+        closure, args = args[0], args[1:]
+        values = (ml_value * narg)()
+        for i, v in enumerate(args):
+            values[i] = v
+        return context.caml_callbackN(closure, ctypes.c_int(narg), values)
+    else:
+        raise ValueError
+
+def caml_alloc(size, tag):
+    '''
+    CAMLextern value caml_alloc (mlsize_t, tag_t);
+    '''
+    return context.caml_alloc(size, tag)
+
+def caml_alloc_tuple(size):
+    '''
+    CAMLextern value caml_alloc_tuple (mlsize_t);
+    '''
+    return context.caml_alloc_tuple(size)
+
+def caml_alloc_string(size):
+    '''
+    CAMLextern value caml_alloc_string (mlsize_t);  /* size in bytes */
+    '''
+    return context.caml_alloc_string(size)
+
+def caml_copy_string(string):
+    '''
+    CAMLextern value caml_copy_string (char const *);
+    '''
+    return context.caml_copy_string(ctypes.c_char_p(string))
+
+def caml_copy_string_array(strings):
+    '''
+    CAMLextern value caml_copy_string_array (char const **);
+    '''
+    return context.caml_copy_string_array(strings) # TODO
+
+def caml_copy_double(f):
+    '''
+    CAMLextern value caml_copy_double (double);
+    '''
+    return context.caml_copy_double(ctypes.c_double(f))
+
+def caml_copy_int32(x):
+    '''
+    CAMLextern value caml_copy_int32 (int32);       /* defined in [ints.c] */
+    '''
+    return context.caml_copy_int32(ml_int32(x))
+
+def caml_copy_int64(x):
+    '''
+    CAMLextern value caml_copy_int64 (int64);       /* defined in [ints.c] */
+    '''
+    return context.caml_copy_int64(ml_int64(x))
+
+def caml_copy_nativeint(x):
+    '''
+    CAMLextern value caml_copy_nativeint (intnat);  /* defined in [ints.c] */
+    '''
+    return context.caml_copy_nativeint(ml_intnat(x))
+
+def caml_alloc_array(f, a):
+    '''
+    caml_alloc_array(f, a) allocates an array of values, calling function f over each element of input sequence a to transform it into a value.
+
+    CAMLextern value caml_alloc_array (value (*funct) (char const *), char const ** array);
+    '''
+    raise NotImplementedError
+
+def caml_copy_string_array(strings):
+    '''
+    caml_copy_string_array(p) allocates an array of strings, copied from Python strings.
+
+    CAMLextern value caml_copy_string_array (char const **);
+    '''
+    array = (ctypes.c_char_p * (len(strings) + 1))()
+    for i, string in enumerate(strings):
+        array[i] = string
+    array[-1] = None
+    return context.caml_copy_string_array(array)
+
+def caml_alloc_small(size, tag):
+    '''
+    caml_alloc_small(n, t) returns a fresh small block of size n <= Max_young_wosize words, with tag t.
+
+    CAMLextern value caml_alloc_small (mlsize_t, tag_t);
+    '''
+    return context.caml_alloc_small(size, tag)
+
+def caml_alloc_shr(size, tag):
+    '''
+    caml_alloc_shr(n, t) returns a fresh block of size n, with tag t.
+
+    CAMLextern value caml_alloc_shr (mlsize_t, tag_t);
+    '''
+    return context.caml_alloc_shr(size, tag)
+
+def caml_modify(dest, src):
+    return context.caml_modify(dest, src)
+
+def field(x, i):
+    '''
+    field(v, n) returns the value contained in the n th field of the structured block v.
+    Fields are numbered from 0 to wosize_val(v) - 1.
+
+    #define Field(x, i) (((value *)(x)) [i])           /* Also an l-value. */
+    '''
+    return ml_value_p.from_buffer(x)[i]
+
+def store_field(block, offset, val):
+    '''
+    store_field(b, n, v) stores the value v in the field number n of value b, which must be a structured block.
+    
+    #define Store_field(block, offset, val) do{ \\
+      mlsize_t caml__temp_offset = (offset); \\
+      value caml__temp_val = (val); \\
+      caml_modify (&Field ((block), caml__temp_offset), caml__temp_val); \\
+    }while(0)
+    '''
+    f = ml_value(block.value + ctypes.alignment(ml_value) * offset)
+    return context.caml_modify(f, val)
+
+def is_long(x):
+    '''
+    is_long(v) is True if value v is an immediate integer, False otherwise.
+
+    #define Is_long(x)   (((x) & 1) != 0)
+    '''
+    return (x.value & 1) != 0
+
+def is_block(x):
+    '''
+    is_block(v) is True if value v is a pointer to a block, and False if it is an immediate integer.
+
+    #define Is_block(x)  (((x) & 1) == 0)
+    '''
+    return (x.value & 1) == 0
+
+def val_int(x):
+    '''
+    val_int(i) returns the value encoding the Python integer object i.
+
+    #define Val_long(x)     (((intnat)(x) << 1) + 1)
+    #define Val_int(x) Val_long(x)
+    '''
+    return ml_value((x << 1) + 1)
+
+def int_val(x):
+    '''
+    int_val(v) returns the Python integer object encoding in value v.
+
+    #define Long_val(x)     ((x) >> 1)
+    #define Int_val(x) ((int) Long_val(x))
+    '''
+    return x.value >> 1
+
+def val_bool(x):
+    '''
+    val_bool(x) returns the Caml boolean representing the truth value of the Python object x.
+
+    #define Val_bool(x) Val_int((x) != 0)
+    '''
+    return val_true if x else val_false
+
+def bool_val(x):
+    '''
+    bool_val(v) returns True if v is the Caml boolean true, False if v is false.
+
+    #define Bool_val(x) Int_val(x)
+    '''
+    return bool(int_val(x))
+
+def store_double_val(v, d):
+    ctypes.c_double.from_address(v.value).value = d
+
+def double_val(v):
+    return ctypes.c_double.from_address(v.value).value
+
+def wosize_hd(hd):
+    '''
+    #define Wosize_val(val) (Wosize_hd (Hd_val (val)))
+    '''
+    return ml_mlsize_t(hd.value >> 10)
+
+def hd_val(val):
+    '''
+    #define Hd_val(val) (((header_t *) (val)) [-1])        /* Also an l-value. */
+    '''
+    return ml_header_t.from_address(val.value - ctypes.alignment(ml_header_t))
+
+def val_hp(hp):
+    '''
+    #define Val_hp(hp) ((value) (((header_t *) (hp)) + 1))
+    '''
+    return ml_value(ml_header_t.from_address(hp)[1].value)
+
+def wosize_val(val):
+    '''
+    wosize_val(v) returns the size of the block v, in words, excluding the header.
+
+    #define Wosize_val(val) (Wosize_hd (Hd_val (val)))
+    '''
+    return wosize_hd(hd_val(val)).value
+
+def tag_val(val):
+    '''
+    tag_val(v) returns the tag of the block v.
+
+    #ifdef ARCH_BIG_ENDIAN
+    #define Tag_val(val) (((unsigned char *) (val)) [-1]) /* Also an l-value. */
+    #else
+    #define Tag_val(val) (((unsigned char *) (val)) [-sizeof(value)]) /* Also an l-value. */
+    #endif
+    '''
+    p = ctypes.POINTER(ctypes.c_ubyte).from_buffer(val)
+    if sys.byteorder == 'big':
+        return p[-1]
+    else:
+        return p[-ctypes.alignment(val)]
+
+def code_val(val):
+    '''
+    code_val(v) returns the code part of the closure v.
+
+    #define Code_val(val) (((code_t *) (val)) [0])     /* Also an l-value. */
+    '''
+    return ctypes.POINTER(ml_code_t).from_buffer(val).contents
+
+def caml_string_length(v):
+    '''
+    caml_string_length(v) returns the length (number of characters) of the string v.
+
+    CAMLextern mlsize_t caml_string_length (value);   /* size in bytes */
+    '''
+    return context.caml_string_length(v).value
+
+def byte(v, n):
+    '''
+    byte(v, n) returns the n th character of the string v.
+    Characters are numbered from 0 to string_length(v) - 1.
+
+    #define Byte(x, i) (((char *) (x)) [i])            /* Also an l-value. */
+    '''
+    return ctypes.POINTER(ctypes.c_char).from_buffer(v)[n]
+
+def bp_val(v):
+    '''
+    #define Bp_val(v) ((char *) (v))
+    '''
+    return ctypes.c_char_p.from_buffer(v)
+
+def string_val(x):
+    '''
+    string_val(v) returns a Python string object of value v.
+
+    #define String_val(x) ((char *) Bp_val(x))
+    '''
+    return bp_val(x).value
+
+def double_val(v):
+    '''
+    double_val(v) returns the Python float object of value v.
+
+    #define Double_val(v) (* (double *)(v))
+    '''
+    return ctypes.c_double.from_address(v.value).value
+
+def double_field(v, i):
+    '''
+    double_field(v, n) returns the n th element of the array of floating-point numbers s (a block tagged DOUBLE_ARRAY_TAG).
+
+    #define Double_field(v,i) Double_val((value)((double *)(v) + (i)))
+    '''
+    return ctypes.POINTER(ctypes.c_double).from_buffer(v)[i]
+
+def store_double_field(v, i, d):
+    '''
+    store_double_field(v, n, d) stores the double precision floating-point number d in the n th element of the array of floating-point numbers v.
+
+    #define Store_double_field(v,i,d) do{ \\
+      mlsize_t caml__temp_i = (i); \\
+      double caml__temp_d = (d); \\
+      Store_double_val((value)((double *) (v) + caml__temp_i), caml__temp_d); \\
+    }while(0)
+    '''
+    ctypes.POINTER(ctypes.c_double).from_buffer(v)[i] = d
+
+def data_custom_val(v):
+    '''
+    data_custom_val(v) returns a pointer to the data part of the custom block v.
+    This pointer has type void * and must be cast to the type of the data contained in the custom block.
+
+    #define Data_custom_val(v) ((void *) &Field((v), 1))
+    '''
+    return ctypes.cast(ctypes.pointer(field(v, 1)), ctypes.c_void_p)
+
+def int32_val(v):
+    '''
+    int32_val(v) returns the Python integer object contained in the int32 v.
+
+    #define Int32_val(v) (*((int32 *) Data_custom_val(v)))
+    '''
+    return ctypes.cast(data_custom_val(v), ml_int32_p).contents.value
+
+def int64_val(v):
+    '''
+    int64_val(v) returns the Python integer object contained in the int64 v.
+
+    #ifndef ARCH_ALIGN_INT64
+    #define Int64_val(v) (*((int64 *) Data_custom_val(v)))
+    #else
+    CAMLextern int64 caml_Int64_val(value v);
+    #define Int64_val(v) caml_Int64_val(v)
+    #endif
+    '''
+    return ctypes.cast(data_custom_val(v), ml_int64_p).contents.value # TODO 32bit
+
+def nativeint_val(v):
+    '''
+    nativeint_val(v) returns the Python integer object contained in the nativeint v.
+
+    #define Nativeint_val(v) (*((intnat *) Data_custom_val(v)))
+    '''
+    return ctypes.cast(data_custom_val(v), ml_intnat_p).contents.value
+
+def atom(tag):
+    '''
+    atom(t) returns an "atom" (zero-sized block) with tag t.
+    Zero-sized blocks are preallocated outside of the heap.
+
+    #define Atom(tag) (Val_hp (&(caml_atom_table [(tag)])))
+    '''
+    return val_hp(caml_atom_table()[tag].address)
+
+def caml_xparam(*args):
+    roots = caml__roots_block()
+    roots.next = caml_local_roots()
+    caml_local_roots().contents = roots
+    roots.nitems = 1
+    roots.ntables = len(args)
+    for i,arg in enumerate(args):
+        roots.tables[i] = ctypes.pointer(arg)
+    return roots
+
+def caml_xparam_n(args):
+    roots = caml__roots_block()
+    local_roots = caml_local_roots()
+    roots.next = local_roots
+    local_roots.contents = roots
+    roots.nitems = len(args)
+    roots.ntables = 1
+    roots.tables[0] = args
+
+def caml_local(n):
+    if n > 5:
+        values = (ml_value * n)()
+        caml_xparam_n(values)
+        return values
+    else:
+        values = [ml_value(0) for _ in range(n)]
+        roots = caml_xparam(*values)
+        if n == 1:
+            return roots, values[0]
+        else:
+            return roots, values
+
+def caml_call(f):
+    @wraps(f)
+    def _caml_call(*args, **kw):
+        frame = caml__roots_block_p.from_buffer_copy(caml_local_roots())
+        res = f(*args, **kw)
+        if frame:
+            caml_local_roots().contents = frame.contents
+        else:
+            ctypes.c_long.from_buffer(caml_local_roots()).value = 0
+        return res
+    return _caml_call
+
+def caml_local_roots():
+    return caml__roots_block_p.in_dll(context, 'caml_local_roots')
+
+def caml_atom_table():
+    return ml_header_t_p.in_dll(context, 'caml_atom_table')
+
+def caml_garbage_collection():
+    context.caml_garbage_collection()
+
+def val_not(x):
+    '''
+    #define Val_not(x) (Val_false + Val_true - (x))
+    '''
+    return val_false if x else val_true
+
+val_unit = val_int(0)
+
+val_emptylist = val_int(0)
+
+#define Val_true Val_int(1)
+val_true = val_int(1)
+
+#define Val_false Val_int(0)
+val_false = val_int(0)
+
+def alloc_tuple(*args):
+    #@otypes.caml_call
+    def inner(*args):
+        #roots, ml_tuple = otypes.caml_local(1)
+        size = len(args)
+        ml_tuple = otypes.caml_alloc(size, 0)
+        for i,arg in enumerate(args):
+            otypes.store_field(ml_tuple, i, arg)
+        return ml_tuple
+    return inner(*args)
+
+def alloc_array(seq, f=lambda x: x):
+    @otypes.caml_call
+    def inner(seq, f):
+        roots, ml_array = otypes.caml_local(1)
+        size = len(seq)
+        ml_array.value = otypes.caml_alloc(size, 0).value
+        for i,item in enumerate(seq):
+            ml_item = f(item)
+            otypes.store_field(ml_array, i, ml_item)
+        return ml_array
+    return inner(seq, f)
+
+def alloc_list(seq, f=lambda x: x):
+    ml_next = otypes.val_emptylist()
+    for item in reversed(seq):
+        ml_item = f(item)
+        ml_next = alloc_tuple(ml_item, ml_next)
+    return ml_next
+
+def py_list_of_ml_list(ml_list, f=lambda x: x):
+    l = []
+    empty = otypes.val_emptylist().value
+    while ml_list.value != empty:
+        l.append(f(otypes.field(ml_list, 0)))
+        ml_list = otypes.field(ml_list, 1)
+    return l
+
+def py_list_of_ml_array(ml_array, f=lambda x: x):
+    size = ml_array_length(ml_array)
+    return [f(otypes.field(ml_array, i)) for i in range(size)]
+
+def py_list_of_ml_tuple(ml_tuple):
+    size = ml_tuple_size(ml_tuple)
+    return [otypes.field(ml_tuple, i) for i in range(size)]
+
+def ml_array_length(ml_array):
+    return otypes.wosize_val(ml_array)
+
+def ml_tuple_size(ml_tuple):
+    return otypes.wosize_val(ml_tuple)
+
-from setuptools import setup
+from setuptools import setup, find_packages
 
 setup(name='otypes',
       version='0.1.0',
       author='Yosuke ONOUE',
       author_email='onoue@likr-lab.com',
-      py_modules=['otypes', 'template'],
+      packages=find_packages(),
       test_suite='nose.collector',
       tests_require=['Nose'],
 )

template/__init__.py

Empty file removed.

template/otypes.py

-import sys
-import ctypes
-from functools import wraps
-
-#define No_scan_tag 251
-NO_SCAN_TAG = 251
-
-#define Closure_tag 247
-CLOSURE_TAG = 247
-
-#define String_tag 252
-STRING_TAG = 252
-
-#define Double_tag 253
-DOUBLE_TAG = 253
-
-#define Double_array_tag 254
-DOUBLE_ARRAY_TAG = 254
-
-#define Abstract_tag 251
-ABSTRACT_TAG = 251
-
-#define Custom_tag 255
-CUSTOM_TAG = 255
-
-#define Max_young_wosize 256
-MAX_YOUNG_WOSIZE = 256
-
-class ml_intnat(ctypes.c_long):
-    '''
-    typedef long intnat;
-    '''
-
-    def __repr__(self):
-        return 'ml_intnat({})'.format(self.value)
-
-ml_intnat_p = ctypes.POINTER(ml_intnat)
-
-class ml_uintnat(ctypes.c_ulong):
-    '''
-    typedef unsigned long uintnat;
-    '''
-
-    def __repr__(self):
-        return 'ml_uintnat({})'.format(self.value)
-
-class ml_value(ml_intnat):
-    '''
-    typedef intnat value;
-    '''
-
-    def __repr__(self):
-        return 'ml_value({})'.format(self.value)
-
-ml_value_p = ctypes.POINTER(ml_value)
-
-class ml_header_t(ml_uintnat):
-    '''
-    typedef uintnat header_t;
-    '''
-
-    def __repr__(self):
-        return 'ml_header_t({})'.format(self.value)
-
-ml_header_t_p = ctypes.POINTER(ml_header_t)
-
-class ml_mlsize_t(ml_uintnat):
-    '''
-    typedef uintnat mlsize_t;
-    '''
-
-    def __repr__(self):
-        return 'ml_size_t({})'.format(self.value)
-
-class ml_int32(ctypes.c_int):
-    '''
-    typedef int int32;
-    '''
-    
-    def __repr__(self):
-        return 'int32({})'.format(self.value)
-
-ml_int32_p = ctypes.POINTER(ml_int32)
-
-class ml_int64(ctypes.c_int64):
-    '''
-    '''
-
-    def __repr__(self):
-        return 'int64({})'.format(self.value)
-
-ml_int64_p = ctypes.POINTER(ml_int64)
-
-class ml_opcode_t(ml_int32):
-    '''
-    typedef int32 opcode_t;
-    '''
-    
-    def __repr__(self):
-        return 'opcode_t({})'.format(self.value)
-
-ml_code_t = ctypes.POINTER(ml_opcode_t)
-
-class caml__roots_block(ctypes.Structure):
-    pass
-
-caml__roots_block._fields_ = [
-    ('next', ctypes.POINTER(caml__roots_block)),
-    ('ntables', ml_intnat),
-    ('nitems', ml_intnat),
-    ('tables', ml_value_p * 5),
-]
-
-caml__roots_block_p = ctypes.POINTER(caml__roots_block)
-
-def caml_named_value(name):
-    '''
-    CAMLextern value * caml_named_value (char const * name);
-    '''
-    return context.caml_named_value(ctypes.c_char_p(name)).contents
-
-def caml_callback(*args):
-    '''
-    CAMLextern value caml_callback (value closure, value arg);
-    CAMLextern value caml_callback2 (value closure, value arg1, value arg2);
-    CAMLextern value caml_callback3 (value closure, value arg1, value arg2, value arg3);
-    CAMLextern value caml_callbackN (value closure, int narg, value args[]);
-    '''
-    narg = len(args) - 1
-    if narg == 1:
-        return context.caml_callback(*args)
-    elif narg == 2:
-        return context.caml_callback2(*args)
-    elif narg == 3:
-        return context.caml_callback3(*args)
-    elif narg > 3:
-        closure, args = args[0], args[1:]
-        values = (ml_value * narg)()
-        for i, v in enumerate(args):
-            values[i] = v
-        return context.caml_callbackN(closure, ctypes.c_int(narg), values)
-    else:
-        raise ValueError
-
-def caml_alloc(size, tag):
-    '''
-    CAMLextern value caml_alloc (mlsize_t, tag_t);
-    '''
-    return context.caml_alloc(size, tag)
-
-def caml_alloc_tuple(size):
-    '''
-    CAMLextern value caml_alloc_tuple (mlsize_t);
-    '''
-    return context.caml_alloc_tuple(size)
-
-def caml_alloc_string(size):
-    '''
-    CAMLextern value caml_alloc_string (mlsize_t);  /* size in bytes */
-    '''
-    return context.caml_alloc_string(size)
-
-def caml_copy_string(string):
-    '''
-    CAMLextern value caml_copy_string (char const *);
-    '''
-    return context.caml_copy_string(ctypes.c_char_p(string))
-
-def caml_copy_string_array(strings):
-    '''
-    CAMLextern value caml_copy_string_array (char const **);
-    '''
-    return context.caml_copy_string_array(strings) # TODO
-
-def caml_copy_double(f):
-    '''
-    CAMLextern value caml_copy_double (double);
-    '''
-    return context.caml_copy_double(ctypes.c_double(f))
-
-def caml_copy_int32(x):
-    '''
-    CAMLextern value caml_copy_int32 (int32);       /* defined in [ints.c] */
-    '''
-    return context.caml_copy_int32(ml_int32(x))
-
-def caml_copy_int64(x):
-    '''
-    CAMLextern value caml_copy_int64 (int64);       /* defined in [ints.c] */
-    '''
-    return context.caml_copy_int64(ml_int64(x))
-
-def caml_copy_nativeint(x):
-    '''
-    CAMLextern value caml_copy_nativeint (intnat);  /* defined in [ints.c] */
-    '''
-    return context.caml_copy_nativeint(ml_intnat(x))
-
-def caml_alloc_array(f, a):
-    '''
-    caml_alloc_array(f, a) allocates an array of values, calling function f over each element of input sequence a to transform it into a value.
-
-    CAMLextern value caml_alloc_array (value (*funct) (char const *), char const ** array);
-    '''
-    raise NotImplementedError
-
-def caml_copy_string_array(strings):
-    '''
-    caml_copy_string_array(p) allocates an array of strings, copied from Python strings.
-
-    CAMLextern value caml_copy_string_array (char const **);
-    '''
-    array = (ctypes.c_char_p * (len(strings) + 1))()
-    for i, string in enumerate(strings):
-        array[i] = string
-    array[-1] = None
-    return context.caml_copy_string_array(array)
-
-def caml_alloc_small(size, tag):
-    '''
-    caml_alloc_small(n, t) returns a fresh small block of size n <= Max_young_wosize words, with tag t.
-
-    CAMLextern value caml_alloc_small (mlsize_t, tag_t);
-    '''
-    return context.caml_alloc_small(size, tag)
-
-def caml_alloc_shr(size, tag):
-    '''
-    caml_alloc_shr(n, t) returns a fresh block of size n, with tag t.
-
-    CAMLextern value caml_alloc_shr (mlsize_t, tag_t);
-    '''
-    return context.caml_alloc_shr(size, tag)
-
-def caml_modify(dest, src):
-    return context.caml_modify(dest, src)
-
-def field(x, i):
-    '''
-    field(v, n) returns the value contained in the n th field of the structured block v.
-    Fields are numbered from 0 to wosize_val(v) - 1.
-
-    #define Field(x, i) (((value *)(x)) [i])           /* Also an l-value. */
-    '''
-    return ml_value_p.from_buffer(x)[i]
-
-def store_field(block, offset, val):
-    '''
-    store_field(b, n, v) stores the value v in the field number n of value b, which must be a structured block.
-    
-    #define Store_field(block, offset, val) do{ \\
-      mlsize_t caml__temp_offset = (offset); \\
-      value caml__temp_val = (val); \\
-      caml_modify (&Field ((block), caml__temp_offset), caml__temp_val); \\
-    }while(0)
-    '''
-    f = ml_value(block.value + ctypes.alignment(ml_value) * offset)
-    return context.caml_modify(f, val)
-
-def is_long(x):
-    '''
-    is_long(v) is True if value v is an immediate integer, False otherwise.
-
-    #define Is_long(x)   (((x) & 1) != 0)
-    '''
-    return (x.value & 1) != 0
-
-def is_block(x):
-    '''
-    is_block(v) is True if value v is a pointer to a block, and False if it is an immediate integer.
-
-    #define Is_block(x)  (((x) & 1) == 0)
-    '''
-    return (x.value & 1) == 0
-
-def val_int(x):
-    '''
-    val_int(i) returns the value encoding the Python integer object i.
-
-    #define Val_long(x)     (((intnat)(x) << 1) + 1)
-    #define Val_int(x) Val_long(x)
-    '''
-    return ml_value((x << 1) + 1)
-
-def int_val(x):
-    '''
-    int_val(v) returns the Python integer object encoding in value v.
-
-    #define Long_val(x)     ((x) >> 1)
-    #define Int_val(x) ((int) Long_val(x))
-    '''
-    return x.value >> 1
-
-def val_bool(x):
-    '''
-    val_bool(x) returns the Caml boolean representing the truth value of the Python object x.
-
-    #define Val_bool(x) Val_int((x) != 0)
-    '''
-    return val_true if x else val_false
-
-def bool_val(x):
-    '''
-    bool_val(v) returns True if v is the Caml boolean true, False if v is false.
-
-    #define Bool_val(x) Int_val(x)
-    '''
-    return bool(int_val(x))
-
-def store_double_val(v, d):
-    ctypes.c_double.from_address(v.value).value = d
-
-def double_val(v):
-    return ctypes.c_double.from_address(v.value).value
-
-def wosize_hd(hd):
-    '''
-    #define Wosize_val(val) (Wosize_hd (Hd_val (val)))
-    '''
-    return ml_mlsize_t(hd.value >> 10)
-
-def hd_val(val):
-    '''
-    #define Hd_val(val) (((header_t *) (val)) [-1])        /* Also an l-value. */
-    '''
-    return ml_header_t.from_address(val.value - ctypes.alignment(ml_header_t))
-
-def val_hp(hp):
-    '''
-    #define Val_hp(hp) ((value) (((header_t *) (hp)) + 1))
-    '''
-    return ml_value(ml_header_t.from_address(hp)[1].value)
-
-def wosize_val(val):
-    '''
-    wosize_val(v) returns the size of the block v, in words, excluding the header.
-
-    #define Wosize_val(val) (Wosize_hd (Hd_val (val)))
-    '''
-    return wosize_hd(hd_val(val)).value
-
-def tag_val(val):
-    '''
-    tag_val(v) returns the tag of the block v.
-
-    #ifdef ARCH_BIG_ENDIAN
-    #define Tag_val(val) (((unsigned char *) (val)) [-1]) /* Also an l-value. */
-    #else
-    #define Tag_val(val) (((unsigned char *) (val)) [-sizeof(value)]) /* Also an l-value. */
-    #endif
-    '''
-    p = ctypes.POINTER(ctypes.c_ubyte).from_buffer(val)
-    if sys.byteorder == 'big':
-        return p[-1]
-    else:
-        return p[-ctypes.alignment(val)]
-
-def code_val(val):
-    '''
-    code_val(v) returns the code part of the closure v.
-
-    #define Code_val(val) (((code_t *) (val)) [0])     /* Also an l-value. */
-    '''
-    return ctypes.POINTER(ml_code_t).from_buffer(val).contents
-
-def caml_string_length(v):
-    '''
-    caml_string_length(v) returns the length (number of characters) of the string v.
-
-    CAMLextern mlsize_t caml_string_length (value);   /* size in bytes */
-    '''
-    return context.caml_string_length(v).value
-
-def byte(v, n):
-    '''
-    byte(v, n) returns the n th character of the string v.
-    Characters are numbered from 0 to string_length(v) - 1.
-
-    #define Byte(x, i) (((char *) (x)) [i])            /* Also an l-value. */
-    '''
-    return ctypes.POINTER(ctypes.c_char).from_buffer(v)[n]
-
-def bp_val(v):
-    '''
-    #define Bp_val(v) ((char *) (v))
-    '''
-    return ctypes.c_char_p.from_buffer(v)
-
-def string_val(x):
-    '''
-    string_val(v) returns a Python string object of value v.
-
-    #define String_val(x) ((char *) Bp_val(x))
-    '''
-    return bp_val(x).value
-
-def double_val(v):
-    '''
-    double_val(v) returns the Python float object of value v.
-
-    #define Double_val(v) (* (double *)(v))
-    '''
-    return ctypes.c_double.from_address(v.value).value
-
-def double_field(v, i):
-    '''
-    double_field(v, n) returns the n th element of the array of floating-point numbers s (a block tagged DOUBLE_ARRAY_TAG).
-
-    #define Double_field(v,i) Double_val((value)((double *)(v) + (i)))
-    '''
-    return ctypes.POINTER(ctypes.c_double).from_buffer(v)[i]
-
-def store_double_field(v, i, d):
-    '''
-    store_double_field(v, n, d) stores the double precision floating-point number d in the n th element of the array of floating-point numbers v.
-
-    #define Store_double_field(v,i,d) do{ \\
-      mlsize_t caml__temp_i = (i); \\
-      double caml__temp_d = (d); \\
-      Store_double_val((value)((double *) (v) + caml__temp_i), caml__temp_d); \\
-    }while(0)
-    '''
-    ctypes.POINTER(ctypes.c_double).from_buffer(v)[i] = d
-
-def data_custom_val(v):
-    '''
-    data_custom_val(v) returns a pointer to the data part of the custom block v.
-    This pointer has type void * and must be cast to the type of the data contained in the custom block.
-
-    #define Data_custom_val(v) ((void *) &Field((v), 1))
-    '''
-    return ctypes.cast(ctypes.pointer(field(v, 1)), ctypes.c_void_p)
-
-def int32_val(v):
-    '''
-    int32_val(v) returns the Python integer object contained in the int32 v.
-
-    #define Int32_val(v) (*((int32 *) Data_custom_val(v)))
-    '''
-    return ctypes.cast(data_custom_val(v), ml_int32_p).contents.value
-
-def int64_val(v):
-    '''
-    int64_val(v) returns the Python integer object contained in the int64 v.
-
-    #ifndef ARCH_ALIGN_INT64
-    #define Int64_val(v) (*((int64 *) Data_custom_val(v)))
-    #else
-    CAMLextern int64 caml_Int64_val(value v);
-    #define Int64_val(v) caml_Int64_val(v)
-    #endif
-    '''
-    return ctypes.cast(data_custom_val(v), ml_int64_p).contents.value # TODO 32bit
-
-def nativeint_val(v):
-    '''
-    nativeint_val(v) returns the Python integer object contained in the nativeint v.
-
-    #define Nativeint_val(v) (*((intnat *) Data_custom_val(v)))
-    '''
-    return ctypes.cast(data_custom_val(v), ml_intnat_p).contents.value
-
-def atom(tag):
-    '''
-    atom(t) returns an "atom" (zero-sized block) with tag t.
-    Zero-sized blocks are preallocated outside of the heap.
-
-    #define Atom(tag) (Val_hp (&(caml_atom_table [(tag)])))
-    '''
-    return val_hp(caml_atom_table()[tag].address)
-
-def caml_xparam(*args):
-    roots = caml__roots_block()
-    roots.next = caml_local_roots()
-    caml_local_roots().contents = roots
-    roots.nitems = 1
-    roots.ntables = len(args)
-    for i,arg in enumerate(args):
-        roots.tables[i] = ctypes.pointer(arg)
-    return roots
-
-def caml_xparam_n(args):
-    roots = caml__roots_block()
-    local_roots = caml_local_roots()
-    roots.next = local_roots
-    local_roots.contents = roots
-    roots.nitems = len(args)
-    roots.ntables = 1
-    roots.tables[0] = args
-
-def caml_local(n):
-    if n > 5:
-        values = (ml_value * n)()
-        caml_xparam_n(values)
-        return values
-    else:
-        values = [ml_value(0) for _ in range(n)]
-        roots = caml_xparam(*values)
-        if n == 1:
-            return roots, values[0]
-        else:
-            return roots, values
-
-def caml_call(f):
-    @wraps(f)
-    def _caml_call(*args, **kw):
-        frame = caml__roots_block_p.from_buffer_copy(caml_local_roots())
-        res = f(*args, **kw)
-        if frame:
-            caml_local_roots().contents = frame.contents
-        else:
-            ctypes.c_long.from_buffer(caml_local_roots()).value = 0
-        return res
-    return _caml_call
-
-def caml_local_roots():
-    return caml__roots_block_p.in_dll(context, 'caml_local_roots')
-
-def caml_atom_table():
-    return ml_header_t_p.in_dll(context, 'caml_atom_table')
-
-def caml_garbage_collection():
-    context.caml_garbage_collection()
-
-def val_not(x):
-    '''
-    #define Val_not(x) (Val_false + Val_true - (x))
-    '''
-    return val_false if x else val_true
-
-val_unit = val_int(0)
-
-val_emptylist = val_int(0)
-
-#define Val_true Val_int(1)
-val_true = val_int(1)
-
-#define Val_false Val_int(0)
-val_false = val_int(0)
-

template/util.py

-def alloc_tuple(*args):
-    #@otypes.caml_call
-    def inner(*args):
-        #roots, ml_tuple = otypes.caml_local(1)
-        size = len(args)
-        ml_tuple = otypes.caml_alloc(size, 0)
-        for i,arg in enumerate(args):
-            otypes.store_field(ml_tuple, i, arg)
-        return ml_tuple
-    return inner(*args)
-
-def alloc_array(seq, f=lambda x: x):
-    @otypes.caml_call
-    def inner(seq, f):
-        roots, ml_array = otypes.caml_local(1)
-        size = len(seq)
-        ml_array.value = otypes.caml_alloc(size, 0).value
-        for i,item in enumerate(seq):
-            ml_item = f(item)
-            otypes.store_field(ml_array, i, ml_item)
-        return ml_array
-    return inner(seq, f)
-
-def alloc_list(seq, f=lambda x: x):
-    ml_next = otypes.val_emptylist()
-    for item in reversed(seq):
-        ml_item = f(item)
-        ml_next = alloc_tuple(ml_item, ml_next)
-    return ml_next
-
-def py_list_of_ml_list(ml_list, f=lambda x: x):
-    l = []
-    empty = otypes.val_emptylist().value
-    while ml_list.value != empty:
-        l.append(f(otypes.field(ml_list, 0)))
-        ml_list = otypes.field(ml_list, 1)
-    return l
-
-def py_list_of_ml_array(ml_array, f=lambda x: x):
-    size = ml_array_length(ml_array)
-    return [f(otypes.field(ml_array, i)) for i in range(size)]
-
-def py_list_of_ml_tuple(ml_tuple):
-    size = ml_tuple_size(ml_tuple)
-    return [otypes.field(ml_tuple, i) for i in range(size)]
-
-def ml_array_length(ml_array):
-    return otypes.wosize_val(ml_array)
-
-def ml_tuple_size(ml_tuple):
-    return otypes.wosize_val(ml_tuple)
-