mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
feat: if
This commit is contained in:
parent
560ac69863
commit
9f7e80dae2
10
README.md
10
README.md
|
@ -24,12 +24,16 @@ Hello, World!
|
||||||
DONE:
|
DONE:
|
||||||
- Parsing, Compiling, Running(VM)
|
- Parsing, Compiling, Running(VM)
|
||||||
- Intrinsic:
|
- Intrinsic:
|
||||||
- `fun`, `do`, `print`
|
- `fun`, `do`, `print`, `if`
|
||||||
- Math:
|
- Math:
|
||||||
|
- `+` , `add`
|
||||||
|
- `-` , `sub`
|
||||||
|
- `*` , `mul`
|
||||||
|
- `/` , `div`
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- Prove turing complete
|
- Prove turing complete
|
||||||
- Do the intrinsic left
|
- Do the intrinsic left
|
||||||
- Quote, Quasiquote, etc.
|
- Quote, Quasiquote, etc.
|
||||||
- Optimizing
|
- Optimizing
|
||||||
- Remove unnecessary copying in the entire codebase
|
- Remove unnecessary copying in the entire codebase (also with `.unwrap()`)
|
||||||
|
|
|
@ -49,6 +49,18 @@ impl Compiler {
|
||||||
result.append(&mut self.compile(body.clone())?);
|
result.append(&mut self.compile(body.clone())?);
|
||||||
result.push(Instr::Return);
|
result.push(Instr::Return);
|
||||||
},
|
},
|
||||||
|
"if" => {
|
||||||
|
let mut cond = self.compile(cdr[0].clone())?;
|
||||||
|
result.append(&mut cond);
|
||||||
|
|
||||||
|
let mut then = self.compile(cdr[1].clone())?;
|
||||||
|
let mut else_ = self.compile(cdr[2].clone())?;
|
||||||
|
|
||||||
|
result.push(Instr::JumpIfFalse { to: then.len() + 1}); // +1 for the jump instr
|
||||||
|
result.append(&mut then);
|
||||||
|
result.push(Instr::Jump { to: else_.len() });
|
||||||
|
result.append(&mut else_);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
result.append(&mut self.compile_intrinsic(call, &cdr)?);
|
result.append(&mut self.compile_intrinsic(call, &cdr)?);
|
||||||
}
|
}
|
||||||
|
@ -72,8 +84,6 @@ impl Compiler {
|
||||||
match intrinsic.as_str() {
|
match intrinsic.as_str() {
|
||||||
"print" => {
|
"print" => {
|
||||||
result.append(&mut self.compile(args[0].clone())?);
|
result.append(&mut self.compile(args[0].clone())?);
|
||||||
let to = self.next_register();
|
|
||||||
let call_register = self.next_register();
|
|
||||||
|
|
||||||
result.push(Instr::Push { value: Type::Int(1) });
|
result.push(Instr::Push { value: Type::Int(1) });
|
||||||
result.push(Instr::Call);
|
result.push(Instr::Call);
|
||||||
|
@ -141,7 +151,7 @@ impl Compiler {
|
||||||
},
|
},
|
||||||
Symbol(s) => {
|
Symbol(s) => {
|
||||||
result.push(Instr::Comment { text: format!("{} variable", comp) });
|
result.push(Instr::Comment { text: format!("{} variable", comp) });
|
||||||
result.push(Instr::Jump { to: format!("function_{}", s), });
|
result.push(Instr::JumpLabel { to: format!("function_{}", s), });
|
||||||
},
|
},
|
||||||
_ => { result.append(&mut self.compile(atom.clone())?); }
|
_ => { result.append(&mut self.compile(atom.clone())?); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,9 +189,10 @@ pub enum Instr {
|
||||||
// Stack arithmetic.
|
// Stack arithmetic.
|
||||||
Add, Sub,
|
Add, Sub,
|
||||||
Mul, Div,
|
Mul, Div,
|
||||||
// Jumping
|
// Jumping.
|
||||||
Jump { to: String },
|
JumpLabel { to: String }, // Jump to (function) label.
|
||||||
PopJumpIfFalse { to: usize },
|
Jump { to: usize }, // Jump with offset.
|
||||||
|
JumpIfFalse { to: usize },
|
||||||
|
|
||||||
Return,
|
Return,
|
||||||
}
|
}
|
||||||
|
@ -212,8 +213,9 @@ impl Display for Instr {
|
||||||
Instr::Sub => write!(f, " SUB"),
|
Instr::Sub => write!(f, " SUB"),
|
||||||
Instr::Mul => write!(f, " MUL"),
|
Instr::Mul => write!(f, " MUL"),
|
||||||
Instr::Div => write!(f, " DIV"),
|
Instr::Div => write!(f, " DIV"),
|
||||||
|
Instr::JumpLabel { to } => write!(f, " JMPL {}", to),
|
||||||
Instr::Jump { to } => write!(f, " JMP {}", to),
|
Instr::Jump { to } => write!(f, " JMP {}", to),
|
||||||
Instr::PopJumpIfFalse { to } => write!(f, " PJMPF {}", to),
|
Instr::JumpIfFalse { to } => write!(f, " JMPF {}", to),
|
||||||
Instr::Return => write!(f, " RET"),
|
Instr::Return => write!(f, " RET"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,8 @@ pub fn parse_instr(src: &str) -> Vec<Instr> {
|
||||||
"SUB" => { result.push(Instr::Sub); },
|
"SUB" => { result.push(Instr::Sub); },
|
||||||
"MUL" => { result.push(Instr::Mul); },
|
"MUL" => { result.push(Instr::Mul); },
|
||||||
"DIV" => { result.push(Instr::Div); },
|
"DIV" => { result.push(Instr::Div); },
|
||||||
"JMP" => { result.push(Instr::Jump { to: tokens[1].to_string() }); },
|
"JMPL" => { result.push(Instr::JumpLabel { to: tokens[1].to_string() }); },
|
||||||
|
"JMP" => { result.push(Instr::Jump { to: tokens[1].parse::<usize>().unwrap() }); },
|
||||||
"PJMPF" => todo!(),
|
"PJMPF" => todo!(),
|
||||||
"RET" => { result.push(Instr::Return); },
|
"RET" => { result.push(Instr::Return); },
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -119,12 +119,16 @@ impl VM {
|
||||||
self.push((lhs / rhs)?)?;
|
self.push((lhs / rhs)?)?;
|
||||||
continue 'tco;
|
continue 'tco;
|
||||||
},
|
},
|
||||||
Jump { to } => {
|
JumpLabel { to } => {
|
||||||
let pointer = self.get_function_pointer(to.to_string())?;
|
let pointer = self.get_function_pointer(to.to_string())?;
|
||||||
self.jumped_from = self.instr_pointer;
|
self.jumped_from = self.instr_pointer;
|
||||||
self.instr_pointer = pointer;
|
self.instr_pointer = pointer;
|
||||||
continue 'tco;
|
continue 'tco;
|
||||||
},
|
},
|
||||||
|
Jump { to } => {
|
||||||
|
self.instr_pointer += *to as isize + 1;
|
||||||
|
continue 'tco;
|
||||||
|
},
|
||||||
Return => {
|
Return => {
|
||||||
if self.jumped_from == 0 { return Ok(()); }
|
if self.jumped_from == 0 { return Ok(()); }
|
||||||
self.instr_pointer = self.jumped_from;
|
self.instr_pointer = self.jumped_from;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
(if true
|
(fun main
|
||||||
(print (+ 34 35))
|
(if true
|
||||||
(print "False"))
|
(print "True")
|
||||||
|
(print "False")))
|
Loading…
Reference in a new issue