X-Git-Url: http://git.ieval.ro/?p=app-scheme79asm.git;a=blobdiff_plain;f=lib%2FApp%2FScheme79asm%2FCompiler.pm;h=417707f1358cf75a456972b7643fc63b7df1a0d5;hp=d9a420f1aaf03408e16c9dc9fa3ae6dc8e4c2a2e;hb=0fea28cb1073527c855de945782711f89a47e227;hpb=2aba73d532a55cd0cfa7a32b1e9270a15b0b53d7 diff --git a/lib/App/Scheme79asm/Compiler.pm b/lib/App/Scheme79asm/Compiler.pm index d9a420f..417707f 100644 --- a/lib/App/Scheme79asm/Compiler.pm +++ b/lib/App/Scheme79asm/Compiler.pm @@ -3,9 +3,7 @@ package App::Scheme79asm::Compiler; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/pretty_print/; our $VERSION = '0.005'; use Carp qw/croak/; @@ -17,6 +15,22 @@ use List::MoreUtils qw/firstidx/; our @PRIMOPS = qw/car cdr cons atom progn reverse-list/; +sub make_symbol { Data::SExpression::Symbol->new(shift) } + +# types +our $LIST = make_symbol 'LIST'; +our $SYMBOL = make_symbol 'SYMBOL'; +our $VAR = make_symbol 'VAR'; +# no need for closures +our $PROC = make_symbol 'PROC'; +our $IF = make_symbol 'IF'; +our $CALL = make_symbol 'CALL'; +# no need for quoted constants + +# primitives +our $MORE = make_symbol 'MORE'; +our $FUNCALL = make_symbol 'FUNCALL'; + BEGIN { *cons = *Data::SExpression::cons; *consp = *Data::SExpression::consp; @@ -78,27 +92,6 @@ sub position { my ($expr, $list) = @_; positionacc $expr, $list, 0 } - -sub pretty_print { - my ($expr) = @_; - if (!defined $expr) { - '()' - } elsif (scalarp $expr) { - "$expr" - } elsif (ref $expr eq 'ARRAY') { - '(' . join (' ', map { pretty_print($_) } @$expr). ')' - } else { - my $cdr = $expr->cdr; - my $car = $expr->car; - my $acc = '(' . pretty_print($car); - while (defined $cdr) { - $car = $cdr->car; - $cdr = $cdr->cdr; - $acc .= ' ' . pretty_print($car); - } - $acc . ')' - } -} # end list processing routines sub new { @@ -114,20 +107,20 @@ sub new { sub process_quoted { my ($self, $expr) = @_; if (!defined $expr) { # nil - [LIST => 0] + [$LIST => 0] } elsif (scalarp $expr) { $expr = uc $expr; if ($expr eq 'NIL') { - return [LIST => 0] + return [$LIST => 0] } if (!exists $self->{symbol_map}{$expr}) { $self->{symbol_map}{$expr} = $self->{nsymbols}; $self->{nsymbols}++; push @{$self->{symbols}}, $expr; } - [SYMBOL => $self->{symbol_map}{$expr}] + [$SYMBOL => $self->{symbol_map}{$expr}] } elsif (consp $expr) { - [LIST => $self->process_quoted($expr->cdr), $self->process_quoted($expr->car)] + [$LIST => $self->process_quoted($expr->cdr), $self->process_quoted($expr->car)] } else { croak 'argument to process_quoted is not a scalar, cons, or nil: ', Dumper($expr); } @@ -144,7 +137,7 @@ sub rest_of_funcall { if (!defined $args) { $func } else { - [MORE => $self->rest_of_funcall($func, $args->cdr), $args->car] + [$MORE => $self->rest_of_funcall($func, $args->cdr), $args->car] } } @@ -157,28 +150,28 @@ sub process_funcall { if (!defined $processed_args) { croak "Cannot call primitive $func_name with no arguments"; } - [CALL => $self->rest_of_funcall([uc $func_name, 0], $processed_args->cdr), $processed_args->car] + [$CALL => $self->rest_of_funcall([make_symbol(uc $func_name), 0], $processed_args->cdr), $processed_args->car] } else { my $final_args = append $processed_args, cons ($self->process_toplevel($func_name, $env), undef); - [CALL => $self->rest_of_funcall([FUNCALL => 0], $final_args->cdr), $final_args->car] + [$CALL => $self->rest_of_funcall([$FUNCALL => 0], $final_args->cdr), $final_args->car] } } sub process_toplevel { my ($self, $expr, $env) = @_; if (!defined $expr) { - [LIST => 0] + [$LIST => 0] } elsif (scalarp $expr) { if (looks_like_number $expr) { $self->process_quoted($expr); } elsif (uc $expr eq 'T') { - [SYMBOL => 2] + [$SYMBOL => 2] } elsif (uc $expr eq 'NIL') { - [LIST => 0] + [$LIST => 0] } else { my $position = position $expr, $env; if (defined $position) { - [VAR => -1 - $position] + [$VAR => -1 - $position] } else { croak "Variable $expr not in environment"; } @@ -191,12 +184,12 @@ sub process_toplevel { my $func_name = $expr->cdr->car; my $func_args = $expr->cdr->cdr->car; my $func_body = $expr->cdr->cdr->cdr->car; ## no critic (ProhibitLongChainsOfMethodCalls) - [PROC => $self->process_proc($func_name, $func_args, $func_body, $env)] + [$PROC => $self->process_proc($func_name, $func_args, $func_body, $env)] } elsif ($func eq 'IF') { my ($if_cond, $if_then, $if_else) = map { $self->process_toplevel($_, $env) } ($expr->cdr->car, $expr->cdr->cdr->car, $expr->cdr->cdr->cdr->car); ## no critic (ProhibitLongChainsOfMethodCalls) - [IF => [LIST => $if_else, $if_then], $if_cond] + [$IF => [$LIST => $if_else, $if_then], $if_cond] } else { $self->process_funcall($expr->car, $expr->cdr, $env) }