Language-Eforth

 view release on metacpan or  search on metacpan

lib/Language/Eforth.pm  view on Meta::CPAN

# -*- Perl -*-
#
# most of the code, however, is over in Eforth.xs

package Language::Eforth;
use strict;
use warnings;
our $VERSION = '0.02';
require XSLoader;
XSLoader::load( 'Language::Eforth', $VERSION );

# more utility bloat
sub signed   { unpack s => pack s => $_[0] }
sub unsigned { unpack S => pack S => $_[0] }

# ( I complain about bloat here but then Chrome takes upwards of 10
# seconds to process a string much shorter than this sentence being
# pasted into the URL bar ... )

1;
__END__

=head1 NAME

Language::Eforth - a tiny embedded Forth interpreter

=head1 SYNOPSIS

  use Language::Eforth;
  my $f = Language::Eforth->new;

  $f->eval("2 2 + .s\n");
  print scalar $f->pop, "\n";

  $f->push(3, 7);
  print "depth: ", $f->depth, "\n";

  $f->eval("+\n");
  print scalar $f->pop, "\n";

  $f->reset;

  # there are, however, better ways to reverse a list of small
  # integers than this
  $f->eval("1 2 3 4\n");
  my @reverse = $f->drain;  # qw(4 3 2 1)

=head1 DESCRIPTION

This module embeds a tiny embeddable Forth interpreter.

L<https://github.com/howerj/embed>

The interpreter has a 16-bit cell size, does not support floating point
values, AND CONTRARY TO THE ans fORTH SPECIFICATION REQUIRES LOWER-CASE
WORDS. Consult C<embed.fth> for details on various "Error Codes" and
other documentation.

Memory usage while not zero should not be very significant; it mostly
depends on the C<EMBED_CORE_SIZE> count of 16-bit cells allocated. And
whatever Perl needs. Assertion failures are also possible, unless the
compile was somehow done with C<-DNDEBUG>.

=head1 METHODS

These may C<croak> should something be awry with the input, or if memory
allocation fails in the constructor.

=over 4

=item B<depth>

Returns the data stack depth as an unsigned integer.

=item B<drain>

Utility method to drain the data stack of all values as unsigned
integers, or returns the empty list otherwise. See also B<reset>.

Since version 0.02.

=item B<eval> I<expr>

Evaluates the string I<expr>. I<expr> MUST end with a newline. Output
from words such as C<.s> or C<.> or C<u.> is sent to standard output;
use L<Capture::Tiny> or similar to redirect this, if need be.

Input could be specified in a heredoc (see C<eg/shape> for an example)
or could be loaded into a string via a module like L<File::Slurper>.

No return value.

=item B<new>

Constructor. Returns a pointer to the interpreter used by the
other methods.

=item B<pop>

Pops an unsigned integer off of the data stack. In list context this
returns the value and the return code. If the code is non-zero something
went awry, probably a stack under- or overflow.

  my ( $value, $failed ) = $f->pop;
  if ( $failed ) { die "pop failed ($failed)\n" }

Otherwise, use the return value in scalar context, but then there is a
semipredicate problem where C<0> could mean the value zero, or that
there was a failure:

  my $v;
  $f->reset;              # empty the stack
  $f->eval("2 2 xor\n");  # calculate a value
  $v = scalar $f->pop;    # 0, the value
  $v = scalar $f->pop;    # 0, the semipredicate (underflow)

The value can be made 16-bit signed via:

  $f->push(54321);
  my $x = $f->pop;



( run in 0.666 second using v1.01-cache-2.11-cpan-71847e10f99 )