Acme-Aheui
view release on metacpan or search on metacpan
lib/Acme/Aheui.pm view on Meta::CPAN
Version 0.05
=cut
our $VERSION = '0.05';
=head1 SYNOPSIS
use utf8;
use Acme::Aheui;
my $interpreter = Acme::Aheui->new( source => 'ìí¬' );
$interpreter->execute();
=head1 DESCRIPTION
An aheui interpreter.
See aheui language specification at L<https://aheui.github.io/specification.en>
Most logic is based on the reference implementation by Puzzlet Chung.
(L<https://github.com/aheui/jsaheui>)
=cut
use constant {
JONG_STROKE_NUMS =>
[0, 2, 4, 4, 2, 5, 5, 3, 5, 7, 9, 9, 7, 9,
9, 8, 4, 4, 6, 2, 4, 1, 3, 4, 3, 4, 4, 3],
REQUIRED_ELEM_NUMS =>
[0, 0, 2, 2, 2, 2, 1, 0, 1, 0, 1, 0, 2, 0, 1, 0, 2, 2, 0],
};
=head1 PUBLIC METHODS
=head2 new
my $interpreter = Acme::Aheui->new( source => 'ìí¬' );
This method will create and return C<Acme::Aheui> object.
=cut
sub new {
my $class = shift;
my %args = @_;
my $source = $args{source} || '';
my $encoding = $args{output_encoding} || Term::Encoding::get_encoding();
my $self = {
_codespace => build_codespace($source),
_stacks => [],
_stack_index => 0,
_x => 0,
_y => 0,
_dx => 0,
_dy => 1,
_encoding => $encoding,
};
bless $self, $class;
return $self;
}
sub build_codespace {
my ($source) = @_;
my @lines = split /\r?\n/, $source;
my @rows = ();
for my $line (@lines) {
my @row = ();
for my $char (split //, $line) {
my $disassembled = disassemble_hangul_char($char);
push @row, $disassembled;
}
push @rows, \@row;
}
return \@rows;
}
sub disassemble_hangul_char {
my ($char) = @_;
if ($char =~ /[ê°-í£]/) {
my $code = unpack 'U', $char;
$code -= 0xAC00;
my ($cho, $jung, $jong) = (int($code/28/21), ($code/28)%21, $code%28);
return {cho => $cho, jung => $jung, jong => $jong};
}
else {
return {cho => -1, jung => -1, jong => -1};
}
}
=head2 execute
$interpreter->execute();
This method will execute the aheui program and return the exit code.
It may use C<STDIN> and/or C<STDOUT> if the aheui program uses I/O.
=cut
sub execute {
my ($self) = @_;
return 0 unless $self->_has_initial_command();
return $self->_loop_steps();
}
sub _has_initial_command {
my ($self) = @_;
for my $row (@{ $self->{_codespace} }) {
my $first_command = @$row[0];
if ($first_command && $$first_command{cho} != -1) {
return 1;
}
}
return 0;
( run in 0.498 second using v1.01-cache-2.11-cpan-d7f47b0818f )