$addr = $self->process($addr) if ref $addr eq 'ARRAY';
die 'Addr of toplevel is not atom: ', Dumper($addr), "\n" unless scalarp($addr);
+ my ($comment_type, $comment_addr) = ($type, $addr);
+
unless (looks_like_number $addr) { # is symbol
unless (exists $self->{symbols}{$addr}) {
$self->{symbols}{$addr} = $self->{nsymbols};
$location = $self->{freeptr}
}
$self->{memory}[$location] = $result;
+ $self->{comment}[$location] = "$comment_type $comment_addr";
$location
}
sub finish {
my ($self) = @_;
$self->{memory}[5] = $self->{memory}[$self->{freeptr}];
+ $self->{comment}[5] = $self->{comment}[$self->{freeptr}];
$self->{memory}[4] = $self->{freeptr};
delete $self->{memory}[$self->{freeptr}]
}
$args{symbols}{NIL} = 0;
$args{symbols}{T} = 1;
$args{nsymbols} = 2;
+ $args{comment} = ['(cdr part of NIL)', '(car part of NIL)', '(cdr part of T)', '(car part of T)', '(free storage pointer)', '', '(result of computation)'];
bless \%args, $class
}
$fh //= \*STDOUT;
my $bits = $self->{type_bits} + $self->{addr_bits};
+ my $index_length = length $#{$self->{memory}};
+ my $index_format = '%' . $index_length . 'd';
for my $index (0 .. $#{$self->{memory}}) {
my $val = $self->{memory}[$index];
+ my $comment = $self->{comment}[$index];
if ($index == 4) {
$val = "${bits}'d$val"
} else {
$val = $val ? sprintf "%d'b%0${bits}b", $bits, $val : '0';
}
- say $fh "mem[$index] <= $val;"
+ my $spaces = ' ' x ($bits + 5 - (length $val));
+ $index = sprintf $index_format, $index;
+ say $fh "mem[$index] <= $val;$spaces // $comment"
}
}
use App::Scheme79asm;
my $asm = App::Scheme79asm->new(type_bits => 3, addr_bits => 5);
- $asm->parse_and_print('(number . 70)');
+ $asm->parse_and_print('(number 70)');
=head1 DESCRIPTION
-B<NOTE:> this module does not do much at the moment.
-
SIMPLE is a LISP processor defined in the 1979
B<Design of LISP-Based Processors> paper by Steele and Sussman.
The SIMPLE processor expects input in a particular tagged-pointer
format. This module takes a string containing a sequence of
-S-expressions of the form C<(tag . value)> representing a tagged
-pointer. Here the tag is either a number or one of several predefined
-values (see the source for a full list), and the value is either a
-number or another tagged pointer. These values are laid out in memory
-and a block of verilog code assigning the memory contents to an array
-named C<mem> is printed.
+S-expressions. Each S-expression is a list of one of three types:
+
+C<(tag value)>, for example C<(symbol nil)>, represents a value to be
+put in memory (for example a number, or a symbol, or a variable
+reference).
+
+C<(tag list)>, where C<list> is of one of these three types,
+represents a tagged pointer. In this case, C<list> is (recursively)
+laid out in memory as per these rules, and a pointer to that location
+(and tagged C<tag>) is put somewhere in memory.
+
+C<(tag list1 list2)>, where C<list1> and C<list2> are of one of these
+three types (not necessarily the same type). In this case, C<list1>
+and C<list2> are (recursively) laid out in memory such that C<list1>
+is at position X and C<list2> is at position X+1, and a pointer of
+type tag and value X is put somewhere in memory.
+
+After this process the very last pointer placed in memory is moved to
+the special location 5 (which is where SIMPLE expects to find the
+expression to be evaluated).
+
+In normal use a single S-expression will be supplied, representing an
+entire program.
+
+The B<parse_and_print> method takes such a string and prints a block
+of verilog code assigning the memory contents to an array named
+C<mem>.
More documentation and features to follow.