Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | =head1 NAME |
2 | ||
3 | Inline-API - How to bind a programming language to Perl using Inline.pm | |
4 | ||
5 | =head1 SYNOPSIS | |
6 | ||
7 | #!/usr/bin/perl | |
8 | ||
9 | use Inline Foo; | |
10 | say_it('foo'); # Use Foo to print "Hello, Foo" | |
11 | ||
12 | __Foo__ | |
13 | foo-sub say_it { | |
14 | foo-my $foo = foo-shift; | |
15 | foo-print "Hello, $foo\n"; | |
16 | } | |
17 | ||
18 | =head1 DESCRIPTION | |
19 | ||
20 | So you think Inline C is pretty cool, but what you really need is for | |
21 | Perl to work with the brand new programming language "Foo". Well you're | |
22 | in luck. C<Inline.pm> has support for adding your own Inline Language | |
23 | Support Module (B<ILSM>), like C<Inline::Foo>. | |
24 | ||
25 | Inline has always been intended to work with lots of different | |
26 | programming languages. Many of the details can be shared between | |
27 | implementations, so that C<Inline::Java> has a similar interface to | |
28 | C<Inline::ASM>. All of the common code is in C<Inline.pm>. | |
29 | ||
30 | Language specific modules like C<Inline::Python> are subclasses of | |
31 | C<Inline.pm>. They can inherit as much of the common behaviour as they | |
32 | want, and provide specific behaviour of their own. This usually comes in | |
33 | the form of Configuration Options and language specific compilation. | |
34 | ||
35 | The Inline C support is probably the best boilerplate to copy from. | |
36 | Since version 0.30 all C support was isolated into the module | |
37 | C<Inline::C> and the parsing grammar is further broken out into | |
38 | C<Inline::C::grammar>. All of these components come with the Inline | |
39 | distribution. | |
40 | ||
41 | This POD gives you all the details you need for implementing an ILSM. | |
42 | For further assistance, contact inline@perl.org See L<"SEE ALSO"> below. | |
43 | ||
44 | We'll examine the joke language Inline::Foo which is distributed with | |
45 | Inline. It actually is a full functioning ILSM. I use it in Inline's | |
46 | test harness to test base Inline functionality. It is very short, and | |
47 | can help you get your head wrapped around the Inline API. | |
48 | ||
49 | =head1 A Skeleton | |
50 | ||
51 | For the remainder of this tutorial, let's assume we're writing an ILSM | |
52 | for the ficticious language C<Foo>. We'll call it C<Inline::Foo>. Here | |
53 | is the entire (working) implementation. | |
54 | ||
55 | package Inline::Foo; | |
56 | use strict; | |
57 | $Inline::Foo::VERSION = '0.01'; | |
58 | @Inline::Foo::ISA = qw(Inline); | |
59 | require Inline; | |
60 | use Carp; | |
61 | ||
62 | #=========================================================== | |
63 | # Register Foo as an Inline Language Support Module (ILSM) | |
64 | #=========================================================== | |
65 | sub register { | |
66 | return { | |
67 | language => 'Foo', | |
68 | aliases => ['foo'], | |
69 | type => 'interpreted', | |
70 | suffix => 'foo', | |
71 | }; | |
72 | } | |
73 | ||
74 | #=========================================================== | |
75 | # Error messages | |
76 | #=========================================================== | |
77 | sub usage_config { | |
78 | my ($key) = @_; | |
79 | "'$key' is not a valid config option for Inline::Foo\n"; | |
80 | } | |
81 | ||
82 | sub usage_config_bar { | |
83 | "Invalid value for Inline::Foo config option BAR"; | |
84 | } | |
85 | ||
86 | #=========================================================== | |
87 | # Validate the Foo Config Options | |
88 | #=========================================================== | |
89 | sub validate { | |
90 | my $o = shift; | |
91 | $o->{ILSM}{PATTERN} ||= 'foo-'; | |
92 | $o->{ILSM}{BAR} ||= 0; | |
93 | while (@_) { | |
94 | my ($key, $value) = splice @_, 0, 2; | |
95 | if ($key eq 'PATTERN') { | |
96 | $o->{ILSM}{PATTERN} = $value; | |
97 | next; | |
98 | } | |
99 | if ($key eq 'BAR') { | |
100 | croak usage_config_bar | |
101 | unless $value =~ /^[01]$/; | |
102 | $o->{ILSM}{BAR} = $value; | |
103 | next; | |
104 | } | |
105 | croak usage_config($key); | |
106 | } | |
107 | } | |
108 | ||
109 | #=========================================================== | |
110 | # Parse and compile Foo code | |
111 | #=========================================================== | |
112 | sub build { | |
113 | my $o = shift; | |
114 | my $code = $o->{API}{code}; | |
115 | my $pattern = $o->{ILSM}{PATTERN}; | |
116 | $code =~ s/$pattern//g; | |
117 | $code =~ s/bar-//g if $o->{ILSM}{BAR}; | |
118 | sleep 1; # imitate compile delay | |
119 | { | |
120 | package Foo::Tester; | |
121 | eval $code; | |
122 | } | |
123 | croak "Foo build failed:\n$@" if $@; | |
124 | my $path = "$o->{API}{install_lib}/auto/$o->{API}{modpname}"; | |
125 | my $obj = $o->{API}{location}; | |
126 | $o->mkpath($path) unless -d $path; | |
127 | open FOO_OBJ, "> $obj" | |
128 | or croak "Can't open $obj for output\n$!"; | |
129 | print FOO_OBJ $code; | |
130 | close \*FOO_OBJ; | |
131 | } | |
132 | ||
133 | #=========================================================== | |
134 | # Only needed for interpreted languages | |
135 | #=========================================================== | |
136 | sub load { | |
137 | my $o = shift; | |
138 | my $obj = $o->{API}{location}; | |
139 | open FOO_OBJ, "< $obj" | |
140 | or croak "Can't open $obj for output\n$!"; | |
141 | my $code = join '', <FOO_OBJ>; | |
142 | close \*FOO_OBJ; | |
143 | eval "package $o->{API}{pkg};\n$code"; | |
144 | croak "Unable to load Foo module $obj:\n$@" if $@; | |
145 | } | |
146 | ||
147 | #=========================================================== | |
148 | # Return a small report about the Foo code. | |
149 | #=========================================================== | |
150 | sub info { | |
151 | my $o = shift; | |
152 | my $text = <<'END'; | |
153 | This is a small report about the Foo code. Perhaps it contains | |
154 | information about the functions the parser found which will be | |
155 | bound to Perl. It will get included in the text produced by the | |
156 | Inline 'INFO' command. | |
157 | END | |
158 | return $text; | |
159 | } | |
160 | ||
161 | 1; | |
162 | ||
163 | Except for C<load()>, the subroutines in this code are mandatory for an | |
164 | ILSM. What they do is described below. A few things to note: | |
165 | ||
166 | =over 4 | |
167 | ||
168 | =item 1 | |
169 | ||
170 | C<Inline::Foo> must be a subclass of Inline. This is accomplished with: | |
171 | ||
172 | @Inline::Foo::ISA = qw(Inline); | |
173 | ||
174 | =item 2 | |
175 | ||
176 | The line 'C<require Inline;>' is not necessary. But it is there to | |
177 | remind you not to say 'C<use Inline;>'. This will not work. | |
178 | ||
179 | =item 3 | |
180 | ||
181 | Remember, it is not valid for a user to say: | |
182 | ||
183 | use Inline::Foo; | |
184 | ||
185 | C<Inline.pm> will detect such usage for you in its C<import> method, | |
186 | which is automatically inherited since C<Inline::Foo> is a subclass. | |
187 | ||
188 | =item 4 | |
189 | ||
190 | In the build function, you normally need to parse your source code. | |
191 | Inline::C uses Parse::RecDescent to do this. Inline::Foo simply uses | |
192 | eval. (After we strip out all occurances of 'foo-'). | |
193 | ||
194 | An alternative parsing method that works well for many ILSMs (like Java | |
195 | and Python) is to use the language's compiler itself to parse for you. | |
196 | This works as long as the compiler can be made to give back parse | |
197 | information. | |
198 | ||
199 | =back | |
200 | ||
201 | =head1 The Inline API | |
202 | ||
203 | This section is a more formal specification of what functionality you'll | |
204 | need to provide to implement an ILSM. | |
205 | ||
206 | When Inline determines that some C<Foo> code needs to be compiled it | |
207 | will automatically load your ILSM module. It will then call various | |
208 | subroutines which you need to supply. We'll call these subroutines | |
209 | "callbacks". | |
210 | ||
211 | You will need to provide the following 5 callback subroutines. | |
212 | ||
213 | =head2 The register() Callback | |
214 | ||
215 | This subroutine receives no arguments. It returns a reference to a hash | |
216 | of ILSM meta-data. Inline calls this routine only when it is trying to | |
217 | detect new ILSM-s that have been installed on a given system. Here is an | |
218 | example of the has ref you would return for Foo: | |
219 | ||
220 | { | |
221 | language => 'Foo', | |
222 | aliases => ['foo'], | |
223 | type => 'interpreted', | |
224 | suffix => 'foo', | |
225 | }; | |
226 | ||
227 | The meta-data items have the following meanings: | |
228 | ||
229 | =over 4 | |
230 | ||
231 | =item language | |
232 | ||
233 | This is the proper name of the language. It is usually implemented as | |
234 | C<Inline::X> for a given language 'X'. | |
235 | ||
236 | =item aliases | |
237 | ||
238 | This is a reference to an array of language name aliases. The proper | |
239 | name of a language can only contain word characters. [A-Za-z0-9_] An | |
240 | alias can contain any characters except whitespace and quotes. This is | |
241 | useful for names like 'C++' and 'C#'. | |
242 | ||
243 | =item type | |
244 | ||
245 | Must be set to 'compiled' or 'interpreted'. Indicates the category of | |
246 | the language. | |
247 | ||
248 | =item suffix | |
249 | ||
250 | This is the file extension for the cached object that will be created. | |
251 | For 'compiled' languages, it will probably be 'so' or 'dll'. The | |
252 | appropriate value is in C<Config.pm>. | |
253 | ||
254 | For interpreted languages, this value can be whatever you want. Python | |
255 | uses C<pydat>. Foo uses C<foo>. | |
256 | ||
257 | =back | |
258 | ||
259 | =head2 The validate() Callback | |
260 | ||
261 | This routine gets passed all configuration options that were not already | |
262 | handled by the base Inline module. The options are passed as key/value | |
263 | pairs. It is up to you to validate each option and store its value in | |
264 | the Inline object (which is also passed in). If a particular option is | |
265 | invalid, you should croak with an appropriate error message. | |
266 | ||
267 | =head2 The build() Callback | |
268 | ||
269 | This subroutine is responsible for doing the parsing and compilation of | |
270 | the Foo source code. The Inline object is passed as the only argument. | |
271 | All pertinent information will be stored in this object. C<build()> is | |
272 | required to create a cache object of a specific name, or to croak with | |
273 | an appropriate error message. | |
274 | ||
275 | This is the meat of your ILSM. Since it will most likely be quite | |
276 | complicated, it is probably best that you study an existing ILSM like | |
277 | C<Inline::C>. | |
278 | ||
279 | =head2 The load() Callback | |
280 | ||
281 | This method only needs to be provided for interpreted languages. It's | |
282 | responsibility is to start the interpreter. | |
283 | ||
284 | For compiled languages, the load routine from C<Inline.pm> is called | |
285 | which uses C<DynaLoader> to load the shared object or DLL. | |
286 | ||
287 | =head2 The info() Callback | |
288 | ||
289 | This method is called when the user makes use of the C<INFO> | |
290 | shortcut. You should return a string containing a small report about | |
291 | the Inlined code. | |
292 | ||
293 | =head1 The Inline Object | |
294 | ||
295 | C<Inline.pm> creates a hash based Perl object for each section of | |
296 | Inlined source code it receives. This object contains lots of | |
297 | information about the code, the environment, and the configuration | |
298 | options used. | |
299 | ||
300 | This object is a hash that is broken into several subhashes. The only | |
301 | two subhashes that an ILSM should use at all are $o->{API} and | |
302 | $o->{ILSM}. The first one contains all of the information that Inline | |
303 | has gather for you in order for you to create/load a cached object of | |
304 | your design. The second one is a repository where your ILSM can freely | |
305 | store data that it might need later on. | |
306 | ||
307 | This section will describe all of the Inline object "API" attributes. | |
308 | ||
309 | =head2 The code Attribute | |
310 | ||
311 | This the actual source code passed in by the user. It is stored as one | |
312 | long string. | |
313 | ||
314 | =head2 The language Attribute | |
315 | ||
316 | The proper name of the language being used. | |
317 | ||
318 | =head2 The language_id Attribute | |
319 | ||
320 | The language name specified by the user. Could be 'C++' instead of 'CPP'. | |
321 | ||
322 | =head2 The module Attribute | |
323 | ||
324 | This is the shared object's file name. | |
325 | ||
326 | =head2 The modfname Attribute | |
327 | ||
328 | This is the shared object's file name. | |
329 | ||
330 | =head2 The modpname Attribute | |
331 | ||
332 | This is the shared object's installation path extension. | |
333 | ||
334 | =head2 The version Attribute | |
335 | ||
336 | The version of C<Inline.pm> being used. | |
337 | ||
338 | =head2 The pkg Attribute | |
339 | ||
340 | The Perl package from which this invocation pf Inline was called. | |
341 | ||
342 | =head2 The install_lib Attribute | |
343 | ||
344 | This is the directory to write the shared object into. | |
345 | ||
346 | =head2 The build_dir Attribute | |
347 | ||
348 | This is the directory under which you should write all of your build | |
349 | related files. | |
350 | ||
351 | =head2 The script Attribute | |
352 | ||
353 | This is the name of the script that invoked Inline. | |
354 | ||
355 | =head2 The location Attribute | |
356 | ||
357 | This is the full path name of the executable object in question. | |
358 | ||
359 | =head2 The suffix Attribute | |
360 | ||
361 | This is the shared library extension name. (Usually 'so' or 'dll'). | |
362 | ||
363 | =over 4 | |
364 | ||
365 | =back | |
366 | ||
367 | =head1 The Inline Namespace | |
368 | ||
369 | C<Inline.pm> has been set up so that anyone can write their own language | |
370 | support modules. It further allows anyone to write a different | |
371 | implementation of an existing Inline language, like C for instance. You | |
372 | can distribute that module on the CPAN. | |
373 | ||
374 | If you have plans to implement and distribute an Inline module, I would | |
375 | ask that you please work with the Inline community. We can be reached at | |
376 | the Inline mailing list: inline@perl.org (Send mail to | |
377 | inline-subscribe@perl.org to subscribe). Here you should find the advice | |
378 | and assistance needed to make your module a success. | |
379 | ||
380 | The Inline community will decide if your implementation of COBOL will be | |
381 | distributed as the official C<Inline::COBOL> or should use an alternate | |
382 | namespace. In matters of dispute, I (Brian Ingerson) retain final | |
383 | authority. (and I hope not to need use of it :-) Actually | |
384 | modules@perl.org retains the B<final> authority. | |
385 | ||
386 | But even if you want to work alone, you are free and welcome to write | |
387 | and distribute Inline language support modules on CPAN. You'll just need | |
388 | to distribute them under a different package name. | |
389 | ||
390 | =head1 SEE ALSO | |
391 | ||
392 | For generic information about Inline, see L<Inline>. | |
393 | ||
394 | For information about using Inline with C see L<Inline::C>. | |
395 | ||
396 | For information on supported languages and platforms see | |
397 | L<Inline-Support>. | |
398 | ||
399 | Inline's mailing list is inline@perl.org | |
400 | ||
401 | To subscribe, send email to inline-subscribe@perl.org | |
402 | ||
403 | =head1 AUTHOR | |
404 | ||
405 | Brian Ingerson <INGY@cpan.org> | |
406 | ||
407 | =head1 COPYRIGHT | |
408 | ||
409 | Copyright (c) 2000, 2001, 2002. Brian Ingerson. All rights reserved. | |
410 | ||
411 | This program is free software; you can redistribute it and/or modify it | |
412 | under the same terms as Perl itself. | |
413 | ||
414 | See http://www.perl.com/perl/misc/Artistic.html | |
415 | ||
416 | =cut |