]> iEval git - app-scheme79asm.git/blobdiff - lib/App/Scheme79asm.pm
Bump version and update Changes
[app-scheme79asm.git] / lib / App / Scheme79asm.pm
index e0bec36c64c32388335bd625fbacf63b36c6b0ed..61305f7abe2de7751211ba7f6a790ea2240a4f5d 100644 (file)
@@ -8,7 +8,7 @@ use Data::Dumper qw/Dumper/;
 use Data::SExpression qw/consp scalarp/;
 use Scalar::Util qw/looks_like_number/;
 
-our $VERSION = '0.001';
+our $VERSION = '0.001001';
 
 our %TYPES = (
        LIST => 0,
@@ -58,6 +58,8 @@ sub process {
        $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};
@@ -83,6 +85,7 @@ sub process {
                $location = $self->{freeptr}
        }
        $self->{memory}[$location] = $result;
+       $self->{comment}[$location] = "$comment_type $comment_addr";
        $location
 }
 
@@ -101,6 +104,7 @@ sub parse {
 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}]
 }
@@ -114,6 +118,7 @@ sub new {
        $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
 }
 
@@ -122,14 +127,19 @@ sub print {
        $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"
        }
 }
 
@@ -153,23 +163,42 @@ App::Scheme79asm - assemble sexp to Verilog ROM for SIMPLE processor
 
   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.
 
This page took 0.028621 seconds and 4 git commands to generate.