jetcrab\bytecode\statements/
control_flow.rs1use crate::ast::Node;
2use crate::vm::instructions::Instruction;
3use crate::vm::types::CodeAddress;
4
5pub trait ControlFlowGenerator {
6 fn generate_if_statement(&mut self, node: &Node);
7 fn generate_for_statement(&mut self, node: &Node);
8 fn generate_while_statement(&mut self, node: &Node);
9 fn generate_do_while_statement(&mut self, node: &Node);
10 fn generate_switch_statement(&mut self, node: &Node);
11 fn generate_try_statement(&mut self, node: &Node);
12 fn generate_catch_clause(&mut self, node: &Node);
13 fn generate_labeled_statement(&mut self, node: &Node);
14 fn generate_break_statement(&mut self, node: &Node);
15 fn generate_continue_statement(&mut self, node: &Node);
16 fn generate_return_statement(&mut self, node: &Node);
17 fn generate_throw_statement(&mut self, node: &Node);
18 fn generate_for_in_statement(&mut self, node: &Node);
19 fn generate_for_of_statement(&mut self, node: &Node);
20 fn generate_import_declaration(&mut self, node: &Node);
21 fn generate_export_declaration(&mut self, node: &Node);
22}
23
24pub trait LabelManager {
25 fn add_label(&mut self, name: String, address: CodeAddress);
26 fn get_label_address(&self, name: &str) -> Option<CodeAddress>;
27 fn get_label_start_address(&self, label_name: &str) -> Option<CodeAddress>;
28 fn get_label_end_address(&self, label_name: &str) -> Option<CodeAddress>;
29 fn push_current_label(&mut self, name: String);
30 fn pop_current_label(&mut self);
31 fn get_current_labels(&self) -> &[String];
32}
33
34pub trait ControlFlowCore {
35 fn instructions(&mut self) -> &mut Vec<Instruction>;
36 fn visit_node(&mut self, node: &Node);
37 fn push_loop_label(&mut self, break_address: CodeAddress);
38 fn pop_loop_label(&mut self);
39 fn get_current_break_address(&self) -> Option<CodeAddress>;
40}
41
42use super::control_statements;
44use super::if_statement;
45use super::loop_statements::{self, generate_for_in_statement, generate_for_of_statement};
46use super::modules::{generate_export_declaration, generate_import_declaration};
47use super::switch_statement;
48use super::try_catch;
49
50impl<T> ControlFlowGenerator for T
51where
52 T: ControlFlowCore + LabelManager,
53{
54 fn generate_if_statement(&mut self, node: &Node) {
55 if_statement::generate_if_statement(self, node);
56 }
57
58 fn generate_for_statement(&mut self, node: &Node) {
59 loop_statements::generate_for_statement(self, node);
60 }
61
62 fn generate_while_statement(&mut self, node: &Node) {
63 loop_statements::generate_while_statement(self, node);
64 }
65
66 fn generate_do_while_statement(&mut self, node: &Node) {
67 loop_statements::generate_do_while_statement(self, node);
68 }
69
70 fn generate_switch_statement(&mut self, node: &Node) {
71 switch_statement::generate_switch_statement(self, node);
72 }
73
74 fn generate_try_statement(&mut self, node: &Node) {
75 try_catch::generate_try_statement(self, node);
76 }
77
78 fn generate_catch_clause(&mut self, node: &Node) {
79 try_catch::generate_catch_clause(self, node);
80 }
81
82 fn generate_labeled_statement(&mut self, node: &Node) {
83 control_statements::generate_labeled_statement(self, node);
84 }
85
86 fn generate_break_statement(&mut self, node: &Node) {
87 control_statements::generate_break_statement(self, node);
88 }
89
90 fn generate_continue_statement(&mut self, node: &Node) {
91 control_statements::generate_continue_statement(self, node);
92 }
93
94 fn generate_return_statement(&mut self, node: &Node) {
95 control_statements::generate_return_statement(self, node);
96 }
97
98 fn generate_throw_statement(&mut self, node: &Node) {
99 try_catch::generate_throw_statement(self, node);
100 }
101
102 fn generate_for_in_statement(&mut self, node: &Node) {
103 generate_for_in_statement(self, node);
104 }
105
106 fn generate_for_of_statement(&mut self, node: &Node) {
107 generate_for_of_statement(self, node);
108 }
109
110 fn generate_import_declaration(&mut self, node: &Node) {
111 generate_import_declaration(self, node);
112 }
113
114 fn generate_export_declaration(&mut self, node: &Node) {
115 generate_export_declaration(self, node);
116 }
117}