From 2d3dbdc3f8221710f6ea9c9a68753148fca4ef86 Mon Sep 17 00:00:00 2001 From: Carl Masak Date: Sat, 17 Jul 2021 00:24:48 +0800 Subject: [PATCH 1/3] Factor passes into a class hierarchy I have a limited belief in class hierarchies. But I'm largely fine with using base classes as interfaces. That's what's happening here, all the passes are an implementation (rather than a derived class) of an abstract class (interface) `Pass`, of which we expect certain things. --- lib/Language/Bel/Compiler.pm | 29 +++++++++++++++-------------- lib/Language/Bel/Compiler/Pass.pm | 24 ++++++++++++++++++++++++ lib/Language/Bel/Compiler/Pass01.pm | 15 ++++++++------- lib/Language/Bel/Compiler/Pass02.pm | 17 +++++++++-------- lib/Language/Bel/Compiler/Pass03.pm | 15 ++++++++------- 5 files changed, 64 insertions(+), 36 deletions(-) create mode 100644 lib/Language/Bel/Compiler/Pass.pm diff --git a/lib/Language/Bel/Compiler.pm b/lib/Language/Bel/Compiler.pm index 1eb19773..7e525fd5 100644 --- a/lib/Language/Bel/Compiler.pm +++ b/lib/Language/Bel/Compiler.pm @@ -4,30 +4,31 @@ use 5.006; use strict; use warnings; -use Language::Bel::Compiler::Pass01 qw( - nanopass_01_alpha -); -use Language::Bel::Compiler::Pass02 qw( - nanopass_02_flatten -); -use Language::Bel::Compiler::Pass03 qw( - nanopass_03_allocate_registers -); +use Language::Bel::Compiler::Pass01; +use Language::Bel::Compiler::Pass02; +use Language::Bel::Compiler::Pass03; use Language::Bel::Compiler::Generator qw( generate_bytefunc ); use Exporter 'import'; +my @PASSES = ( + Language::Bel::Compiler::Pass01->new(), + Language::Bel::Compiler::Pass02->new(), + Language::Bel::Compiler::Pass03->new(), +); + sub compile { my ($source) = @_; - my $_00 = read_whole($source); - my $_01 = nanopass_01_alpha($_00); - my $_02 = nanopass_02_flatten($_01); - my $_03 = nanopass_03_allocate_registers($_02); + my $program = read_whole($source); + + for my $nanopass (@PASSES) { + $program = $nanopass->translate($program); + } - return generate_bytefunc($_03); + return generate_bytefunc($program); } our @EXPORT_OK = qw( diff --git a/lib/Language/Bel/Compiler/Pass.pm b/lib/Language/Bel/Compiler/Pass.pm new file mode 100644 index 00000000..6653e089 --- /dev/null +++ b/lib/Language/Bel/Compiler/Pass.pm @@ -0,0 +1,24 @@ +package Language::Bel::Compiler::Pass; + +use 5.006; +use strict; +use warnings; + +sub new { + my ($class, $name) = @_; + + return bless({ + name => $name, + }, $class); +} + +# abstract +sub translate { + my ($self) = @_; + + my $name = $self->{name}; + + die "The [$name] pass doesn't implement a 'translate' method"; +} + +1; diff --git a/lib/Language/Bel/Compiler/Pass01.pm b/lib/Language/Bel/Compiler/Pass01.pm index 0969e7b4..480f1a91 100644 --- a/lib/Language/Bel/Compiler/Pass01.pm +++ b/lib/Language/Bel/Compiler/Pass01.pm @@ -1,4 +1,5 @@ package Language::Bel::Compiler::Pass01; +use base qw(Language::Bel::Compiler::Pass); use 5.006; use strict; @@ -24,7 +25,11 @@ use Language::Bel::Compiler::Gensym qw( gensym ); -use Exporter 'import'; +sub new { + my ($class) = @_; + + return $class->SUPER::new("alpha"); +} sub replace_variables { my ($ast, $translation_ref) = @_; @@ -43,8 +48,8 @@ sub replace_variables { } } -sub nanopass_01_alpha { - my ($ast) = @_; +sub translate { + my ($self, $ast) = @_; $ast = cdr($ast); my $fn_name = car($ast); @@ -81,8 +86,4 @@ sub nanopass_01_alpha { ); } -our @EXPORT_OK = qw( - nanopass_01_alpha -); - 1; diff --git a/lib/Language/Bel/Compiler/Pass02.pm b/lib/Language/Bel/Compiler/Pass02.pm index 976b6f42..d0bb4ad2 100644 --- a/lib/Language/Bel/Compiler/Pass02.pm +++ b/lib/Language/Bel/Compiler/Pass02.pm @@ -1,4 +1,5 @@ package Language::Bel::Compiler::Pass02; +use base qw(Language::Bel::Compiler::Pass); use 5.006; use strict; @@ -28,13 +29,17 @@ use Language::Bel::Compiler::Primitives qw( cdr ); -use Exporter 'import'; - my %arg_count_of = ( "id" => 2, "type" => 1, ); +sub new { + my ($class) = @_; + + return $class->SUPER::new("flatten"); +} + sub is_primitive { my ($op) = @_; @@ -130,8 +135,8 @@ sub listify { return $list; } -sub nanopass_02_flatten { - my ($ast) = @_; +sub translate { + my ($self, $ast) = @_; $ast = cdr($ast); # skipping $fn_name @@ -166,8 +171,4 @@ sub nanopass_02_flatten { ); } -our @EXPORT_OK = qw( - nanopass_02_flatten -); - 1; diff --git a/lib/Language/Bel/Compiler/Pass03.pm b/lib/Language/Bel/Compiler/Pass03.pm index 11f85e35..01f710b5 100644 --- a/lib/Language/Bel/Compiler/Pass03.pm +++ b/lib/Language/Bel/Compiler/Pass03.pm @@ -1,4 +1,5 @@ package Language::Bel::Compiler::Pass03; +use base qw(Language::Bel::Compiler::Pass); use 5.006; use strict; @@ -18,7 +19,11 @@ use Language::Bel::Compiler::Primitives qw( cdr ); -use Exporter 'import'; +sub new { + my ($class) = @_; + + return $class->SUPER::new("allocate-registers"); +} sub substitute_registers { my ($expr) = @_; @@ -37,8 +42,8 @@ sub substitute_registers { } } -sub nanopass_03_allocate_registers { - my ($ast) = @_; +sub translate { + my ($self, $ast) = @_; $ast = cdr($ast); my $args = substitute_registers(car($ast)); @@ -54,8 +59,4 @@ sub nanopass_03_allocate_registers { ); } -our @EXPORT_OK = qw( - nanopass_03_allocate_registers -); - 1; From d7a5c2acb45b3fde8e219b278264306d2a819770 Mon Sep 17 00:00:00 2001 From: Carl Masak Date: Sat, 17 Jul 2021 00:45:19 +0800 Subject: [PATCH 2/3] Rename modules Names are better than numbers. --- lib/Language/Bel/Compiler.pm | 12 ++++++------ .../{Pass03.pm => Pass/AllocateRegisters.pm} | 2 +- .../Bel/Compiler/{Pass01.pm => Pass/Alpha.pm} | 2 +- .../Bel/Compiler/{Pass02.pm => Pass/Flatten.pm} | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename lib/Language/Bel/Compiler/{Pass03.pm => Pass/AllocateRegisters.pm} (94%) rename lib/Language/Bel/Compiler/{Pass01.pm => Pass/Alpha.pm} (97%) rename lib/Language/Bel/Compiler/{Pass02.pm => Pass/Flatten.pm} (98%) diff --git a/lib/Language/Bel/Compiler.pm b/lib/Language/Bel/Compiler.pm index 7e525fd5..44d3f7c2 100644 --- a/lib/Language/Bel/Compiler.pm +++ b/lib/Language/Bel/Compiler.pm @@ -4,9 +4,9 @@ use 5.006; use strict; use warnings; -use Language::Bel::Compiler::Pass01; -use Language::Bel::Compiler::Pass02; -use Language::Bel::Compiler::Pass03; +use Language::Bel::Compiler::Pass::AllocateRegisters; +use Language::Bel::Compiler::Pass::Alpha; +use Language::Bel::Compiler::Pass::Flatten; use Language::Bel::Compiler::Generator qw( generate_bytefunc ); @@ -14,9 +14,9 @@ use Language::Bel::Compiler::Generator qw( use Exporter 'import'; my @PASSES = ( - Language::Bel::Compiler::Pass01->new(), - Language::Bel::Compiler::Pass02->new(), - Language::Bel::Compiler::Pass03->new(), + Language::Bel::Compiler::Pass::Alpha->new(), + Language::Bel::Compiler::Pass::Flatten->new(), + Language::Bel::Compiler::Pass::AllocateRegisters->new(), ); sub compile { diff --git a/lib/Language/Bel/Compiler/Pass03.pm b/lib/Language/Bel/Compiler/Pass/AllocateRegisters.pm similarity index 94% rename from lib/Language/Bel/Compiler/Pass03.pm rename to lib/Language/Bel/Compiler/Pass/AllocateRegisters.pm index 01f710b5..d2dbba94 100644 --- a/lib/Language/Bel/Compiler/Pass03.pm +++ b/lib/Language/Bel/Compiler/Pass/AllocateRegisters.pm @@ -1,4 +1,4 @@ -package Language::Bel::Compiler::Pass03; +package Language::Bel::Compiler::Pass::AllocateRegisters; use base qw(Language::Bel::Compiler::Pass); use 5.006; diff --git a/lib/Language/Bel/Compiler/Pass01.pm b/lib/Language/Bel/Compiler/Pass/Alpha.pm similarity index 97% rename from lib/Language/Bel/Compiler/Pass01.pm rename to lib/Language/Bel/Compiler/Pass/Alpha.pm index 480f1a91..2af70df9 100644 --- a/lib/Language/Bel/Compiler/Pass01.pm +++ b/lib/Language/Bel/Compiler/Pass/Alpha.pm @@ -1,4 +1,4 @@ -package Language::Bel::Compiler::Pass01; +package Language::Bel::Compiler::Pass::Alpha; use base qw(Language::Bel::Compiler::Pass); use 5.006; diff --git a/lib/Language/Bel/Compiler/Pass02.pm b/lib/Language/Bel/Compiler/Pass/Flatten.pm similarity index 98% rename from lib/Language/Bel/Compiler/Pass02.pm rename to lib/Language/Bel/Compiler/Pass/Flatten.pm index d0bb4ad2..97b700ce 100644 --- a/lib/Language/Bel/Compiler/Pass02.pm +++ b/lib/Language/Bel/Compiler/Pass/Flatten.pm @@ -1,4 +1,4 @@ -package Language::Bel::Compiler::Pass02; +package Language::Bel::Compiler::Pass::Flatten; use base qw(Language::Bel::Compiler::Pass); use 5.006; From b3d971c73bed986ff61a100a5e1720e97a3f48d1 Mon Sep 17 00:00:00 2001 From: Carl Masak Date: Sat, 17 Jul 2021 01:05:57 +0800 Subject: [PATCH 3/3] Simplify pass generation --- lib/Language/Bel/Compiler.pm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/Language/Bel/Compiler.pm b/lib/Language/Bel/Compiler.pm index 44d3f7c2..d613dc01 100644 --- a/lib/Language/Bel/Compiler.pm +++ b/lib/Language/Bel/Compiler.pm @@ -13,11 +13,17 @@ use Language::Bel::Compiler::Generator qw( use Exporter 'import'; -my @PASSES = ( - Language::Bel::Compiler::Pass::Alpha->new(), - Language::Bel::Compiler::Pass::Flatten->new(), - Language::Bel::Compiler::Pass::AllocateRegisters->new(), -); +sub make_pass { + my ($name) = @_; + + return "Language::Bel::Compiler::Pass::$name"->new(); +} + +my @PASSES = map { make_pass($_) } qw< + Alpha + Flatten + AllocateRegisters +>; sub compile { my ($source) = @_;