rscmm/core/compiler/
imp.rs1use super::{Compiler, Context};
2use crate::core::types::nodes::*;
3use crate::core::types::{CalcItem, Code, CodeAddr, Type, Value};
4
5impl Compiler for FactorNd {
6 fn compile(&self, cxt: &mut Context) {
7 match self {
8 FactorNd::Var(n) => n.compile(cxt),
9 FactorNd::Value(v) => {
10 if let Value::Int(num) = v {
11 cxt.add_code(Code::PushValue(*num));
12 }
13 }
14 FactorNd::Func(n) => n.compile(cxt),
15 }
16 }
17}
18
19impl Compiler for ExprNd {
20 fn compile(&self, cxt: &mut Context) {
21 for it in self.stack.iter() {
22 match it {
23 CalcItem::Op(op) => {
24 cxt.add_code(Code::Op(op.clone()));
25 }
26 CalcItem::Factor(f) => {
27 f.compile(cxt);
28 }
29 }
30 }
31 }
32}
33
34impl Compiler for VarNd {
35 fn compile(&self, cxt: &mut Context) {
36 cxt.push(self.get_id());
37 }
38}
39
40impl Compiler for AssignNd {
41 fn compile(&self, cxt: &mut Context) {
42 self.expr.compile(cxt);
43 cxt.pop(self.var.get_id());
44 }
45}
46
47impl Compiler for DeclareNd {
48 fn compile(&self, cxt: &mut Context) {
49 match &self.expr {
50 Some(e) => {
51 e.compile(cxt);
52 }
53 None => {
54 cxt.add_code(Code::PushValue(0));
55 }
56 };
57 }
58}
59
60impl Compiler for StmtNd {
61 fn compile(&self, cxt: &mut Context) {
62 match self {
63 StmtNd::Assign(n) => {
64 n.compile(cxt);
65 }
66 StmtNd::Declare(n) => n.compile(cxt),
67 StmtNd::Expr(n) => {
68 n.compile(cxt);
69 cxt.add_code(Code::Pop(1));
70 }
71 StmtNd::Print(n) => {
72 cxt.push(n.get_id());
73 cxt.add_code(Code::Print);
74 cxt.add_code(Code::Pop(1));
75 }
76 _ => {}
77 }
78 }
79}
80
81impl Compiler for IfNd {
82 fn compile(&self, cxt: &mut Context) {
83 cxt.enter(self.get_id());
84 self.expr.compile(cxt);
85 cxt.add_code(Code::CondJump(CodeAddr::NameEnd(self.get_id())));
86 self.item.compile(cxt);
87 cxt.exit(self.get_id());
88 if self.els.is_some() {
89 self.els.as_ref().unwrap().compile(cxt);
90 }
91 }
92}
93
94impl Compiler for ElsNd {
95 fn compile(&self, cxt: &mut Context) {
96 match self {
97 ElsNd::If(n) => n.compile(cxt),
98 ElsNd::Item(n) => n.compile(cxt),
99 }
100 }
101}
102
103impl Compiler for WhileNd {
104 fn compile(&self, cxt: &mut Context) {
105 cxt.enter(self.get_id());
106 self.expr.compile(cxt);
107 cxt.add_code(Code::CondJump(CodeAddr::NameEnd(self.get_id())));
108 self.item.compile(cxt);
109 cxt.add_code(Code::Jump(CodeAddr::NameStart(self.get_id())));
110 cxt.exit(self.get_id());
111 }
112}
113
114impl Compiler for BreakNd {
115 fn compile(&self, cxt: &mut Context) {
116 cxt.add_code(Code::Pop(self.get_pop_off()));
117 cxt.add_code(Code::Jump(CodeAddr::NameEnd(self.get_id())));
118 }
119}
120
121impl Compiler for ContinueNd {
122 fn compile(&self, cxt: &mut Context) {
123 cxt.add_code(Code::Pop(self.get_pop_off()));
124 cxt.add_code(Code::Jump(CodeAddr::NameStart(self.get_id())));
125 }
126}
127
128impl Compiler for ReturnNd {
129 fn compile(&self, cxt: &mut Context) {
130 match self.expr.as_ref() {
131 Some(n) => {
132 n.compile(cxt);
133 cxt.add_code(Code::Ret(self.get_sz()));
134 }
135 None => {
136 let sz = self.get_sz();
137 for _ in 0..sz {
138 cxt.add_code(Code::PushValue(0));
139 }
140 cxt.add_code(Code::Ret(0));
141 }
142 }
143 }
144}
145
146impl Compiler for ItemNd {
147 fn compile(&self, cxt: &mut Context) {
148 match self {
149 ItemNd::Block(n) => n.compile(cxt),
150 ItemNd::Stmt(n) => n.compile(cxt),
151 ItemNd::If(n) => n.compile(cxt),
152 ItemNd::While(n) => n.compile(cxt),
153 ItemNd::Break(n) => n.compile(cxt),
154 ItemNd::Continue(n) => n.compile(cxt),
155 ItemNd::Return(n) => n.compile(cxt),
156 }
157 }
158}
159
160impl Compiler for BlockNd {
161 fn compile(&self, cxt: &mut Context) {
162 cxt.enter(self.get_id());
163 for it in self.items.iter() {
164 it.compile(cxt);
165 }
166 let sz = cxt.get_scope_size(self.get_id());
167 cxt.add_code(Code::Pop(sz));
168 cxt.exit(self.get_id());
169 }
170}
171
172impl Compiler for FuncNd {
173 fn compile(&self, cxt: &mut Context) {
174 if self.is_impl() {
175 let id = self.var.get_id();
176 cxt.enter_func(id);
177 self.block.as_ref().unwrap().compile(cxt);
178 cxt.exit_func();
179 }
180 }
181}
182
183impl Compiler for FuncCallNd {
184 fn compile(&self, cxt: &mut Context) {
185 for p in self.params.iter() {
186 p.compile(cxt);
187 }
188 let id = self.var.get_id();
189 cxt.call(id);
190 }
191}
192
193impl Compiler for GItemNd {
194 fn compile(&self, cxt: &mut Context) {
195 match self {
196 GItemNd::Func(n) => n.compile(cxt),
197 GItemNd::Declare(n) => {
198 if n.ty == Type::Int {
200 let v = n.try_retrieve_const().unwrap();
201 cxt.add_memory(v);
202 }
203 }
204 }
205 }
206}
207
208impl Compiler for RootNd {
209 fn compile(&self, cxt: &mut Context) {
210 for it in self.items.iter() {
211 it.compile(cxt);
212 }
213 }
214}