summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjluehrs2 <jluehrs2@uiuc.edu>2008-05-24 19:56:51 -0500
committerjluehrs2 <jluehrs2@uiuc.edu>2008-05-24 19:56:51 -0500
commitd9a470f639166685bde3b696212c20bfbd3c9f6a (patch)
treea88bb41077545a94aa6858fdfab8ac5c399a0fb9
parent857d474b0eed23f6be5c3fe96c60b3e28dbc86c6 (diff)
downloadlanguage-teco-d9a470f639166685bde3b696212c20bfbd3c9f6a.tar.gz
language-teco-d9a470f639166685bde3b696212c20bfbd3c9f6a.zip
big refactor of execute to make it more precise and easier to expand
-rw-r--r--lib/Language/TECO.pm292
1 files changed, 140 insertions, 152 deletions
diff --git a/lib/Language/TECO.pm b/lib/Language/TECO.pm
index aba111f..7486a82 100644
--- a/lib/Language/TECO.pm
+++ b/lib/Language/TECO.pm
@@ -4,7 +4,7 @@ use strict;
use warnings;
use Language::TECO::Buffer;
use base 'Class::Accessor::Fast';
-Language::TECO->mk_accessors qw/at colon negate current_num/;
+Language::TECO->mk_accessors qw/at colon negate current_num want_num/;
Language::TECO->mk_ro_accessors qw/buf/;
sub new {
@@ -27,9 +27,12 @@ sub reset {
$self->{current_num} = 'n1';
$self->{n1} = undef;
$self->{n2} = undef;
+
$self->{at} = 0;
$self->{colon} = 0;
$self->{negate} = 0;
+
+ $self->{want_num} = 1;
}
sub num {
@@ -53,187 +56,172 @@ sub num {
}
}
-sub cmd {
+sub get_string {
my $self = shift;
- my $code = shift;
-
- $self->current_num('n1');
+ my $command = shift;
+ my $str;
- $code->($self);
+ if ($self->at) {
+ $command =~ s/(.)(.*?)\1//s;
+ $str = $2;
+ }
+ else {
+ $command =~ s/(.*?)\e//s;
+ $str = $1;
+ }
- $self->reset;
+ return ($str, $command);
}
-sub cmd_with_string {
+sub try_num {
my $self = shift;
- my $code = shift;
-
- return $self->cmd(sub {
- my $self = shift;
- my $str = '';
-
- if ($self->at) {
- $self->{command} =~ s/(.)(.*?)\1//s;
- $str = $2;
- }
- else {
- $self->{command} =~ s/(.*?)\e//s;
- $str = $1;
- }
+ my $command = shift;
+
+ $self->want_num(0);
+ if ($command =~ s/^([0-9])//) {
+ my $num = $self->num || 0;
+ my $prev = $1;
+ $prev = -$prev if $num < 0;
+ $self->num($num * 10 + $prev);
+ $self->want_num(1);
+ }
+ elsif ($command =~ s/^-//) {
+ $self->negate(1);
+ $self->want_num(1);
+ }
+ elsif ($command =~ s/^b//i) {
+ $self->num(0);
+ }
+ elsif ($command =~ s/^z//i) {
+ $self->num($self->buflen);
+ }
+ elsif ($command =~ s/^\.//) {
+ $self->num($self->pointer);
+ }
+ elsif ($command =~ s/^h//i) {
+ $command = 'b,z'.$command;
+ $self->want_num(1);
+ }
+ elsif ($command =~ s/^\cy//) {
+ $command = ".+\cs,.".$command;
+ $self->want_num(1);
+ }
- $code->($self, $str);
- });
+ return $command;
}
-sub push_cmd {
+sub try_cmd {
my $self = shift;
- my $to_push = shift;
- $self->{command} = $to_push . $self->{command};
-}
+ my $command = shift;
-sub execute {
- my $self = shift;
- $self->{command} = shift;
- my $ret = '';
-
- while ($self->{command}) {
- $_ = substr($self->{command}, 0, 1, '');
- if (/[0-9]/) {
- my $num = $self->num || 0;
- $_ = -$_ if $num < 0;
- $self->num($num * 10 + $_);
- }
- elsif (/-/) {
- $self->negate(1);
- }
- elsif (/b/i) {
- $self->num(0);
- }
- elsif (/z/i) {
- $self->num($self->buflen);
- }
- elsif (/\./) {
- $self->num($self->pointer);
- }
- elsif (/h/i) {
- $self->push_cmd('b,z');
- redo;
- }
- elsif (/\cy/) {
- $self->push_cmd(".+\cs,.");
- redo;
- }
- elsif (/,/) {
- $self->current_num('n2');
- }
- elsif (/:/) {
- $self->colon(1);
+ my $need_reset = 1;
+ if ($command =~ s/^,//) {
+ $self->current_num('n2');
+ $self->want_num(1);
+ $need_reset = 0;
+ }
+ elsif ($command =~ s/^://) {
+ $self->colon(1);
+ $need_reset = 0;
+ }
+ elsif ($command =~ s/^@//) {
+ $self->at(1);
+ $need_reset = 0;
+ }
+ elsif ($command =~ s/^i//i) {
+ if (defined $self->num) {
+ $self->buf->insert(chr($self->num))
}
- elsif (/@/) {
- $self->at(1);
+ else {
+ my $str;
+ ($str, $command) = $self->get_string($command);
+ $self->buf->insert($str);
}
- elsif (/i/i) {
- if (defined $self->num) {
- $self->cmd(sub {
- my $self = shift;
- $self->buf->insert(chr($self->num))
- });
- }
- else {
- $self->cmd_with_string(sub {
- my $self = shift;
- $self->buf->insert(shift);
- });
- }
+ }
+ elsif ($command =~ s/^d//i) {
+ if ($self->has_range) {
+ $command = 'k'.$command;
+ $need_reset = 0;
}
- elsif (/d/i) {
- if ($self->has_range) {
- $self->push_cmd('k');
- redo;
- }
+ else {
if (!defined $self->num) {
$self->num(1);
}
- $self->cmd(sub {
- my $self = shift;
- $self->buf->delete($self->pointer, $self->pointer + $self->num);
- });
+ $self->buf->delete($self->pointer, $self->pointer + $self->num);
}
- elsif (/k/i) {
- $self->cmd(sub {
- my $self = shift;
- if ($self->has_range) {
- $self->buf->delete($self->num);
- }
- else {
- if (!defined $self->num) {
- $self->num(1);
- }
- my $num = $self->num;
- $self->buf->delete($self->buf->get_line_offset($num));
- }
- });
- }
- elsif (/j/i) {
- if (!defined $self->num) {
- $self->num(0);
- }
- $self->cmd(sub {
- my $self = shift;
- $self->buf->set($self->num);
- });
+ }
+ elsif ($command =~ s/^k//i) {
+ if ($self->has_range) {
+ $self->buf->delete($self->num);
}
- elsif (/c/i) {
+ else {
if (!defined $self->num) {
$self->num(1);
}
- $self->cmd(sub {
- my $self = shift;
- $self->buf->offset($self->num);
- });
+ $self->buf->delete($self->buf->get_line_offset(scalar $self->num));
+ }
+ }
+ elsif ($command =~ s/^j//i) {
+ if (!defined $self->num) {
+ $self->num(0);
+ }
+ $self->buf->set($self->num);
+ }
+ elsif ($command =~ s/^c//i) {
+ if (!defined $self->num) {
+ $self->num(1);
+ }
+ $self->buf->offset($self->num);
+ }
+ elsif ($command =~ s/^r//i) {
+ if (!defined $self->num) {
+ $self->num(1);
}
- elsif (/r/i) {
+ $self->num(-$self->num);
+ $command = 'c'.$command;
+ $need_reset = 0;
+ }
+ elsif ($command =~ s/^l//i) {
+ if (!defined $self->num) {
+ $self->num(1);
+ }
+ $self->buf->set(scalar $self->buf->get_line_offset(scalar $self->num));
+ }
+ elsif ($command =~ s/^=//) {
+ my $fmt = ($command =~ s/^=//) ? "%o%s" : "%d%s";
+ $self->{ret} .= sprintf $fmt, $self->num, $self->colon ? "" : "\n";
+ }
+ elsif ($command =~ s/^t//i) {
+ if ($self->has_range) {
+ $self->{ret} .= $self->buffer($self->num);
+ }
+ else {
if (!defined $self->num) {
$self->num(1);
}
- $self->num(-$self->num);
- $self->push_cmd('c');
- redo;
- }
- elsif (/l/i) {
- $self->cmd(sub {
- my $self = shift;
- if (!defined $self->num) {
- $self->num(1);
- }
- $self->buf->set(scalar $self->buf->get_line_offset($self->num));
- });
- }
- elsif (/=/i) {
- $self->cmd(sub {
- my $self = shift;
- my $fmt = ($self->{command} =~ s/^=//) ? "%o%s" : "%d%s";
- $ret .= sprintf $fmt, $self->num, $self->colon ? "" : "\n";
- });
+ $self->{ret} .= $self->buffer($self->buf->get_line_offset(scalar $self->num));
}
- elsif (/t/i) {
- $self->cmd(sub {
- my $self = shift;
- if ($self->has_range) {
- $ret .= $self->buffer($self->num);
- }
- else {
- if (!defined $self->num) {
- $self->num(1);
- }
- my $num = $self->num;
- $ret .= $self->buffer($self->buf->get_line_offset($num));
- }
- });
+ }
+
+ $self->reset if $need_reset;
+
+ return $command;
+}
+
+sub execute {
+ my $self = shift;
+ my $command = shift;
+ $self->{ret} = '';
+
+ while ($command) {
+ if ($self->want_num) {
+ $command = $self->try_num($command);
+ next;
}
+ $command = $self->try_cmd($command);
}
- return $ret;
+ return $self->{ret};
}
=head1 NAME