Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Perl implementation of an esolang. It's a party, yes?

by corenth (Monk)
on Jul 09, 2012 at 22:01 UTC ( #980769=CUFP: print w/replies, xml ) Need Help??

Good day everybody. Over the past couple of months, I decided to try my hand at building an esoteric programming language (esolang).

I freely admit that it's probably poorly written, but oh so fun!

I've written up a draft of how to write in it There's a lot that needs to be added to make things understandable.

The sourcecode for a fibonacci number generator is built into the array @A in the script below. Just run the critter and have fun.

Here is a commented version of the "source code"::
my @A #list A = ( #init: 0, #assignment call 0,0,1,5, # R[0] = 5 0, #assign 3,0,1,1, # R[3] = 1 0, #assign 4,0,1,1, # R[4] = 1 2, #Flow call 3000, #iterations --> that's lots of numbers! 4, #number of function calls (those four assignment calls followin +g...) 1000, #skipto effectively ends the program when this is done 0,1,1, #condition statement. returns a '1' which is "true" 0, #assignment 1, 1, 1,1, 2,0, 1, #R[1] = R[0] - 1 0, #assignment 2, 1, 1,2, 2,0, 1, #R[2] = R[0] - 2 0, #assignment -.1, 1, 2,-1, 2,-2, 0, #R[R[0]] = R[R[2]] + R[R[1]] 0, #assignment 0, 1, 2,0, 1,1, 0, #R[0] = R[0] +1 );
And, here is the script:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @R = qw//; my @A = ( #init: 0, #asn 0,0,1,5, 0, 3,0,1,1, 0, 4,0,1,1, 2, #Flow() 3000, #iterations 4, #num events 1000, #skipto 0,1,1, 0, 1, 1, 1,1, 2,0, 1, 0, 2, 1, 1,2, 2,0, 1, 0, -.1, 1, 2,-1, 2,-2, 0, 0, 0, 1, 2,0, 1,1, 0, ); my $ptr = 0; my $limit = 10000; #kill infinite loops etc. while (1){ event(); } sub event { $limit--; dump_("LIMIT REACHED") unless $limit; my ($choice) = access_A(); $choice = $choice%3; if ($choice == 0) { assignment() } if ($choice == 1){ go() } if ($choice == 2){ flow() } } sub dump_{ my $debug = shift; print map{$_,"|"}@R; print "\ndump_ message is $debug\n"; die; } sub access_A { my $value; my $no_R = shift; #if this has a value, then we do not convert neg +ative numbers from A to R references. This is needed for expressions. my $int = shift; defined $A[$ptr]? $value = $A[$ptr]: dump_('end'); $ptr++; unless ($no_R){ $value =$R [abs($value)] if $value < 0; #to get to R[0] this w +ay, use -.1 or some similar value } $value = int($value) if $int; return ($value); } sub access_R{ my $ref = shift; my $value; (defined $R[$ref])? ($value = $R[$ref]): ($value = 0); $value } sub flow{ # iterations give us if() for() and while() loops all in one. # iterations = 0 gives us a while from the conditional # iterations = 1 gives us an if from conditional # iterations = >1 gives us a for loop from conditional. # with a conditional of (1) (like while (1)) you end # up with a classic for loop # # # my $iterations = access_A(0,'int'); my $num_events = access_A(0,'int'); $num_events = 1 unless $num_events; my $skipto = access_A(0,'int'); $skipto += $ptr; my $conditional_ptr = $ptr; if ($iterations){ for (1 .. $iterations){ if (conditional()){ for (1 .. $num_events){event()} }else{last} $ptr = $conditional_ptr; } }else{ while (conditional()){ for (1 .. $num_events){event()} $ptr = $conditional_ptr; } } $ptr = $skipto; } sub conditional{ my @operators = qw/== < > != <= >= and or xor/; my $truthiness = expression(\@operators); return $truthiness } sub assignment{ my @operators = qw/+ - * \/ ** %/; my $left_val_ref = access_A(); my $result = expression(\@operators); $R[$left_val_ref] = $result; } ####____ # sub expression has several routines associated with it: # rpn() # get_operator() # get_value() # val_or_operator() # # sub expression { my $operator_list = shift; my $o = access_A(0,'int');#num of ops if ($o == 0){ return get_value(); } my @a = (get_value(),get_value()); #start with two numbers my $v = $o -1; #with the two numbers above.. we reduce the value c +ount while ($o){ if ($o == $v){ push @a, get_value();$v--; next }elsif ($v){ if (val_or_operator()){ push @a, get_value(); $v--; }else{ push @a, get_operator($operator_list); $o--; } next } push @a, get_operator($operator_list); $o--; } my $result = rpn(\@a); return $result; } sub get_operator { my $operator_list = shift; my $op = access_A(); my $operator = $operator_list->[$op % ($#$operator_list+1)]; return $operator; } sub get_value{ #in which we learn weather or not the next value is a reference to + @R # then we return the result # # we don't use the "negative numbers are R refs," becuase negative + nums # are kinda useful in arithmetic... go figure. my $val = access_A(); # $val is the choice between either an A value or an R value ($val% 2)? ($val = access_A("no R")): ($val = access_R(access_A())); # $val is now an arithmetic value defined($val)?return $val:return 0; } sub val_or_operator{ my $choice = access_A(); return $choice%2; } sub rpn{ my $a = shift; my @stack; for (@$a){ (/\d/)? (push @stack, $_): (push @stack, eval ((pop @stack)." $_ ".(pop @stack))); dump_("big-ass number") if ($stack[$#stack] =~/e/); #too b +ig is too big. dump_(" DIV by ZERO is a BIG problem") if ($@=~ /Illegal/) +; #honestly don't need to deal with div by 0 ($stack[$#stack] = 0) unless (defined $stack[$#stack]); $stack[$#stack] = 0 if $stack[$#stack] == -0; #wierd... but I +have to do it. } return $stack[0]; } # the above ends selections of routines for expression() ###__________ sub go { my $loc = access_A(); my $iterations = access_A(0,'int'); unless ($iterations){ $ptr = $loc; return } my $temp = $ptr; $ptr = $loc; for (0 .. $iterations){ event() } $ptr = $temp; }
Any ideas? Please give me a yell! I'd love to hear the good and the bad.

BTW- look at sub rpn. I had to change -0 to 0 on occasion (don't recall the specific conditions). Now, what could that mean?

Thank you all, & I hope you have fun with this.


Replies are listed 'Best First'.
Re: Perl implementation of an esolang. It's a party, yes?
by bitingduck (Chaplain) on Jul 10, 2012 at 07:02 UTC

    Reading the description (I didn't look carefully through the code spec) it kind of reminds me of the old Corewars. Corewars included both self-modifying code, and the possibility (actually near certainty) that your code would be modified by your hostile opponent. Short of trying to execute a DATA statement (the goal was to make the other guy execute DATA statements with all his processes) pretty much everything would execute. It was a simple language-- 10-ish "assembly" instructions and 3 or 4 addressing modes (I'm too lazy to even look through the current site to check). It was fun to have a crude display and watch processes go zipping through the core in unexpected ways.

      I looked up the site & found it really interesting. I didn't get to look at the genetic algorithm part of it, but it makes sense to me how it may work.


        It's not really an explicit part of the game-- it just always seemed like with 64 processes per side running around blasting each other with unpredictable commands you end up with random mods to code and then tests of survival. Hence the genetic algorithm element. I never tried developing programs genetically though.

        Watching stuff fly through the core it usually started off looking like you expect, and then often switching to really random behavior.

Re: Perl implementation of an esolang. It's a party, yes?
by Anonymous Monk on Jul 09, 2012 at 22:17 UTC

    Must have been named by an esolang

      Ok. I admit it. I'm lost. :P


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://980769]
Approved by ww
Front-paged by Arunbear
[choroba]: Unfortunately, none of it is online
[haukex]: I figured that POD tests make sense, but only as author tests
[choroba]: I mean, the slides are, but not the makefile with scripts to create them
[Corion]: haukex: I've only now arrived at that revelation ;)
[Corion]: choroba: I use spod5, which also has that support, and also implements its own kinda-make stuff
[haukex]: But that module I just linked to assumes that most verbatim blocks are runnable code, I have other modules where that's not the case, so there I just copy-and-paste the synopsis into the author tests...
[haukex]: not the most efficient, but then again, I don't have that many modules on CPAN :-)
[Corion]: haukex: Yes, but if it's only supposed to run on my machine, I can be far more liberal with how I extract the code etc.
[Corion]: haukex: Yes - I see the benefit of using Dist::Zilla for people with 150+ modules on CPAN, but I don't see it for myself, and I'm always put off from contributing to such modules because they require a lot of toolchain setup that I don't want to ...
[Corion]: ... spend time on if I only want to provide a short patch

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (13)
As of 2017-02-27 12:31 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (385 votes). Check out past polls.