Skip to content

Commit

Permalink
add vector operations (size & indexing) to API
Browse files Browse the repository at this point in the history
  • Loading branch information
aaptel committed Nov 2, 2015
1 parent fb049a1 commit 016e8b6
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 0 deletions.
18 changes: 18 additions & 0 deletions modules/modt-vector/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

ROOT = ../..

CC = gcc
LD = gcc
CFLAGS = -ggdb3 -Wall
LDFLAGS =

all: modt-vector.so modt-vector.doc

%.so: %.o
$(CC) -shared $(LDFLAGS) -o $@ $<

%.o: %.c
gcc $(CFLAGS) -I$(ROOT)/src -fPIC -c $<

%.doc: %.c
$(ROOT)/lib-src/make-docfile $< > $@
56 changes: 56 additions & 0 deletions modules/modt-vector/modt-vector.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

#include <emacs_module.h>

int plugin_is_GPL_compatible;

static emacs_value Fmodt_vector_fill (emacs_env *env, int nargs, emacs_value args[], void *data)
{
size_t i;
emacs_value vec = args[0];
emacs_value val = args[1];
const size_t size = env->vec_size (env, vec);
for (i = 0; i < size; i++)
env->vec_set (env, vec, i, val);
return env->intern (env, "t");
}

static emacs_value Fmodt_vector_eq (emacs_env *env, int nargs, emacs_value args[], void *data)
{
size_t i;
emacs_value vec = args[0];
emacs_value val = args[1];
const size_t size = env->vec_size (env, vec);
for (i = 0; i < size; i++)
if (!env->eq (env, env->vec_get (env, vec, i), val))
return env->intern (env, "nil");
return env->intern (env, "t");
}

/* Binds NAME to FUN */
static void bind_function (emacs_env *env, const char *name, emacs_value Sfun)
{
emacs_value Qfset = env->intern (env, "fset");
emacs_value Qsym = env->intern (env, name);
emacs_value args[] = { Qsym, Sfun };

env->funcall (env, Qfset, 2, args);
}

/* Provide FEATURE to Emacs */
static void provide (emacs_env *env, const char *feature)
{
emacs_value Qfeat = env->intern (env, feature);
emacs_value Qprovide = env->intern (env, "provide");
emacs_value args[] = { Qfeat };

env->funcall (env, Qprovide, 1, args);
}

int emacs_module_init (struct emacs_runtime *ert)
{
emacs_env *env = ert->get_environment (ert);
bind_function (env, "modt-vector-fill", env->make_function (env, 2, 2, Fmodt_vector_fill, NULL));
bind_function (env, "modt-vector-eq", env->make_function (env, 2, 2, Fmodt_vector_eq, NULL));
provide (env, "modt-vector");
return 0;
}
23 changes: 23 additions & 0 deletions modules/modt-vector/test.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

(require 'ert)
(require 'module-test-common)

;; #$ works when loading, buffer-file-name when evaluating from emacs
(module-load (module-path (or #$ (expand-file-name (buffer-file-name)))))

(ert-deftest modt-vector-test ()
(dolist (s '(2 10 100 1000))
(dolist (e '(42 foo "foo"))
(let* ((v-ref (make-vector 2 e))
(eq-ref (eq (aref v-ref 0) (aref v-ref 1)))
(v-test (make-vector s nil)))

(should (eq (modt-vector-fill v-test e) t))
(should (eq (modt-vector-eq v-test e) eq-ref))))))







15 changes: 15 additions & 0 deletions src/emacs_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,21 @@ struct emacs_env_25 {
void (*set_user_ptr_finalizer)(emacs_env *env,
emacs_value uptr,
void (*fin)(void *) EMACS_NOEXCEPT);

/*
* Vector functions
*/
emacs_value (*vec_get) (emacs_env *env,
emacs_value vec,
size_t i);

void (*vec_set) (emacs_env *env,
emacs_value vec,
size_t i,
emacs_value val);

size_t (*vec_size) (emacs_env *env,
emacs_value vec);
};

EMACS_EXTERN_C_END
Expand Down
63 changes: 63 additions & 0 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ static void module_wrong_type (emacs_env *env, Lisp_Object predicate, Lisp_Objec
/* Signal an out-of-memory condition to the caller. */
static void module_out_of_memory (emacs_env *env);

/* Signal arguments are out of range. */
static void module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2);


/* Value conversion */

Expand Down Expand Up @@ -674,6 +677,58 @@ static void module_set_user_ptr_finalizer (emacs_env *env,
XUSER_PTR (lisp)->finalizer = fin;
}

static void module_vec_set (emacs_env *env,
emacs_value vec,
size_t i,
emacs_value val)
{
check_main_thread ();
Lisp_Object lvec = value_to_lisp (vec);
if (! VECTORP (lvec))
{
module_wrong_type (env, Qvectorp, lvec);
return;
}
if (i >= ASIZE (lvec))
{
module_args_out_of_range (env, lvec, make_number (i));
return;
}
ASET (lvec, i, value_to_lisp (val));
}

static emacs_value module_vec_get (emacs_env *env,
emacs_value vec,
size_t i)
{
check_main_thread ();
Lisp_Object lvec = value_to_lisp (vec);
if (! VECTORP (lvec))
{
module_wrong_type (env, Qvectorp, lvec);
return lisp_to_value (env, Qnil);
}
if (i >= ASIZE (lvec))
{
module_args_out_of_range (env, lvec, make_number (i));
return lisp_to_value (env, Qnil);
}
return lisp_to_value (env, AREF (lvec, i));
}

static size_t module_vec_size (emacs_env *env,
emacs_value vec)
{
check_main_thread ();
Lisp_Object lvec = value_to_lisp (vec);
if (! VECTORP (lvec))
{
module_wrong_type (env, Qvectorp, lvec);
return 0;
}
return (size_t) ASIZE (lvec);
}


/* Subroutines */

Expand Down Expand Up @@ -817,6 +872,11 @@ static void module_out_of_memory (emacs_env *env)
module_error_signal_1 (env, XCAR (Vmemory_signal_data), XCDR (Vmemory_signal_data));
}

static void module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2)
{
module_error_signal_1 (env, Qargs_out_of_range, list2 (a1, a2));
}


/* Value conversion */

Expand Down Expand Up @@ -909,6 +969,9 @@ static void initialize_environment (struct env_storage *env)
env->pub.set_user_ptr_ptr = module_set_user_ptr_ptr;
env->pub.get_user_ptr_finalizer = module_get_user_ptr_finalizer;
env->pub.set_user_ptr_finalizer = module_set_user_ptr_finalizer;
env->pub.vec_set = module_vec_set;
env->pub.vec_get = module_vec_get;
env->pub.vec_size = module_vec_size;
}

static void finalize_environment (struct env_storage *env)
Expand Down

0 comments on commit 016e8b6

Please sign in to comment.