mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Implements let
compliation
This commit is contained in:
parent
348d96ec8e
commit
2cf6688e39
|
@ -27,8 +27,34 @@ impl Compiler {
|
||||||
instrs.push(Instr::ListMake(count));
|
instrs.push(Instr::ListMake(count));
|
||||||
instrs
|
instrs
|
||||||
}
|
}
|
||||||
Expr::Unary(_, _) => todo!(),
|
Expr::Unary(op, x) => {
|
||||||
Expr::Binary(_, _, _) => todo!(),
|
let mut instrs = self.compile_expr(x.0);
|
||||||
|
instrs.extend(match op.0 {
|
||||||
|
parser::UnaryOp::Neg => vec![Instr::NumPush(-1), Instr::NumMul],
|
||||||
|
parser::UnaryOp::Not => vec![Instr::BoolNot],
|
||||||
|
});
|
||||||
|
instrs
|
||||||
|
}
|
||||||
|
Expr::Binary(op, x, y) => {
|
||||||
|
let mut instrs = self.compile_expr(y.0);
|
||||||
|
instrs.extend(self.compile_expr(x.0));
|
||||||
|
instrs.push(match op.0 {
|
||||||
|
parser::BinaryOp::Add => Instr::NumAdd,
|
||||||
|
parser::BinaryOp::Sub => Instr::NumSub,
|
||||||
|
parser::BinaryOp::Mul => Instr::NumMul,
|
||||||
|
parser::BinaryOp::Div => Instr::NumDiv,
|
||||||
|
// parser::BinaryOp::Eq => Instr::Eq,
|
||||||
|
// parser::BinaryOp::Ne => Instr::Neq,
|
||||||
|
// parser::BinaryOp::Lt => Instr::Lt,
|
||||||
|
// parser::BinaryOp::Gt => Instr::Gt,
|
||||||
|
// parser::BinaryOp::Le => Instr::Lte,
|
||||||
|
// parser::BinaryOp::Ge => Instr::Gte,
|
||||||
|
parser::BinaryOp::And => Instr::BoolAnd,
|
||||||
|
parser::BinaryOp::Or => Instr::BoolOr,
|
||||||
|
_ => todo!(),
|
||||||
|
});
|
||||||
|
instrs
|
||||||
|
}
|
||||||
Expr::Lambda(args, body) => {
|
Expr::Lambda(args, body) => {
|
||||||
vec![Instr::FuncMake(args, self.compile_expr(body.0))]
|
vec![Instr::FuncMake(args, self.compile_expr(body.0))]
|
||||||
}
|
}
|
||||||
|
@ -45,7 +71,34 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
instrs
|
instrs
|
||||||
}
|
}
|
||||||
Expr::Let(_, _) => todo!(),
|
Expr::Let(binds, body) => {
|
||||||
|
let mut instrs = vec![];
|
||||||
|
let binds = binds
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|(name, expr)| {
|
||||||
|
let mut instrs = self.compile_expr(expr.0);
|
||||||
|
instrs.extend(vec![Instr::Set(name)]);
|
||||||
|
instrs
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if let Some(e) = body {
|
||||||
|
// If there is a body then we put the bindings
|
||||||
|
// inside the closure so it gets undefined outside
|
||||||
|
// the scope
|
||||||
|
instrs.extend(vec![
|
||||||
|
Instr::FuncMake(
|
||||||
|
vec![],
|
||||||
|
binds.into_iter().chain(self.compile_expr(e.0)).collect(),
|
||||||
|
),
|
||||||
|
Instr::FuncApply,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// If there is no body then we just push the bindings
|
||||||
|
// to the global scope
|
||||||
|
instrs.extend(binds);
|
||||||
|
}
|
||||||
|
instrs
|
||||||
|
}
|
||||||
Expr::Do(es) => {
|
Expr::Do(es) => {
|
||||||
let mut instrs = vec![];
|
let mut instrs = vec![];
|
||||||
for e in es {
|
for e in es {
|
||||||
|
|
|
@ -13,6 +13,7 @@ fn main() {
|
||||||
if let Some(ast) = ast {
|
if let Some(ast) = ast {
|
||||||
let mut compiler = Compiler::new();
|
let mut compiler = Compiler::new();
|
||||||
let instrs = compiler.compile_program(ast);
|
let instrs = compiler.compile_program(ast);
|
||||||
|
instrs.iter().for_each(|i| println!("{:?}", i));
|
||||||
let mut executor = Executor::new(instrs);
|
let mut executor = Executor::new(instrs);
|
||||||
match executor.run() {
|
match executor.run() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
|
|
|
@ -5,4 +5,10 @@ fun main = do
|
||||||
[1, 2, 3]
|
[1, 2, 3]
|
||||||
true
|
true
|
||||||
print("Hello, World")
|
print("Hello, World")
|
||||||
|
let seven = 7 in
|
||||||
|
print(5 - seven)
|
||||||
|
|
||||||
|
let a = 34 in
|
||||||
|
let b = 35 in
|
||||||
|
print(a + b)
|
||||||
end
|
end
|
|
@ -198,7 +198,7 @@ impl Instr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> Vec<u8> {
|
pub fn to_bytes(&self) -> Vec<u8> {
|
||||||
// a macro that will return the next index and increment it
|
// A macro that will return the next index and increment it
|
||||||
// so we don't have to rewrite all the first bytes again when
|
// so we don't have to rewrite all the first bytes again when
|
||||||
// we changes the order or add new instructions
|
// we changes the order or add new instructions
|
||||||
macro_rules! index {
|
macro_rules! index {
|
||||||
|
|
Loading…
Reference in a new issue