git @ Cat's Eye Technologies SMITH / cc88566
Fix two bugs with string literals; thanks to Keymaker for bug report. catseye 12 years ago
1 changed file(s) with 58 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
11
22 ### smith.pl ###
33
4 # SMITH - Self Modifying Indecent Turing Hack, v2.1-2011.0922
5
6 # Copyright (c)2000-2011, Chris Pressey, Cat's Eye Technologies.
4 # SMITH - Self Modifying Indecent Turing Hack, v2.1-2012.0912
5
6 # Copyright (c)2000-2012, Chris Pressey, Cat's Eye Technologies.
77 # All rights reserved.
88 #
99 # Redistribution and use in source and binary forms, with or without
3333 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3434 # POSSIBILITY OF SUCH DAMAGE.
3535
36 ### SMITH Interpreter v2007.0722 ###
36 ### SMITH Interpreter v2.1-2012.0912 ###
3737
3838 ##############################################################
3939 # "'Look outside,' I said. #
4545 # -- Hunter S. Thompson, _Fear and Loathing in Las Vegas_ #
4646 ##############################################################
4747
48 # Usage: [perl] smith[.pl] [-c] [-d] [-g] [-p] [-q] program.smt
48 # Usage: [perl] smith[.pl] [-c] [-d] [-g] [-p] [-q] [-x] [-y] program.smt
4949 # Options: -c Continue (Don't Break program on Error)
5050 # -d Run in Debugging Mode
5151 # -g Use v2-compatible "goofy copy"
5252 # -p Pause (in conjunction with -d)
5353 # -q Quiet (Don't display messages)
54
54 # -x Expand * even in strings (pre-2012 compat)
55 # -y Use pre-2012-compatible "goofy string literals"
56
57 # Changes in SMITH v2.1-2012.0912:
58 # - Fixed a bug reported by Keymaker: creating a string literal
59 # where one of the characters of the string is written into
60 # the same register used in the indirect register reference, e.g.
61 # MOV R0, 0
62 # MOV R[R0], "hi"
63 # was... goofy; it would take the character written into R0 as the
64 # new reference, and typically jump ahead many registers. This
65 # has been fixed, but the behaviour can be re-enabled with the
66 # -y option (although why you would need this behaviour is beyond me.)
67 # - Fixed a bug not reported by Keymaker, but which would have
68 # affected his example if it had got that far: the * "macro"
69 # was being expanded to the source line number, even in string
70 # literals. This has been turned off, but can be re-enabled
71 # with the -x option.
5572 # Changes in SMITH v2007.0722:
5673 # - Copying instructions over other instructions is now defined
5774 # by the language. Previous implementation of interpreter had
102119 $debug = 0;
103120
104121 # flag to enable v2-compatible "goofy copy" behaviour
105 $goofy = 0;
122 $goofycopy = 0;
123
124 # flag to enable expanding * in string constants (pre-2012 behaviour)
125 $starstr = 0;
126
127 # flag to enable pre-2012 compatible "goofy string literal" behaviour
128 $goofystr = 0;
106129
107130 # flag to pause during debugging
108131 # only works when input is from terminal! :-)
128151 $line = $' if $line =~ /^\s*/;
129152 $line = $` if $line =~ /\s*$/;
130153 $line =~ s/\s*;.*?$//;
131 $line =~ s/\*/$i/ge;
154 if ($starstr or $line !~ /\"(.*?)\"/) {
155 $line =~ s/\*/$i/ge;
156 }
132157 if ($line =~ /^\S+/)
133158 {
134159 my $reps = 1; my $j;
202227 {
203228 my $i = $reg->[$1];
204229 my $s = $2;
205 while($i < ($reg->[$1] + length($s)))
206 {
207 $reg->[$i] = ord(substr($s, ($i-$reg->[$1]), 1)); $i++;
230 if ($goofystr) {
231 while ($i < ($reg->[$1] + length($s)))
232 {
233 $reg->[$i] = ord(substr($s, ($i-$reg->[$1]), 1)); $i++;
234 }
235 } else {
236 my $j = $i;
237 while ($i < $j + length($s))
238 {
239 $reg->[$i] = ord(substr($s, ($i-$j), 1)); $i++;
240 }
208241 }
209242 }
210243 elsif ($mem->[$pc] =~
292325 {
293326 for ($i = 0; $i < $reg->[$lrg]; $i++)
294327 {
295 $mem->[$dst+$i] = $goofy ? $mem->[$src+$i] : $instructions[$i];
328 $mem->[$dst+$i] = $goofycopy ? $mem->[$src+$i] : $instructions[$i];
296329 $ggg = $dst + $i;
297330 $hhh = $src + $i;
298331 print " $ggg = $hhh = $mem->[$ggg]\n" if $debug;
313346 {
314347 for ($i = 0; $i < $reg->[$lrg]; $i++)
315348 {
316 $mem->[$dst+$i] = $goofy ? $mem->[$src+$i] : $instructions[$i];
349 $mem->[$dst+$i] = $goofycopy ? $mem->[$src+$i] : $instructions[$i];
317350 $ggg = $dst + $i;
318351 $hhh = $src + $i;
319352 print " $ggg = $hhh = $mem->[$ggg]\n" if $debug;
366399 {
367400 $debug = 1;
368401 }
369 elsif ($1 eq 'g' or $1 eq 'goofy')
370 {
371 $goofy = 1;
402 elsif ($1 eq 'g' or $1 eq 'goofycopy')
403 {
404 $goofycopy = 1;
372405 }
373406 elsif ($1 eq 'p' or $1 eq 'pause')
374407 {
377410 elsif ($1 eq 'q' or $1 eq 'quiet')
378411 {
379412 $quiet = 1;
413 }
414 elsif ($1 eq 'x' or $1 eq 'starstr')
415 {
416 $starstr = 1;
417 }
418 elsif ($1 eq 'y' or $1 eq 'goofystr')
419 {
420 $goofystr = 1;
380421 }
381422 else
382423 {
387428
388429 ### START ###
389430
390 print "SMITH Interpreter v2.1-2011.0922\n" if not $quiet;
431 print "SMITH Interpreter v2.1-2012.0912\n" if not $quiet;
391432
392433 die "No program filename given" if !defined($ARGV[0]) or $ARGV[0] eq '';
393434 die "Can't find/read file '$ARGV[0]'" if not -r $ARGV[0];