File Coverage

blib/lib/Mylisp.pm
Criterion Covered Total %
statement 32 150 21.3
branch 0 22 0.0
condition n/a
subroutine 11 25 44.0
pod 0 14 0.0
total 43 211 20.3


line stmt bran cond sub pod time code
1             package Mylisp;
2            
3 1     1   87431 use 5.012;
  1         5  
4 1     1   654 use experimental 'switch';
  1         4712  
  1         7  
5            
6 1     1   183 use Exporter;
  1         3  
  1         110  
7             our @ISA = qw(Exporter);
8             our @EXPORT = qw(SppRepl GrammarToAst Parse MyToAst AstToTable Spp LintSppAst UpdateSppAst);
9            
10             our $VERSION = '3.00';
11            
12 1     1   521 use Mylisp::Builtin;
  1         4  
  1         202  
13 1     1   505 use Mylisp::Estr;
  1         5  
  1         163  
14 1     1   490 use Mylisp::SppAst;
  1         4  
  1         61  
15 1     1   462 use Mylisp::SppGrammar;
  1         3  
  1         61  
16 1     1   540 use Mylisp::Match;
  1         4  
  1         79  
17 1     1   503 use Mylisp::OptSppAst;
  1         4  
  1         62  
18 1     1   466 use Mylisp::MyGrammar;
  1         3  
  1         60  
19 1     1   480 use Mylisp::OptMyAst;
  1         3  
  1         2187  
