rscmm/core/compiler/
imp.rs

1use 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                // add memory
199                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}