<commit_before>/*
 * SchemePrimitive.cc
 *
 * Allow C++ code to be invoked from scheme --
 * by defining a scheme primitive function.
 *
 * Copyright (C) 2009, 2014, 2015 <NAME>
 */

#include <exception>

#include "SchemeEval.h"
#include "SchemePrimitive.h"
#include "SchemeSmob.h"

using namespace opencog;

bool PrimitiveEnviron::is_inited = false;

#ifdef HAVE_GUILE2
 #define C(X) ((scm_t_subr) X)
#else
 #define C(X) ((SCM (*) ()) X)
#endif


/**
 * initialization code -- This is currently called under a
 * lock, from SchemeEval::init()
 */
void PrimitiveEnviron::init(void)
{
	if (is_inited) return;
	is_inited = true;
	scm_c_define_module("opencog extension", init_in_module, NULL);

	// Use, immediately after define. Kind of hacky-ish, but assorted
	// C++ code will fail if they forget to use: so we use it, for them.
	scm_c_use_module("opencog extension");
}

/// This is called while (opencog extension) is the current module.
/// Thus, opencog-extension is only defined in that module.
void PrimitiveEnviron::init_in_module(void*)
{
	scm_c_define_gsubr("opencog-extension", 2,0,0, C(do_call));

	// Export, because other modules will need to call this directly.
	scm_c_export("opencog-extension", NULL);
}

PrimitiveEnviron::~PrimitiveEnviron() {}

void PrimitiveEnviron::do_register(const char * module,
                                   const char *name, int nargs)
{
	// Now enter guile mode, and do the actual work there.
	tmp_module = module;
	tmp_name = name;
	tmp_nargs = nargs;
	scm_with_guile(c_wrap_register, this);
}

void *PrimitiveEnviron::c_wrap_register(void *p)
{
	PrimitiveEnviron *self = (PrimitiveEnviron *) p;
	self->really_do_register(self->tmp_module, self->tmp_name, self->tmp_nargs);
	return NULL;
}

/**
 * Create a new smob that will store a pointer to "this", which, in
 * turn, holds a pointer to the C++ instance and the C++ method to be
 * invoked, when its called from scheme.  The evaluation of the scheme
 * function will actually end up calling "opencog-extension", which
 * passes this smob to do_call(). It will be do_call that then calls
 * the actual C++ function.
 *
 * Note that this method must be called in "guile mode".
 */
void
PrimitiveEnviron::really_do_register(const char * module_name,
                                     const char *name, int nargs)
{
	init();

	// Scheme garbage collection will be managing the lifecycle
	scm_gc_register_collectable_memory (this, get_size(),
	                                    "opencog primitive environ");

	// The (opencog extension) module
	std::string modn = "opencog ";
	modn += module_name;
	SCM module = scm_c_define_module(modn.c_str(), NULL, NULL);

	// The smob will hold a pointer to "this" -- the PrimitiveEnviron
	SCM smob;<commit_msg>guile: uses the newly defined module<commit_after>/*
 * SchemePrimitive.cc
 *
 * Allow C++ code to be invoked from scheme --
 * by defining a scheme primitive function.
 *
 * Copyright (C) 2009, 2014, 2015 <NAME>
 */

#include <exception>

#include "SchemeEval.h"
#include "SchemePrimitive.h"
#include "SchemeSmob.h"

using namespace opencog;

bool PrimitiveEnviron::is_inited = false;

#ifdef HAVE_GUILE2
 #define C(X) ((scm_t_subr) X)
#else
 #define C(X) ((SCM (*) ()) X)
#endif


/**
 * initialization code -- This is currently called under a
 * lock, from SchemeEval::init()
 */
void PrimitiveEnviron::init(void)
{
	if (is_inited) return;
	is_inited = true;
	scm_c_define_module("opencog extension", init_in_module, NULL);

	// Use, immediately after define. Kind of hacky-ish, but assorted
	// C++ code will fail if they forget to use: so we use it, for them.
	scm_c_use_module("opencog extension");
}

/// This is called while (opencog extension) is the current module.
/// Thus, opencog-extension is only defined in that module.
void PrimitiveEnviron::init_in_module(void*)
{
	scm_c_define_gsubr("opencog-extension", 2,0,0, C(do_call));

	// Export, because other modules will need to call this directly.
	scm_c_export("opencog-extension", NULL);
}

PrimitiveEnviron::~PrimitiveEnviron() {}

void PrimitiveEnviron::do_register(const char * module,
                                   const char *name, int nargs)
{
	// Now enter guile mode, and do the actual work there.
	tmp_module = module;
	tmp_name = name;
	tmp_nargs = nargs;
	scm_with_guile(c_wrap_register, this);
}

void *PrimitiveEnviron::c_wrap_register(void *p)
{
	PrimitiveEnviron *self = (PrimitiveEnviron *) p;
	self->really_do_register(self->tmp_module, self->tmp_name, self->tmp_nargs);
	return NULL;
}

/**
 * Create a new smob that will store a pointer to "this", which, in
 * turn, holds a pointer to the C++ instance and the C++ method to be
 * invoked, when its called from scheme.  The evaluation of the scheme
 * function will actually end up calling "opencog-extension", which
 * passes this smob to do_call(). It will be do_call that then calls
 * the actual C++ function.
 *
 * Note that this method must be called in "guile mode".
 */
void
PrimitiveEnviron::really_do_register(const char * module_name,
                                     const char *name, int nargs)
{
	init();

	// Scheme garbage collection will be managing the lifecycle
	scm_gc_register_collectable_memory (this, get_size(),
	                                    "opencog primitive environ");

	// The (opencog extension) module
	std::string modn = "opencog ";
	modn += module_name;
	SCM module = scm_c_define_module(modn.c_str(), NULL, NULL);
    scm_c_use_module(modn.c_str());

	// The smob will hold a pointer to "this" -- the PrimitiveEnviron
	SCM smob;
{'fraction_non_alphanumeric': 0.11159029649595688, 'fraction_numerical': 0.005750224618149146, 'mean_word_length': 3.7410562180579214, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3375918', 'n_tokens_mistral': 1850, 'n_tokens_neox': 1810, 'n_words': 591}