<?xml version="1.0" encoding="windows-1252"?>
<node id="980769" title="Perl implementation of an esolang. It's a party, yes?" created="2012-07-09 18:01:26" updated="2012-07-09 18:01:26">
<type id="1042">
CUFP</type>
<author id="329759">
corenth</author>
<data>
<field name="doctext">
Good day everybody. Over the past couple of months, I decided to try my hand at building an &lt;i&gt;esoteric&lt;/i&gt; programming language ([wp://esolang]).
&lt;p /&gt;
I freely admit that it's probably poorly written, but oh so fun!
&lt;p /&gt;
I've written up a draft of how to write in it [http://esolangs.org/wiki/Iris]. There's a lot that needs to be added to make things understandable.
&lt;p /&gt;
The sourcecode for a fibonacci number generator is built into the array @A in the script below. Just run the critter and have fun.
&lt;p /&gt;

&lt;readmore&gt;
Here is a commented version of the "source code"::

&lt;code&gt;
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 --&gt; that's lots of numbers!
	4, #number of function calls (those four assignment calls following...)
	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

);
&lt;/code&gt;

And, here is the script:

&lt;code&gt;

#!/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 negative 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 &lt; 0; #to get to R[0] this way, 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 = &gt;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/== &lt; &gt; != &lt;= &gt;= 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 count
	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-&gt;[$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 big 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; 
}
&lt;/code&gt;
&lt;/readmore&gt;

Any ideas? Please give me a yell! I'd love to hear the good and the bad.
&lt;p /&gt;
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?
&lt;p /&gt;
Thank you all, &amp; I hope you have fun with this.
&lt;p /&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-329759"&gt;
$state{tired}?sleep(40):eat($food);
&lt;/div&gt;&lt;/div&gt;</field>
</data>
</node>
