use strict; use warnings;
package YAMLScript::RT;
use base 'Lingy::RT';
use Lingy::Common;
use YAMLScript::Core;
use YAMLScript::Reader;
use constant LANG => 'YAMLScript';
use constant reader_class => 'YAMLScript::Reader';
our ($rt, $reader);
sub new {
my $class = shift;
$rt = $class->SUPER::new(@_);
}
sub rt { $rt }
sub init {
my $self = shift;
$self->SUPER::init(@_);
$reader = $self->require_new($self->reader_class);
$self->rep(q<
(def load-file (fn [f]
(cond
(ends-with? f ".ys")
(eval (read-file-ys f))
(ends-with? f ".ly")
(-load-file-ly f)
:else
(throw (str "Can't load-file '" f "'\n"))
)))>);
return $self;
}
sub user_namespace {
my ($self) = @_;
Lingy::Namespace->new(
name => 'user',
refer => [
$self->core,
$self->util,
YAMLScript::Core->new,
],
);
}
sub repl {
local $YAMLScript::Reader::read_ys = 1;
my $self = shift;
$self->SUPER::repl(@_);
}
# TODO Find cleaner way to override 'require' to support .ys files.
use Lingy::Lang::RT;
package Lingy::Lang::RT;
use Lingy::Common;
no warnings 'redefine';
sub require {
outer:
for my $spec (@_) {
err "'require' only works with symbols"
unless ref($spec) eq SYMBOL;
return nil if $Lingy::RT::ns{$$spec};
my $name = $$spec;
my $path = $name;
$path =~ s/^lingy\.lang\./Lingy.Lang\./;
$path =~ s/^lingy\./Lingy\./;
my $module = $path;
$path =~ s/\./\//g;
for my $inc (@INC) {
$inc =~ s{^([^/.])}{./$1};
my $inc_path = "$inc/$path";
if (-f "$inc_path.pm" or
-f "$inc_path.ly" or
-f "$inc_path.ys"
) {
if (-f "$inc_path.pm") {
CORE::require("$inc_path.pm");
$module =~ s/\./::/g;
err "Can't require $name. " .
"$module is not a Lingy::Namespace."
unless $module->isa('Lingy::Namespace');
$module->new(
name => symbol($name),
refer => Lingy::RT->core,
);
}
if (-f "$inc_path.ly") {
my $ns = $Lingy::RT::ns{$Lingy::RT::ns};
Lingy::RT->rep(qq< (load-file "$inc_path.ly") >);
$ns->current;
}
if (-f "$inc_path.ys") {
my $ns = $Lingy::RT::ns{$Lingy::RT::ns};
Lingy::RT->rep(qq< (load-file "$inc_path.ys") >);
$ns->current;
}
next outer;
}
}
err "Can't find library for (require '$name)";
}
return nil;
}
1;