Drkcore

12 04 2009 perl Moose Moosp Tweet

MooseでLispを実装してみる(List)

やさしい Lisp の作り方 by Java and by C#を参考に書いてみる。リストの構成にはシンボルが出てこない。

list

名前を付けるということがちょっと分かったような気がした。

シンボルは Lisp の最も重要なデータタイプの一つです。「記号」とか単に「名前」または「識別子」とも呼ばれていました。

シンボルは (1) 1 個以上の値を持つことができる、(2) シンボル名により唯一性が保障されます。(2) の唯一性とは同じ名前のシンボルは同じであることを表しています。もっと正確に言えば、同じ名前のシンボルは、ある等価関数によって必ず T を返す、つまり等価であることを保障します。

とりあえず、動くとこを見たかったので、色々端折ってる。

Atom

package Moosp::Atom;

use Moose;

__PACKAGE__->meta->make_immutable;

no Moose;


1; # End of Moosp::Atom

Number

package Moosp::Number;

use Moose;

extends 'Moosp::Atom';

sub str {}

no Moose;

1; # End of Moosp::Number

Integer

package Moosp::Integer;

use Moose;

extends 'Moosp::Number';
with 'Moosp::Sexp';

has 'value' => (is => 'rw',isa => 'Int');

sub add {
  my ($self, $i) = @_;
  my $new_value = $self->value + $i->value;
  __PACKAGE__->new({value => $new_value});
}

sub subt {
  my ($self, $i) = @_;
  my $new_value = $self->value - $i->value;
  __PACKAGE__->new({value => $new_value});
}

sub mul {
  my ($self, $i) = @_;
  my $new_value = $self->value * $i->value;
  __PACKAGE__->new({value => $new_value});
}

sub div {
  my ($self, $i) = @_;
  my $new_value = int($self->value / $i->value);
  __PACKAGE__->new({value => $new_value});
}

sub ge {
  my ($self, $i) = @_;
  if ($self->value >= $i->value){
    return Moosp::T->new();
  }
  else {
    return Moosp::Nil->new();
  }
}

sub str {
  my $self = shift;
  return $self->value;
}

__PACKAGE__->meta->make_immutable;
no Moose;

1; # End of Moosp::Integer

Cell

package Moosp::Cell;

use Moosp::Nil;
use Moose;

has 'car' => (
          is => 'rw',
          default => sub{ Moosp::Nil->instance }
);

has 'cdr' => (
          is => 'rw',
          default => sub { Moosp::Nil->instance }
);

__PACKAGE__->meta->make_immutable;

no Moose;

1;

List

package Moosp::List;

use Moose;
use Moosp::Nil;
extends 'Moosp::Cell';

sub BUILD {
  my ($self, $car, $cdr) = @_;
  $self->car(Moosp::Nil->instance);
  $self->cdr(Moosp::Nil->instance);
  return $self;
}

sub serialize {
  my $self = shift;
  my $str = "(";
  $str .= $self->car->serialize;
  if (ref($self->cdr) eq 'Moosp::Nil') {
    $str .= ")";
  }
  elsif (ref($self->cdr) eq 'Moosp::List') {
    $str .= " " . $self->cdr->serialize . ")";
  }
  else {
    $str .= " . " . $self->cdr->serialize . ")";
  }
  return $str;
}

1; # End of Moosp::List

test

my $int3 = Moosp::Integer->new(value => 3);
my $int5 = Moosp::Integer->new(value => 5);
my $list = Moosp::List->new();
$list->car($int3);
$list->cdr($int5); # (3 . 5)

my $list2 = Moosp::List->new();
$list2->car($int3);
$list2->cdr($list);  # (3 (3 . 5))

print $list2->cdr->car->value # cadr -> 3

About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021