• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015 PLUMgrid, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "printer.h"
18 #include "lexer.h"
19 #include "bcc_exception.h"
20 
21 namespace ebpf {
22 namespace cc {
23 
print_indent()24 void Printer::print_indent() {
25   fprintf(out_, "%*s", indent_, "");
26 }
27 
visit_block_stmt_node(BlockStmtNode * n)28 StatusTuple Printer::visit_block_stmt_node(BlockStmtNode* n) {
29   fprintf(out_, "{\n");
30 
31   if (!n->stmts_.empty()) {
32     ++indent_;
33     for (auto it = n->stmts_.begin(); it != n->stmts_.end(); ++it) {
34       print_indent();
35       TRY2((*it)->accept(this));
36       fprintf(out_, "\n");
37     }
38     --indent_;
39   }
40   fprintf(out_, "%*s}", indent_, "");
41   return StatusTuple(0);
42 }
43 
visit_if_stmt_node(IfStmtNode * n)44 StatusTuple Printer::visit_if_stmt_node(IfStmtNode* n) {
45   fprintf(out_, "if ");
46   TRY2(n->cond_->accept(this));
47   fprintf(out_, " ");
48   TRY2(n->true_block_->accept(this));
49   if (n->false_block_) {
50     fprintf(out_, " else ");
51     TRY2(n->false_block_->accept(this));
52   }
53   return StatusTuple(0);
54 }
55 
visit_onvalid_stmt_node(OnValidStmtNode * n)56 StatusTuple Printer::visit_onvalid_stmt_node(OnValidStmtNode* n) {
57   fprintf(out_, "if ");
58   TRY2(n->cond_->accept(this));
59   fprintf(out_, " ");
60   TRY2(n->block_->accept(this));
61   if (n->else_block_) {
62     fprintf(out_, " else ");
63     TRY2(n->else_block_->accept(this));
64   }
65   return StatusTuple(0);
66 }
67 
visit_switch_stmt_node(SwitchStmtNode * n)68 StatusTuple Printer::visit_switch_stmt_node(SwitchStmtNode* n) {
69   fprintf(out_, "switch (");
70   TRY2(n->cond_->accept(this));
71   fprintf(out_, ") ");
72   TRY2(n->block_->accept(this));
73   return StatusTuple(0);
74 }
75 
visit_case_stmt_node(CaseStmtNode * n)76 StatusTuple Printer::visit_case_stmt_node(CaseStmtNode* n) {
77   if (n->value_) {
78     fprintf(out_, "case ");
79     TRY2(n->value_->accept(this));
80   } else {
81     fprintf(out_, "default");
82   }
83   TRY2(n->block_->accept(this));
84   return StatusTuple(0);
85 }
86 
visit_ident_expr_node(IdentExprNode * n)87 StatusTuple Printer::visit_ident_expr_node(IdentExprNode* n) {
88   if (n->scope_name_.size()) {
89     fprintf(out_, "%s::", n->scope_name_.c_str());
90   }
91   fprintf(out_, "%s", n->name_.c_str());
92   if (n->sub_name_.size()) {
93     fprintf(out_, ".%s", n->sub_name_.c_str());
94   }
95   return StatusTuple(0);
96 }
97 
visit_assign_expr_node(AssignExprNode * n)98 StatusTuple Printer::visit_assign_expr_node(AssignExprNode* n) {
99   TRY2(n->lhs_->accept(this));
100   fprintf(out_, " = ");
101   TRY2(n->rhs_->accept(this));
102   return StatusTuple(0);
103 }
104 
visit_packet_expr_node(PacketExprNode * n)105 StatusTuple Printer::visit_packet_expr_node(PacketExprNode* n) {
106   fprintf(out_, "$");
107   TRY2(n->id_->accept(this));
108   return StatusTuple(0);
109 }
110 
visit_integer_expr_node(IntegerExprNode * n)111 StatusTuple Printer::visit_integer_expr_node(IntegerExprNode* n) {
112   fprintf(out_, "%s:%zu", n->val_.c_str(), n->bits_);
113   return StatusTuple(0);
114 }
115 
visit_string_expr_node(StringExprNode * n)116 StatusTuple Printer::visit_string_expr_node(StringExprNode *n) {
117   fprintf(out_, "%s", n->val_.c_str());
118   return StatusTuple(0);
119 }
120 
visit_binop_expr_node(BinopExprNode * n)121 StatusTuple Printer::visit_binop_expr_node(BinopExprNode* n) {
122   TRY2(n->lhs_->accept(this));
123   fprintf(out_, "%d", n->op_);
124   TRY2(n->rhs_->accept(this));
125   return StatusTuple(0);
126 }
127 
visit_unop_expr_node(UnopExprNode * n)128 StatusTuple Printer::visit_unop_expr_node(UnopExprNode* n) {
129   const char* s = "";
130   switch (n->op_) {
131     case Tok::TNOT: s = "!"; break;
132     case Tok::TCMPL: s = "~"; break;
133     case Tok::TMOD:  s = "%"; break;
134     default: {}
135   }
136   fprintf(out_, "%s", s);
137   TRY2(n->expr_->accept(this));
138   return StatusTuple(0);
139 }
140 
visit_bitop_expr_node(BitopExprNode * n)141 StatusTuple Printer::visit_bitop_expr_node(BitopExprNode* n) {
142 
143   return StatusTuple(0);
144 }
145 
visit_return_expr_node(ReturnExprNode * n)146 StatusTuple Printer::visit_return_expr_node(ReturnExprNode* n) {
147   fprintf(out_, "return ");
148   TRY2(n->expr_->accept(this));
149   return StatusTuple(0);
150 }
151 
visit_goto_expr_node(GotoExprNode * n)152 StatusTuple Printer::visit_goto_expr_node(GotoExprNode* n) {
153   const char* s = n->is_continue_ ? "continue " : "goto ";
154   fprintf(out_, "%s", s);
155   TRY2(n->id_->accept(this));
156   return StatusTuple(0);
157 }
158 
visit_method_call_expr_node(MethodCallExprNode * n)159 StatusTuple Printer::visit_method_call_expr_node(MethodCallExprNode* n) {
160   TRY2(n->id_->accept(this));
161   fprintf(out_, "(");
162   for (auto it = n->args_.begin(); it != n->args_.end(); ++it) {
163     TRY2((*it)->accept(this));
164     if (it + 1 != n->args_.end()) {
165       fprintf(out_, ", ");
166     }
167   }
168   fprintf(out_, ")");
169   if (!n->block_->stmts_.empty()) {
170     fprintf(out_, " {\n");
171     ++indent_;
172     for (auto it = n->block_->stmts_.begin(); it != n->block_->stmts_.end(); ++it) {
173       print_indent();
174       TRY2((*it)->accept(this));
175       fprintf(out_, "\n");
176     }
177     --indent_;
178     fprintf(out_, "%*s}", indent_, "");
179   }
180   return StatusTuple(0);
181 }
182 
visit_table_index_expr_node(TableIndexExprNode * n)183 StatusTuple Printer::visit_table_index_expr_node(TableIndexExprNode *n) {
184   fprintf(out_, "%s[", n->id_->c_str());
185   TRY2(n->index_->accept(this));
186   fprintf(out_, "]");
187   return StatusTuple(0);
188 }
189 
visit_expr_stmt_node(ExprStmtNode * n)190 StatusTuple Printer::visit_expr_stmt_node(ExprStmtNode* n) {
191   TRY2(n->expr_->accept(this));
192   return StatusTuple(0);
193 }
194 
visit_struct_variable_decl_stmt_node(StructVariableDeclStmtNode * n)195 StatusTuple Printer::visit_struct_variable_decl_stmt_node(StructVariableDeclStmtNode* n) {
196   fprintf(out_, "var ");
197   TRY2(n->struct_id_->accept(this));
198   fprintf(out_, " ");
199   TRY2(n->id_->accept(this));
200   if (!n->init_.empty()) {
201     fprintf(out_, "{");
202     for (auto it = n->init_.begin(); it != n->init_.end(); ++it) {
203       TRY2((*it)->accept(this));
204       if (it + 1 != n->init_.end()) {
205         fprintf(out_, ", ");
206       }
207     }
208     fprintf(out_, "}");
209   }
210   return StatusTuple(0);
211 }
212 
visit_integer_variable_decl_stmt_node(IntegerVariableDeclStmtNode * n)213 StatusTuple Printer::visit_integer_variable_decl_stmt_node(IntegerVariableDeclStmtNode* n) {
214   fprintf(out_, "var ");
215   TRY2(n->id_->accept(this));
216   fprintf(out_, ":%zu", n->bit_width_);
217   if (!n->init_.empty()) {
218     fprintf(out_, "; ");
219     TRY2(n->init_[0]->accept(this));
220   }
221   return StatusTuple(0);
222 }
223 
visit_struct_decl_stmt_node(StructDeclStmtNode * n)224 StatusTuple Printer::visit_struct_decl_stmt_node(StructDeclStmtNode* n) {
225   fprintf(out_, "struct ");
226   TRY2(n->id_->accept(this));
227   fprintf(out_, " {\n");
228   ++indent_;
229   for (auto it = n->stmts_.begin(); it != n->stmts_.end(); ++it) {
230     print_indent();
231     TRY2((*it)->accept(this));
232     fprintf(out_, "\n");
233   }
234   --indent_;
235   fprintf(out_, "%*s}", indent_, "");
236   return StatusTuple(0);
237 }
238 
visit_state_decl_stmt_node(StateDeclStmtNode * n)239 StatusTuple Printer::visit_state_decl_stmt_node(StateDeclStmtNode* n) {
240   if (!n->id_) {
241     return StatusTuple(0);
242   }
243   fprintf(out_, "state ");
244   TRY2(n->id_->accept(this));
245   //if (!n->id2_) {
246   //  fprintf(out_, ", * ");
247   //} else {
248   //  fprintf(out_, ", ");
249   //  TRY2(n->id2_->accept(this));
250   //}
251   //TRY2(n->block_->accept(this));
252   return StatusTuple(0);
253 }
254 
visit_parser_state_stmt_node(ParserStateStmtNode * n)255 StatusTuple Printer::visit_parser_state_stmt_node(ParserStateStmtNode* n) {
256   return StatusTuple(0);
257 }
258 
visit_match_decl_stmt_node(MatchDeclStmtNode * n)259 StatusTuple Printer::visit_match_decl_stmt_node(MatchDeclStmtNode* n) {
260   fprintf(out_, "on_match ");
261   TRY2(n->id_->accept(this));
262   fprintf(out_, " (");
263   for (auto it = n->formals_.begin(); it != n->formals_.end(); ++it) {
264     TRY2((*it)->accept(this));
265     if (it + 1 != n->formals_.end()) {
266       fprintf(out_, ", ");
267     }
268   }
269   fprintf(out_, ") ");
270   TRY2(n->block_->accept(this));
271   return StatusTuple(0);
272 }
273 
visit_miss_decl_stmt_node(MissDeclStmtNode * n)274 StatusTuple Printer::visit_miss_decl_stmt_node(MissDeclStmtNode* n) {
275   fprintf(out_, "on_miss ");
276   TRY2(n->id_->accept(this));
277   fprintf(out_, " (");
278   for (auto it = n->formals_.begin(); it != n->formals_.end(); ++it) {
279     TRY2((*it)->accept(this));
280     if (it + 1 != n->formals_.end()) {
281       fprintf(out_, ", ");
282     }
283   }
284   fprintf(out_, ") ");
285   TRY2(n->block_->accept(this));
286   return StatusTuple(0);
287 }
288 
visit_failure_decl_stmt_node(FailureDeclStmtNode * n)289 StatusTuple Printer::visit_failure_decl_stmt_node(FailureDeclStmtNode* n) {
290   fprintf(out_, "on_failure ");
291   TRY2(n->id_->accept(this));
292   fprintf(out_, " (");
293   for (auto it = n->formals_.begin(); it != n->formals_.end(); ++it) {
294     TRY2((*it)->accept(this));
295     if (it + 1 != n->formals_.end()) {
296       fprintf(out_, ", ");
297     }
298   }
299   fprintf(out_, ") ");
300   TRY2(n->block_->accept(this));
301   return StatusTuple(0);
302 }
303 
visit_table_decl_stmt_node(TableDeclStmtNode * n)304 StatusTuple Printer::visit_table_decl_stmt_node(TableDeclStmtNode* n) {
305   TRY2(n->table_type_->accept(this));
306   fprintf(out_, "<");
307   for (auto it = n->templates_.begin(); it != n->templates_.end(); ++it) {
308     TRY2((*it)->accept(this));
309     if (it + 1 != n->templates_.end()) {
310       fprintf(out_, ", ");
311     }
312   }
313   fprintf(out_, "> ");
314   TRY2(n->id_->accept(this));
315   fprintf(out_, "(%zu)", n->size_);
316   return StatusTuple(0);
317 }
318 
visit_func_decl_stmt_node(FuncDeclStmtNode * n)319 StatusTuple Printer::visit_func_decl_stmt_node(FuncDeclStmtNode *n) {
320   fprintf(out_, "func ");
321   TRY2(n->id_->accept(this));
322   fprintf(out_, "(");
323   for (auto it = n->formals_.begin(); it != n->formals_.end(); ++it) {
324     TRY2((*it)->accept(this));
325     if (it + 1 != n->formals_.end()) {
326       fprintf(out_, ", ");
327     }
328   }
329   fprintf(out_, ") ");
330   TRY2(n->block_->accept(this));
331   return StatusTuple(0);
332 }
333 
334 }  // namespace cc
335 }  // namespace ebpf
336