20            
21             sub SppRepl {
22 0     0 0   my $table = get_spp_table();
23 0           say 'This is Spp REPL, type enter to exit.';
24 0           while (1) {
25 0           print '>> ';
26 0           my $line = ;
27 0           $line = trim($line);
28 0 0         exit() if $line eq '';
29 0           my ($match,$ok) = MatchTable($table,$line);
30 0 0         if ($ok) {
31 0           my $ast = clean_ast($match);
32 0           say estr_to_json($ast);
33 0           my $opt_ast = OptSppAst($ast);
34 0           say estr_to_json($opt_ast);
35             }
36             else {
37 0           say $match;
38             }
39             }
40             }
41            
42             sub GrammarToAst {
43 0     0 0   my $grammar = shift;
44 0           my $spp_ast = GetSppAst();
45 0           my $table = AstToTable($spp_ast);
46 0           my ($match,$ok) = MatchTable($table,$grammar);
47 0 0         if (not($ok)) {
48 0           error($match);
49             }
50 0           my $ast = OptSppAst($match);
51 0           LintSppAst($ast);
52 0           return $ast
53             }
54            
55             sub Parse {
56 0     0 0   my ($grammar_file,$text_file) = @_;
57 0           my $grammar = read_file($grammar_file);
58 0           my $text = read_file($text_file);
59 0           my $ast = GrammarToAst($grammar);
60 0           my $table = AstToTable($ast);
61 0           my ($match,$ok) = MatchTable($table,$text);
62 0 0         if (not($ok)) {
63 0           error($match);
64             }
65 0           my $clean_ast = clean_ast($match);
66 0           return estr_to_json($clean_ast)
67             }
68            
69             sub get_my_table {
70 0     0 0   my $grammar = GetMyGrammar();
71 0           my $ast = GrammarToAst($grammar);
72 0           return AstToTable($ast)
73             }
74            
75             sub MyToAst {
76 0     0 0   my $code = shift;
77 0           my $table = get_my_table();
78 0           my ($match,$ok) = MatchTable($table,$code);
79 0 0         if (not($ok)) {
80 0           error($match);
81             }
82 0           return OptMyAst($match)
83             }
84            
85             sub AstToTable {
86 0     0 0   my $ast = shift;
87 0           my $table = {};
88 0           for my $spec (@{atoms($ast)}) {
  0            
89 0           my ($name,$rule) = flat($spec);
90 0 0         if (exists $table->{$name}) {
91 0           say "Repeat define token: |$name|";
92             }
93 0           $table->{$name} = $rule;
94             }
95 0           return $table
96             }
97            
98             sub get_spp_table {
99 0     0 0   my $ast = GetSppAst();
100 0           return AstToTable($ast)
101             }
102            
103             sub Spp {
104 0     0 0   my $file = shift;
105 0           my $grammar = read_file($file);
106 0           my $ast = GrammarToAst($grammar);
107 0           return estr_to_json($ast)
108             }
109            
110             sub LintSppAst {
111 0     0 0   my $ast = shift;
112 0           my $table = {};
113 0           my $values = [];
114 0           for my $atom (@{atoms($ast)}) {
  0            
115 0           my ($name,$value) = flat($atom);
116 0 0         if (exists $table->{$name}) {
117 0           say "repeat define rule: |$name|";
118             }
119             else {
120 0           $table->{$name} = 'define';
121 0           apush($values,$value);
122             }
123             }
124 0           for my $rule (@{$values}) {
  0            
125 0           lint_spp_rule($rule,$table);
126             }
127 0           for my $name (keys %{$table}) {
  0            
128 0 0         next if $name eq 'door';
129 0           my $value = $table->{$name};
130 0 0         if ($value eq 'define') {
131 0           say "not used rule: |$name|";
132             }
133             }
134             }
135            
136             sub lint_spp_rule {
137 0     0 0   my ($rule,$t) = @_;
138 0           my ($name,$atoms) = flat($rule);
139 0 0         if (not($name ~~ ['Any','Str','Char','Cclass','Assert','Chclass','Nclass','Blank'])) {
140 0           given ($name) {
141 0           when ('Ctoken') {
142 0           lint_spp_token($atoms,$t);
143             }
144 0           when ('Ntoken') {
145 0           lint_spp_token($atoms,$t);
146             }
147 0           when ('Rtoken') {
148 0           lint_spp_token($atoms,$t);
149             }
150 0           when ('Till') {
151 0           lint_spp_rule($atoms,$t);
152             }
153 0           when ('Rept') {
154 0           lint_spp_rule(value($atoms),$t);
155             }
156 0           when ('Branch') {
157 0           lint_spp_atoms($atoms,$t);
158             }
159 0           when ('Group') {
160 0           lint_spp_atoms($atoms,$t);
161             }
162 0           when ('Rules') {
163 0           lint_spp_atoms($atoms,$t);
164             }
165 0           default {
166 0           say "lint spp rule-name? |$name|";
167             }
168             }
169             }
170             }
171            
172             sub lint_spp_atoms {
173 0     0 0   my ($atoms,$table) = @_;
174 0           for my $atom (@{atoms($atoms)}) {
  0            
175 0           lint_spp_rule($atom,$table);
176             }
177             }
178            
179             sub lint_spp_token {
180 0     0 0   my ($name,$table) = @_;
181 0 0         if (exists $table->{$name}) {
182 0           $table->{$name} = 'used';
183             }
184             else {
185 0           say "not exists rule: |$name|";
186             }
187             }
188            
189             sub UpdateSppAst {
190 0     0 0   my $grammar = GetSppGrammar;
191 0           my $ast = GrammarToAst($grammar);
192 0           my $json = estr_to_json(clean_ast($ast));
193 0           my $code = ast_to_package($json);
194 0           my $ast_file = 'SppAst.my';
195 0           write_file($ast_file,$code);
196 0           say "update ok! write file $ast_file";
197             }
198            
199             sub ast_to_package {
200 0     0 0   my $estr = shift;
201 0           my $head = '(package Mylisp::SppAst)';
202 0           my $use = '(use Mylisp::Estr)';
203 0           my $func = "(func (GetSppAst) (-> Str) (return (json-to-estr '''";
204 0           return add($head,$use,$func,$estr,"''')))")
205             }
206             1;