File Coverage

blib/lib/Lox/AstPrinter.pm
Criterion Covered Total %
statement 6 72 8.3
branch 0 10 0.0
condition 0 2 0.0
subroutine 2 28 7.1
pod 0 26 0.0
total 8 138 5.8


line stmt bran cond sub pod time code
1             package Lox::AstPrinter;
2 1     1   6 use strict;
  1         1  
  1         81  
3 1     1   6 use warnings;
  1         2  
  1         1830  
4             our $VERSION = 0.02;
5              
6 0     0 0   sub new { bless {}, shift }
7              
8             sub print_tree {
9 0     0 0   my ($self, $stmts) = @_;
10 0           return join "\n", grep { /\S/ } split "\n", $self->parenthesize(@$stmts);
  0            
11             }
12              
13             sub visit_break_stmt {
14 0     0 0   my ($self, $stmt) = @_;
15 0           return $self->parenthesize('break');
16             }
17              
18             sub visit_class_stmt {
19 0     0 0   my ($self, $stmt) = @_;
20 0           return $self->parenthesize('class', $stmt->name, $stmt->methods->@*);
21             }
22              
23             sub visit_expression_stmt {
24 0     0 0   my ($self, $stmt) = @_;
25 0           return $self->parenthesize($stmt->expression);
26             }
27              
28             sub visit_return_stmt {
29 0     0 0   my ($self, $stmt) = @_;
30 0           return $self->parenthesize('return', $stmt->value);
31             }
32              
33             sub visit_print_stmt {
34 0     0 0   my ($self, $stmt) = @_;
35 0           return $self->parenthesize('print', $stmt->expression);
36             }
37              
38             sub visit_var_stmt {
39 0     0 0   my ($self, $stmt) = @_;
40 0           my @expressions = ('var', $stmt->name, '=');
41 0 0         push @expressions, $stmt->initializer if $stmt->initializer;
42 0           return $self->parenthesize(@expressions);
43             }
44              
45             sub visit_while_stmt {
46 0     0 0   my ($self, $stmt) = @_;
47 0           return $self->parenthesize('while', $stmt->condition, $stmt->body);
48             }
49              
50             sub visit_function_stmt {
51 0     0 0   my ($self, $stmt) = @_;
52 0           my @expressions = ('fun', $stmt->name, '(');
53 0 0         push @expressions, $stmt->params->@* if $stmt->params->@*;
54 0           return $self->parenthesize(@expressions, ')', $stmt->body->@*);
55             }
56              
57             sub visit_function_expr {
58 0     0 0   my ($self, $expr) = @_;
59 0           my @expressions = ('fun', '(');
60 0 0         push @expressions, $expr->params->@* if $expr->params->@*;
61 0           return $self->parenthesize(@expressions, ')', $expr->body->@*);
62             }
63              
64             sub visit_if_stmt {
65 0     0 0   my ($self, $stmt) = @_;
66 0           my @expressions = ('if', $stmt->condition, $stmt->then_branch);
67 0 0         push @expressions, $stmt->else_branch if $stmt->else_branch;
68 0           return $self->parenthesize(@expressions);
69             }
70              
71             sub visit_block_stmt {
72 0     0 0   my ($self, $stmt) = @_;
73 0           return $self->parenthesize($stmt->statements->@*);
74             }
75              
76             sub visit_unary_expr {
77 0     0 0   my ($self, $expr) = @_;
78 0           return $self->parenthesize($expr->operator,$expr->right);
79             }
80              
81             sub visit_binary_expr {
82 0     0 0   my ($self, $expr) = @_;
83 0           return $self->parenthesize($expr->left,$expr->operator,$expr->right);
84             }
85              
86             sub visit_assign_expr {
87 0     0 0   my ($self, $expr) = @_;
88 0           return $self->parenthesize($expr->name,'=',$expr->value);
89             }
90              
91             sub visit_call_expr {
92 0     0 0   my ($self, $expr) = @_;
93 0           return $self->parenthesize($expr->callee, $expr->arguments->@*);
94             }
95              
96             sub visit_set_expr {
97 0     0 0   my ($self, $expr) = @_;
98 0           return $self->parenthesize($expr->object, '.', $expr->name, '(', $expr->value, ')');
99             }
100              
101             sub visit_this_expr {
102 0     0 0   my ($self, $expr) = @_;
103 0           return $expr->keyword->lexeme;
104             }
105              
106             sub visit_variable_expr {
107 0     0 0   my ($self, $expr) = @_;
108 0           return $expr->name->lexeme;
109             }
110              
111             sub visit_get_expr {
112 0     0 0   my ($self, $expr) = @_;
113 0           return $self->parenthesize($expr->object, '.', $expr->name, '()');
114             }
115              
116             sub visit_grouping_expr {
117 0     0 0   my ($self, $expr) = @_;
118 0           return $self->parenthesize($expr->expression);
119             }
120              
121             sub visit_literal_expr {
122 0     0 0   my ($self, $expr) = @_;
123 0           return $expr->value;
124             }
125              
126             sub visit_logical_expr {
127 0     0 0   my ($self, $expr) = @_;
128 0           return $self->visit_binary($expr);
129             }
130              
131             sub visit_token {
132 0     0 0   my ($self, $token) = @_;
133 0           return $token->lexeme;
134             }
135              
136             my $column = 0;
137             sub parenthesize {
138 0     0 0   my ($self, @expr) = @_;
139 0   0       my $indent = ' ' x $column // '';
140 0           $column += 2;
141 0 0         my $values = join ' ', map { ref $_ ? $_->accept($self) : $_ } @expr;
  0            
142 0           my $parenthesized = "\n$indent(\n$indent $values\n$indent)";
143 0           $column -= 2;
144 0           return $parenthesized;
145             }
146              
147             1;