package Inline::MzScheme; $Inline::MzScheme::VERSION = '0.05'; @Inline::MzScheme::ISA = qw(Inline); use strict; use Inline (); use Language::MzScheme (); =head1 NAME Inline::MzScheme - Inline module for the PLT MzScheme interpreter =head1 VERSION This document describes version 0.05 of Inline::MzScheme, released June 13, 2004. =head1 SYNOPSIS use subs 'perl_multiply'; # have to declare before Inline runs use Math::BigInt; use Inline MzScheme => q{ (define (square x) (perl-multiply x x)) (define assoc-list '((1 . 2) (3 . 4) (5 . 6))) (define linked-list '(1 2 3 4 5 6)) (define hex-string (bigint 'as_hex)) }, (bigint => Math::BigInt->new(1792)); sub perl_multiply { $_[0] * $_[1] } print square(10); # 100 print $hex_string; # 0x700 print $assoc_list->{1}; # 2 print $linked_list->[3]; # 4 =head1 DESCRIPTION This module allows you to add blocks of Scheme code to your Perl scripts and modules. All user-defined procedures in your Scheme code will be available as Perl subroutines; association lists and hash tables are available as Perl hash refereces; lists and vectors available as array references; boxed values become scalar references. Perl subroutines in the same package are imported as Scheme primitives, as long as they are declared before the C line. Non-word characters in Scheme identifiers are turned into C<_> for Perl. Underscores in Perl identifiers are turned into C<-> for Scheme. Additional objects, classes and procedures may be imported into Scheme, by passing them as config parameters to C. See L for details about this syntax. You can invoke perl objects in Scheme code with the syntax: (object 'method arg1 arg2 ...) If your method takes named argument lists, this will do: (object 'method 'key1 val1 'key2 val2) For information about handling MzScheme data in Perl, please see L. This module is mostly a wrapper around L with a little auto-binding magic for procedures and input variables. =cut # register for Inline sub register { return { language => 'MzScheme', aliases => ['MZSCHEME'], type => 'interpreted', suffix => 'go', }; } # check options sub validate { my $self = shift; my $env = $self->{env} ||= Language::MzScheme->new; while (@_ >= 2) { my ($key, $value) = (shift, shift); $env->define($key, $value) if $key =~ /^\w/; } } # required method - doesn't do anything useful sub build { my $self = shift; # magic dance steps to a successful Inline compile... my $path = "$self->{API}{install_lib}/auto/$self->{API}{modpname}"; my $obj = $self->{API}{location}; $self->mkpath($path) unless -d $path; $self->mkpath($self->{API}{build_dir}) unless -d $self->{API}{build_dir}; # touch my monkey open(OBJECT, ">$obj") or die "Unable to open object file: $obj : $!"; close(OBJECT) or die "Unable to close object file: $obj : $!"; } # load the code into the interpreter sub load { my $self = shift; my $code = $self->{API}{code}; my $pkg = $self->{API}{pkg} || 'main'; my $env = $self->{env} ||= Language::MzScheme->new; $env->define_perl_wrappers; my %sym = map( ( $_ => 1 ), $env->eval('(namespace-mapped-symbols)') =~ /([^\s()]+)/g ); $env->eval($code); no strict 'refs'; foreach my $sym (sort keys %{"$pkg\::"}) { my $code = *{${"$pkg\::"}{$sym}}{CODE} or next; $sym =~ tr/_/-/; $env->define("$pkg\::$sym", $code) unless $sym{"$pkg\::$sym"}++; $env->define($sym, $code) unless $sym{$sym}++; } SYMBOL: foreach my $sym (grep !$sym{$_}, $env->eval('(namespace-mapped-symbols)') =~ /([^\s()]+)/g) { my $obj = $env->lookup($sym); $sym =~ s/\W/_/g; foreach my $type (qw( CODE GLOB )) { $obj->isa($type) or next; *{"$pkg\::$sym"} = $obj->can('to_'.lc($type).'ref')->($obj); next SYMBOL; } *{"$pkg\::$sym"} = \$obj; } } # no info implementation yet sub info { } 1; __END__ =head1 ACKNOWLEDGEMENTS Thanks to Sam Tregar's L for showing me how to do this. =head1 SEE ALSO L, L =head1 AUTHORS Autrijus Tang Eautrijus@autrijus.orgE =head1 COPYRIGHT Copyright 2004 by Autrijus Tang Eautrijus@autrijus.orgE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =cut