#!/usr/bin/perl -w # l00p.pl : A compiler for the esoteric programming language "L00P". # Author : Georg Westenberger ( gwestenb@gmx.de ) # usage : perl l00p.pl [infile [outfile]] # #-------------------- BEGIN C HEREDOC -------------------------------- my $decl = < #define ARRAYSIZE 8192 signed short a[ARRAYSIZE]; signed short p = 0; signed short wrap (signed short ptr) { if (ptr>=0) return (ptr % ARRAYSIZE); else return (-ptr/ARRAYSIZE+1)*ARRAYSIZE+ptr; } #define A a[p] #define _a(x) a[wrap(x)] #define out_c printf("%c",a[p]) #define in_c scanf("%c",a+p) #define out_d printf("%d",a[p]) #define in_d scanf("%d",a+p) int main() { int i; for (i=0;i 'A--;', '+' => 'A++;', '<' => 'p = wrap(p-1);', '>' => 'p = wrap(p+1);', ',' => 'in_c;', '.' => 'out_c;', ';' => 'in_d;', ':' => 'out_d;', '&' => 'break;', '*' => 'A*=2;', '0' => 'A=0;', '_' => 'A=-A;', '@' => 'A=_a(p+_a(p));', '#' => 'p=wrap(p+_a(p));', '$' => '_a(p+_a(p))=A;', '(' => 'if(A){', '|' => '}else{', ')' => '}', '[' => 'if(!A){', ']' => '}', 'S' => 'A= A>0 ? 1:(A<0 ? -1 : 0);' ); sub check_syntax { my $s = shift; $s =~s-[^\[\]\(\)\|]--g; while ($s=~s-(?:\[\|??\])|(?:\(\|??\))--g) {}; die "\n||| SYNTAX ERROR: reduces to $s\n" unless ($s eq ''); } my $prog = ''; my $nsf = shift @ARGV; # Name of Source File, stdin by default $nsf ||= '-'; open SRC,$nsf or die "Can't open '$nsf'!\n"; while (defined($l=)) { chomp $l; $l=~s[\s][]g; $l=~s[//.*$][]; $l=~s-(?:\s+|[^\-\+\<\>\*0\_\@\#\$\&\(\)\|\[\]\,\.\;\:]+)--g; $prog .= $l; } close SRC; check_syntax $prog; my $ncf = shift @ARGV; $ncf ||= '-'; open CSRC, ">$ncf" or die "Can't open '$ncf'!\n"; print CSRC $decl; my @l = map{$_=$translation{$_}} (split '',$prog); foreach $x (@l) { print CSRC $x."\n" }; print CSRC '}}'; close CSRC;