test_deparser.pl 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 13 March 2015
  5. # Website: https://github.com/trizen
  6. #
  7. ## Test the Sidef deparser for consistency.
  8. #
  9. ## Algorithm:
  10. # - parse the code as C1
  11. # - deparse the C1 code as D1
  12. # - parse the D1 code as C2
  13. # - deparse the C2 code as D2
  14. # - if D1 != D2: throw an error
  15. use utf8;
  16. use 5.014;
  17. use strict;
  18. use autodie;
  19. use warnings;
  20. no warnings 'once';
  21. use lib qw(../lib);
  22. use Sidef;
  23. binmode(STDERR, ':utf8');
  24. use File::Find qw(find);
  25. use File::Basename qw(basename);
  26. use File::Spec::Functions qw(catdir updir rel2abs);
  27. sub parse_deparse {
  28. my ($code, $name) = @_;
  29. my $sidef = Sidef->new(name => $name);
  30. my $ast = $sidef->parse_code($code);
  31. my $deparser = Sidef::Deparse::Sidef->new();
  32. my @statements = $deparser->deparse_script($ast);
  33. my $deparsed = $deparser->{before} . join($deparser->{between}, grep { $_ ne '' }@statements) . $deparser->{after};
  34. return ($deparsed, \@statements);
  35. }
  36. my %ignore = ('matrix_class.sf' => 1, 'arrays.sf' => 1);
  37. my $dir = catdir(updir, 'scripts');
  38. find {
  39. wanted => sub { /\.s[fm]\z/ && (-f $_) && test_file($_) },
  40. no_chdir => 1,
  41. } => $dir;
  42. sub test_file {
  43. my ($file) = @_;
  44. my $basename = basename($file);
  45. {
  46. local $| = 1;
  47. printf("** Processing: %s\r", $file);
  48. }
  49. open my $fh, '<:utf8', $file;
  50. my $content = do { local $/; <$fh> };
  51. close $fh;
  52. my ($deparse_1, $statements_1) = parse_deparse($content, $file);
  53. my ($deparse_2, $statements_2) = parse_deparse($deparse_1, $file);
  54. if ($deparse_1 ne $deparse_2) {
  55. require Algorithm::Diff;
  56. my $diff = Algorithm::Diff::diff($statements_1, $statements_2);
  57. if (exists $ignore{$basename}) {
  58. my $count = 0;
  59. $count += @$_ for @{$diff};
  60. say "[!] Detected $count differences on file <<$basename>>, but we're ignoring it...";
  61. return;
  62. }
  63. require Data::Dump;
  64. Data::Dump::pp($diff);
  65. warn "\n[!] Error detected on file: $file\n\n";
  66. }
  67. }