1 | Date: Mon, 14 Feb 2000 11:49:27 GMT |
---|
2 | From: John Harper <john@dcs.warwick.ac.uk> |
---|
3 | To: "Mikolaj J. Habryn" <dichro-mail-682f458@rcpt.to> |
---|
4 | Subject: Re: embedding librep |
---|
5 | |
---|
6 | Mikolaj J. Habryn writes: |
---|
7 | | Hi John - do you have any simple examples of using librep in an |
---|
8 | |inferior role? I need a scripting interface for a program that I'm |
---|
9 | |writing, and I'd much rather re-use somebody else's code :) Is there |
---|
10 | |anything other than sawmill (or presumably jade) that I could squint |
---|
11 | |at and try to understand? |
---|
12 | |
---|
13 | the simplest (and only other) example is rep.c in librep/src, it's not |
---|
14 | commented so here's a slightly simplified annotated version (from cvs |
---|
15 | librep) |
---|
16 | |
---|
17 | #include <rep.h> |
---|
18 | |
---|
19 | static repv |
---|
20 | inner_main (repv arg) |
---|
21 | { |
---|
22 | -- this boots the lisp environment, then loads the rep.jl[c] script |
---|
23 | |
---|
24 | return rep_load_environment (rep_string_dup ("rep")); |
---|
25 | } |
---|
26 | |
---|
27 | int |
---|
28 | main(int argc, char **argv) |
---|
29 | { |
---|
30 | char *prog_name = *argv++; |
---|
31 | argc--; |
---|
32 | |
---|
33 | -- this initialises the lisp data structures |
---|
34 | |
---|
35 | rep_init (prog_name, &argc, &argv, 0, 0); |
---|
36 | |
---|
37 | if (rep_get_option ("--version", 0)) |
---|
38 | { |
---|
39 | printf ("rep version %s\n", REP_VERSION); |
---|
40 | return 0; |
---|
41 | } |
---|
42 | |
---|
43 | -- this function is complex, it creates an execution context |
---|
44 | then calls inner_main from within this new context. It's |
---|
45 | needed because new librep does continuations and (soft) |
---|
46 | threading |
---|
47 | |
---|
48 | rep_call_with_barrier (inner_main, Qnil, rep_TRUE, 0, 0, 0); |
---|
49 | |
---|
50 | -- this function just checks if an error occurred, if so it |
---|
51 | will print some descriptive message, and returns a suitable |
---|
52 | exit code |
---|
53 | |
---|
54 | return rep_top_level_exit (); |
---|
55 | } |
---|
56 | |
---|
57 | |
---|
58 | But this is only half the story (or less). The main thing you'd have to |
---|
59 | understand is the C representation of Lisp data types. The header file |
---|
60 | rep_lisp.h defines this, and is reasonably well commented. For each |
---|
61 | data type there will be at least two macros rep_FOOP (x) which tests |
---|
62 | if a repv (a lisp pointer) is of type FOO, and rep_FOO (x) which casts |
---|
63 | the lisp pointer to the correct C pointer. |
---|
64 | |
---|
65 | So, e.g. for pairs, there's rep_CONSP and rep_CONS. There's also |
---|
66 | accessor macros rep_CAR (x) and rep_CDR (x) for this type. |
---|
67 | |
---|
68 | Another thing is that if a repv == rep_NULL, then an error occurred |
---|
69 | somewhere, and control should be unwound back to the top-level |
---|
70 | |
---|
71 | Garbage collection also complicates things, I posted a message to |
---|
72 | librep-list explaining the mechanics of this, it will be in the |
---|
73 | archives on sourceforge.. |
---|
74 | |
---|
75 | I've been meaning to document all this, but it's quite an undertaking :-) |
---|
76 | |
---|
77 | If you decide to use rep, I'm happy to answer as many questions as you |
---|
78 | have, or just post them to librep-list@lists.sourceforge.net |
---|
79 | |
---|
80 | John |
---|
81 | |
---|
82 | |
---|