#!/usr/bin/perl -w
use strict;
use warnings;
my $header = "perl: ";
my (@errors, $param, @statement, $command, @context, @buffer);
my $evalstring = '';
my %builtins = (
spit => \&spit,
clear => \&clear,
save => \&save,
quit => sub { exit },
'exit' => sub { exit },
errors => \&printerrors,
help => \&help,
set => \&replset,
);
my %replenv = (
save => 0,
);
print $header;
while (my $line = <>) {
chomp $line;
@buffer = makebuffer("$line"); #format the incoming line so that each statement on the line is a separate value in @buffer
clear() unless $replenv{save};
while (@buffer > 0) {
@statement = split(/ /, $buffer[0]); #so that i can set hooks on certain commands.
$statement[0] =~ s/\W//; #remove the ';' added by makebuffer()
if (exists($builtins{"$statement[0]"})) {
$command = shift @statement;
$param = join " ", @statement;
$builtins{"$command"}->("$param");
}
else {
push @context, "$buffer[0]";
$evalstring = join " ", @context;
eval "no strict; use warnings; $evalstring" if (@buffer == 1); #run only if this is the last thing in the buffer.
if ($@) {
warn $@;
push @errors, $@;
}
}
shift @buffer;
}
print "\n$header";
}
sub save {
if ($replenv{save}) {
print "NOT saving input as context.";
}
else {
print "SAVING input as context.";
}
$replenv{save} = !$replenv{save};
clear();
return;
}
sub spit {
my $spitter = join " ", @context;
$spitter =~ s/;/;BREAKCRUSHKILLMAIMDESTROY/g; #to make splitting it easier
if ($spitter =~ /[({].*?BREAKCRUSHKILLMAIMDESTROY.*?[)}]/) {
$spitter =~ s/BREAKCRUSHKILLMAIMDESTROY//g; #so that we dont split inside a for's EXPR or inside a block
}
$spitter =~ s/{/{BREAKCRUSHKILLMAIMDESTROY/g;
$spitter =~ s/}/}BREAKCRUSHKILLMAIMDESTROY/g;
#later i might try to implement some kind of indentation scheme here but this will do for now.
my @foo = split(/BREAKCRUSHKILLMAIMDESTROY/, $spitter);
print "Current context is:\n\n";
for my $bar (@foo) {
$bar =~ s/^\s*//;
print $bar, "\n";
}
print "\nEND\nWe are ";
if ($replenv{save}) {
print "SAVING";
}
else {
print "NOT saving";
}
print " input as context.\n";
return;
}
sub clear {
@context = ();
return;
}
sub help {
#information on builtin commands, and general info
print "Soon";
return;
}
sub printerrors {
for (@errors) { print "$_\n"; }
return;
}
sub replset {
#manipulate the %replenv hash
print "Soon";
return;
}
sub makebuffer {
my $rawline = shift;
if ($rawline !~ /[;}]\s*$/) {
$rawline .= ';';
}
$rawline =~ s/;/;BREAKCRUSHKILLMAIMDESTROY/g; #to make splitting it easier
if ($rawline =~ /[({].*?BREAKCRUSHKILLMAIMDESTROY.*?[)}]/) {
$rawline =~ s/BREAKCRUSHKILLMAIMDESTROY//g; #so that we dont split inside a for's EXPR or inside a block
}
my $blargh = [ split(/BREAKCRUSHKILLMAIMDESTROY/, $rawline) ];
return @{$blargh};
}