thutu.pl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/bin/perl
  2. # Thutu to Perl reference compiler.
  3. # Preamble.
  4. print << "EOF";
  5. #!/bin/perl
  6. # Perl output for Thutu file $0.
  7. EOF
  8. print << 'EOF';
  9. $_="=1";
  10. $row="";
  11. $ninequit=0;
  12. while(!$ninequit)
  13. {
  14. $row =~ s/=/=q/g;
  15. $row =~ s/\t/=t/g;
  16. $row =~ s/\n/=x/g; # The newline at the end of the line becomes =x
  17. $row =~ s/\r/=r/g;
  18. $row =~ s/\f/=f/g;
  19. $row =~ s/\a/=a/g;
  20. $row =~ s/\e/=e/g;
  21. $row =~ s/([!-\/:-<>-@[-`{-~])/=$1/g; #`
  22. defined($row) or $row = '=9';
  23. $_ = $row . $_;
  24. while(1) {
  25. EOF
  26. # The main loop.
  27. $ilo=0;
  28. $ilocheck=0;
  29. while(<>)
  30. {
  31. chomp; # An input newline will be =n, representing a newline is \n
  32. s/\t/ /;
  33. /^ *\#/ and next; # Ignore comments (lines starting with #).
  34. s/^( *)//;
  35. print $1; # Format the output with the same indentation as the input.
  36. $ilo > length $1 and print "last;}};\n"; # Indentation shows looping.
  37. $ilo < length $1 and $ilocheck and die "Indentation increased illegaly.";
  38. $ilo = length $1;
  39. $ilocheck = 1;
  40. @regexps = split /(?<!\\)\//, $_, -1; # Split on / not preceded by \
  41. $regexps[-1] eq "" and $#regexps--;
  42. $lastexp = $regexps[-1];
  43. $#regexps--; # The last part is going to be special.
  44. $penexp = undef;
  45. $regsep = 'and';
  46. # print 'print "$_\r";'."\n"; # DEBUG
  47. if(/\/$/) # Lines ending with / are replacement lines.
  48. {
  49. $penexp = $regexps[-1];
  50. $#regexps--; # In this case, the penultimate part is also special.
  51. }
  52. elsif($lastexp eq "*") # Loop while the guards and some replacement match.
  53. {
  54. print "while(";
  55. }
  56. elsif($lastexp eq "!") # Loop while no guards but some replacement match.
  57. {
  58. print "while(not(";
  59. $regsep = 'or';
  60. }
  61. elsif($lastexp eq "^") # Check that no guards match at start of the loop.
  62. {
  63. $regsep = 'or';
  64. }
  65. foreach $regexp (@regexps)
  66. {
  67. $regexp and print "/$regexp/ $regsep "; # Guards are just Perl regexps.
  68. }
  69. if(defined($penexp)) # This is a replacement line.
  70. {
  71. print "s/$penexp/$lastexp/ and next;\n";
  72. }
  73. elsif($lastexp eq "<") # Jump back to the start of the block
  74. {
  75. print "next;\n";
  76. }
  77. elsif($lastexp eq ">") # Jump out of this block
  78. {
  79. print "last;\n";
  80. }
  81. elsif($lastexp eq "@") # If the guards are met, loop within this block.
  82. { # The guards are only checked at the start.
  83. $ilo++;
  84. $ilocheck = 0;
  85. print "do {while(1) {\n";
  86. }
  87. elsif($lastexp eq "^") # If no guards are met, loop within this block.
  88. {
  89. $ilo++;
  90. $ilocheck = 0;
  91. print "0 or do {while(1) {\n";
  92. }
  93. elsif($lastexp eq "!") # Loop while a replacement but no guards match.
  94. {
  95. $ilo++;
  96. $ilocheck = 0;
  97. print "0)) {do {\n";
  98. }
  99. elsif($lastexp eq "*") # Loop while the guards and a replacement match.
  100. {
  101. $ilo++;
  102. $ilocheck = 0;
  103. print "1) {do {\n";
  104. }
  105. elsif($lastexp eq ".") # Dedentation marker for multiple dedents
  106. {} # Do nothing.
  107. else {die "Unrecognized row modifier."};
  108. };
  109. # Finishing off.
  110. print << 'EOF';
  111. last; }
  112. s/=9// and $ninequit=1;
  113. if(s/(.*?)=x//) # =x marks the end of what to print out.
  114. {
  115. $row=$1;
  116. $row =~ s/=t/\t/g;
  117. $row =~ s/=n/\n/g; # =n converts back to newline.
  118. $row =~ s/=r/\r/g;
  119. $row =~ s/=f/\f/g;
  120. $row =~ s/=a/\a/g;
  121. $row =~ s/=e/\e/g;
  122. $row =~ s/=([!-\/:-<>-@[-`{-~])/$1/g; #`
  123. $row =~ s/=q/=/g;
  124. # print "\n"; # DEBUG
  125. print $row;
  126. }
  127. $ninequit or $row=<>;
  128. };
  129. EOF