1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-09-28 07:17:41 +00:00

refactor: CALL use string

This commit is contained in:
Natapat Samutpong 2022-02-05 13:31:39 +07:00
parent 81f982a574
commit a7a61acd6e
4 changed files with 25 additions and 41 deletions

View file

@ -23,10 +23,6 @@ impl Compiler {
r r
} }
fn current_register(&self) -> Register {
Register { value: self.register_pointer - 1 }
}
pub fn compile(&mut self, src: Sexpr) -> Result<Vec<Instr>, String> { pub fn compile(&mut self, src: Sexpr) -> Result<Vec<Instr>, String> {
let mut result = Vec::new(); let mut result = Vec::new();
let comp = src.clone(); // Used for commenting let comp = src.clone(); // Used for commenting
@ -121,15 +117,10 @@ 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())?);
result.push(Instr::Call { function: "print".to_string() });
result.push(Instr::Push { value: Type::Int(1) });
result.push(Instr::Call);
}, },
"read" => { "read" => { result.push(Instr::Call { function: "read".to_string() }); }
result.push(Instr::Push { value: Type::Int(0) }); // read doesn't need an argument
result.push(Instr::Push { value: Type::Int(2) });
result.push(Instr::Call);
}
"add" | "+" => { "add" | "+" => {
let mut lhs = self.compile_atom(&args[0])?; let mut lhs = self.compile_atom(&args[0])?;
result.append(&mut lhs); result.append(&mut lhs);

View file

@ -176,7 +176,7 @@ pub enum Instr {
// Variable declaration // Variable declaration
Load { address: Register }, Store { address: Register }, Load { address: Register }, Store { address: Register },
// Call intrinsic function. // Call intrinsic function.
Call, Call { function: String },
// Stack operations. // Stack operations.
Push { value: Type }, Pop { address: Register }, Swap, Push { value: Type }, Pop { address: Register }, Swap,
// Stack arithmetic operations. // Stack arithmetic operations.
@ -204,7 +204,7 @@ impl Display for Instr {
Instr::Load { address } => write!(f, " LOAD {}", address), Instr::Load { address } => write!(f, " LOAD {}", address),
Instr::Store { address } => write!(f, " STORE {}", address), Instr::Store { address } => write!(f, " STORE {}", address),
Instr::Call => write!(f, " CALL"), Instr::Call { function } => write!(f, " CALL {}", function),
Instr::Push { value } => write!(f, " PUSH {}", value), Instr::Push { value } => write!(f, " PUSH {}", value),
Instr::Pop { address } => write!(f, " POP {}", address), Instr::Pop { address } => write!(f, " POP {}", address),

View file

@ -19,7 +19,7 @@ pub fn parse_instr(src: &str) -> Vec<Instr> {
"LOAD" => { result.push(Instr::Load { address: register!(tokens[1].to_string()) }); }, "LOAD" => { result.push(Instr::Load { address: register!(tokens[1].to_string()) }); },
"STORE" => { result.push(Instr::Store { address: register!(tokens[1].to_string()) }); }, "STORE" => { result.push(Instr::Store { address: register!(tokens[1].to_string()) }); },
"CALL" => { result.push(Instr::Call); }, "CALL" => { result.push(Instr::Call { function: tokens[1].to_string() }); },
"PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); }, "PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); },
"POP" => { result.push(Instr::Pop { address: register!(tokens[1]) }); }, "POP" => { result.push(Instr::Pop { address: register!(tokens[1]) }); },

View file

@ -6,7 +6,7 @@ pub enum Error {
NoMainFunction, NoMainFunction,
StackOverflow, StackOverflow,
UnknownFunction(String), UnknownFunction(String),
UnknownFunctionCall(isize, isize), UnknownFunctionCall(String),
InvalidAriphmeticOperation, InvalidAriphmeticOperation,
} }
@ -16,7 +16,7 @@ impl Display for Error {
Error::NoMainFunction => write!(f, "Main function not found"), Error::NoMainFunction => write!(f, "Main function not found"),
Error::StackOverflow => write!(f, "Stack overflow"), Error::StackOverflow => write!(f, "Stack overflow"),
Error::UnknownFunction(name) => write!(f, "Unknown function: {}", name), Error::UnknownFunction(name) => write!(f, "Unknown function: {}", name),
Error::UnknownFunctionCall(l, e) => write!(f, "Unknown function call at {}: {}", l, e), Error::UnknownFunctionCall(function) => write!(f, "Unknown function call: {}", function),
Error::InvalidAriphmeticOperation => write!(f, "Invalid ariphmetic operation"), Error::InvalidAriphmeticOperation => write!(f, "Invalid ariphmetic operation"),
} }
} }
@ -81,10 +81,8 @@ impl VM {
continue 'tco; continue 'tco;
}, },
Call => { Call { function } => {
let index = &self.stack.pop().unwrap(); self.call(function)?;
let args = &self.stack.pop().unwrap();
self.call(index, args, self.instr_pointer)?;
continue 'tco; continue 'tco;
}, },
@ -205,26 +203,21 @@ impl VM {
Err(Error::UnknownFunction(name)) Err(Error::UnknownFunction(name))
} }
fn call(&mut self, index: &Type, args: &Type, line: isize) -> Result<(), Error> { fn call(&mut self, function: &String) -> Result<(), Error> {
match index { match function.as_str() {
Type::Int(i) => { "print" => {
match i { let value = self.stack.pop().unwrap();
0 => Err(Error::UnknownFunctionCall(line, 0)), println!("{}", value.fmt());
1 => { return Ok(());
print!("{}", args.fmt()); },
Ok(()) "read" => {
}, let mut input = String::new();
2 => { io::stdin().read_line(&mut input).unwrap();
let mut input = String::new(); let input = input.trim().parse::<Type>().unwrap();
io::stdin().read_line(&mut input).unwrap(); self.stack.push(input);
let input = input.trim().parse::<Type>().unwrap(); Ok(())
self.stack.push(input); },
Ok(()) _ => { dbg!(function); Err(Error::UnknownFunctionCall(function.to_string())) },
}
_ => Err(Error::UnknownFunctionCall(line, *i as isize)),
}
}
_ => {dbg!(index); Err(Error::UnknownFunctionCall(line, -1))},
} }
} }
} }