Skip to content

Instantly share code, notes, and snippets.

@shhyou
Last active July 25, 2017 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shhyou/e424424236d1bc685fa002192221c29b to your computer and use it in GitHub Desktop.
Save shhyou/e424424236d1bc685fa002192221c29b to your computer and use it in GitHub Desktop.
Attempt to embed Racket v6.9
#lang racket/base
(provide (all-defined-out))
(define (binding-to-a-function x)
(list "this is in a function with" x "being the first argument"))
(printf "In Racket: module instantiated: ~s\n" (binding-to-a-function 'arg))
(define a-value 12354)
;; By default, this should print 12354
a-value
/*
raco ctool --cgc --c-mods base.c ++lib racket/base ++lib racket/base/lang/reader ++lib racket/runtime-config
g++ -framework Foundation -I<RACKET-SRC-PATH>/racket/include -L<RACKET-SRC-PATH>/racket/src/build/racket -L<RACKET-SRC-PATH>/racket/src/build/rktio call_racket.cpp -o call_racket -lracket -lmzgc -lrktio -liconv
./call_racket "<RACKET-SRC-PATH>/racket/collects"
*/
#include <scheme.h>
#include <iostream>
#include "base.c"
static int run(Scheme_Env *e, int argc, char *argv[])
{
Scheme_Object *curout;
int i;
Scheme_Thread *th;
mz_jmp_buf * volatile save, fresh;
/* Declare embedded modules in "base.c": */
declare_modules(e);
scheme_namespace_require(scheme_intern_symbol("racket/base"));
curout = scheme_get_param(scheme_current_config(),
MZCONFIG_OUTPUT_PORT);
th = scheme_get_current_thread();
Scheme_Object *path = scheme_make_path(argv[1]);
{
scheme_set_collects_path(path);
/*
// init collection paths with `((dynamic-require 'racket/base 'list) argv-1)
Scheme_Object *rkt_list_sym[2], *args[1];
rkt_list_sym[0] = scheme_intern_symbol("racket/base");
rkt_list_sym[1] = scheme_intern_symbol("list");
args[0] = path;
Scheme_Object *paths = scheme_apply(scheme_dynamic_require(2, rkt_list_sym), 1, args);
scheme_init_collection_paths(e, paths);
*/
scheme_init_collection_paths(e, scheme_null);
}
save = th->error_buf;
th->error_buf = &fresh;
if (scheme_setjmp(*th->error_buf)) {
th->error_buf = save;
return -1; /* There was an error */
} else {
std::cout << "Trying to load file from \"a-module.rkt\"\n";
Scheme_Object *load_result = scheme_load("a-module.rkt");
scheme_display(load_result, curout);
scheme_display(scheme_make_char('\n'), curout);
// Instantiate the loaded module
std::cout << "\nIn cpp: Instantiating the loaded module, `a-module`:\n";
scheme_eval_string("(dynamic-require ''a-module #f)", e);
// Instead of scheme_eval_string, we can also built the S-expression of
// (list 'quote 'a-module) then use scheme_dynamic_require
std::cout << "\nIn cpp: get the value of `a-value`:\n";
Scheme_Object *a_value = scheme_eval_string("(dynamic-require ''a-module 'a-value)", e);
std::cout << "a-value is " << SCHEME_INT_VAL(a_value) << "\n";
th->error_buf = save;
}
return 0;
}
int main(int argc, char **argv) {
std::cout << "In cpp main\n";
return scheme_main_setup(1, run, argc, argv);
}
// remember to add "load-file.rkt" in raco ctool
// raco ctool --cgc --c-mods base.c ++lib racket/base ++lib racket/base/lang/reader ++lib racket/runtime-config load-file.rkt
// then we can `(dynamic-require ''load-file 'my-load-file)` to use that function
save = th->error_buf;
th->error_buf = &fresh;
if (scheme_setjmp(*th->error_buf)) {
th->error_buf = save;
return -1; /* There was an error */
} else {
std::cout << "Trying to load file from \"a-module.rkt\"\n";
Scheme_Object *my_load_path[2];
my_load_path[0] = scheme_make_pair(
scheme_intern_symbol("quote"),
scheme_make_pair(
scheme_intern_symbol("load-file"),
scheme_make_null()));
my_load_path[1] = scheme_intern_symbol("my-load-file");
Scheme_Object *my_load = scheme_dynamic_require(2, my_load_path);
Scheme_Object *load_args[1];
load_args[0] = scheme_make_utf8_string("a-module.rkt");
Scheme_Object *unused = scheme_apply(my_load, 1, load_args);
th->error_buf = save;
}
#lang racket/base
(require syntax/modread)
(provide my-load-file)
(define (my-load-file path)
(define my-module
(with-input-from-file path
(lambda ()
(with-module-reading-parameterization
(lambda ()
(read-syntax path))))))
(define my-module-name
(syntax-case my-module ()
[(_ name _ ...)
(syntax-e #'name)]))
(define my-module-fixed
(syntax-case my-module ()
[(_ name forms ...)
#`(#,#'module name forms ...)]))
(define base-ns
(make-base-empty-namespace))
(parameterize ([current-namespace base-ns])
(eval my-module-fixed)
;; instantiate the loaded module here
(displayln "In my load library:")
(dynamic-require `',my-module-name #f)))
$ raco ctool --cgc --c-mods base.c ++lib racket/base ++lib racket/base/lang/reader ++lib racket/runtime-config
$ g++ -framework Foundation -I<RACKET-SRC-PATH>/racket/include -L<RACKET-SRC-PATH>/racket/src/build/racket -L<RACKET-SRC-PATH>/racket/src/build/rktio call_racket.cpp -o call_racket -lracket -lmzgc -lrktio -liconv
ld: warning: could not create compact unwind for _ffi_call_unix64: does not use RBP or RSP based frame
$ ./call_racket "<RACKET-SRC-PATH>/racket/collects"
In cpp main
Trying to load file from "a-module.rkt"
#<void>
In cpp: Instantiating the loaded module, `a-module`:
In Racket: module instantiated: ("this is in a function with" arg "being the first argument")
12354
In cpp: get the value of `a-value`:
a-value is 12354
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment