1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

feat: throw

This commit is contained in:
Natapat Samutpong 2022-02-06 19:00:12 +07:00
parent c1975a40af
commit 5d9d0f700b
8 changed files with 45 additions and 41 deletions

View file

@ -22,13 +22,14 @@ Hello, World!
DONE: DONE:
- Parsing, Compiling, Running(VM) - Parsing, Compiling, Running(VM)
- Intrinsic: - Intrinsic:
- Function definition: `fun` - Function definition: `fun` (no arguments yet)
- Variable definition: `def` - Variable definition: `def`
- Do blocks: `do` - Do blocks: `do`
- User input: `read` - User input: `read`
- Printing: `print` - Printing: `print`
- Condition: `if` - Condition: `if`
- Loops: `while` - Loops: `while`
- Erroring: `throw`
- Math: - Math:
- `+` , `add` - `+` , `add`
- `-` , `sub` - `-` , `sub`

View file

@ -113,6 +113,28 @@ impl Compiler {
Ok(result) Ok(result)
} }
fn compile_atom(&mut self, atom: &Sexpr) -> Result<Vec<Instr>, String> {
let mut result = Vec::new();
match atom {
Int(i) => { result.push(Instr::Push { value: Type::Int(*i) }); },
Float(f) => { result.push(Instr::Push { value: Type::Float(*f) }); },
Str(s) => { result.push(Instr::Push { value: Type::String(s.to_string()) }); },
Boolean(b) => { result.push(Instr::Push { value: Type::Boolean(*b) }); },
Symbol(s) => {
let var_pointer = match self.variables.iter().find(|&(ref name, _)| name == s) {
Some((_, pointer)) => *pointer,
None => return Err(format!("Undefined variable {}", s)),
};
result.push(Instr::Comment { text: format!("`{}` variable", s) });
result.push(Instr::Load { address: var_pointer });
},
_ => { result.append(&mut self.compile(atom.clone())?); }
}
Ok(result)
}
fn compile_intrinsic(&mut self, intrinsic: &String, args: &[Sexpr]) -> Result<Vec<Instr>, String> { fn compile_intrinsic(&mut self, intrinsic: &String, args: &[Sexpr]) -> Result<Vec<Instr>, String> {
let mut result = Vec::new(); let mut result = Vec::new();
@ -127,6 +149,10 @@ impl Compiler {
result.append(&mut self.compile(args[0].clone())?); result.append(&mut self.compile(args[0].clone())?);
result.push(Instr::Call { function: "slurp".to_string() }); result.push(Instr::Call { function: "slurp".to_string() });
}, },
"throw" => {
result.append(&mut self.compile(args[0].clone())?);
result.push(Instr::Call { function: "throw".to_string() });
}
"add" | "+" => { "add" | "+" => {
let mut lhs = self.compile_atom(&args[0])?; let mut lhs = self.compile_atom(&args[0])?;
@ -189,36 +215,6 @@ impl Compiler {
Ok(result) Ok(result)
} }
fn compile_atom(&mut self, atom: &Sexpr) -> Result<Vec<Instr>, String> {
let mut result = Vec::new();
match atom {
Int(i) => {
result.push(Instr::Push { value: Type::Int(*i) });
},
Float(f) => {
result.push(Instr::Push { value: Type::Float(*f) });
},
Str(s) => {
result.push(Instr::Push { value: Type::String(s.to_string()) });
},
Boolean(b) => {
result.push(Instr::Push { value: Type::Boolean(*b) });
},
Symbol(s) => {
let var_pointer = match self.variables.iter().find(|&(ref name, _)| name == s) {
Some((_, pointer)) => *pointer,
None => return Err(format!("Undefined variable {}", s)),
};
result.push(Instr::Comment { text: format!("`{}` variable", s) });
result.push(Instr::Load { address: var_pointer });
},
_ => { result.append(&mut self.compile(atom.clone())?); }
}
Ok(result)
}
} }
fn quoted_sexpr(cdr: &Sexpr) -> Result<Type, String> { fn quoted_sexpr(cdr: &Sexpr) -> Result<Type, String> {

View file

@ -34,7 +34,7 @@ fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, debug: bool) {
let file_name = match path { let file_name = match path {
Some(path) => path, Some(path) => path,
None => Path::new(&file).to_path_buf(), None => Path::new(&file).to_path_buf(),
}.file_stem().unwrap().to_str().unwrap().to_string(); }.file_stem().unwrap().to_str().unwrap().to_string(); // what
let start = Instant::now(); let start = Instant::now();
let tokens = tokenize(&cover_paren(src)); let tokens = tokenize(&cover_paren(src));
@ -57,14 +57,17 @@ fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, debug: bool) {
let elapsed = start.elapsed(); let elapsed = start.elapsed();
println!("Compiled in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis()); println!("Compiled in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis());
exit(0);
}, },
Err(err) => { Err(err) => {
eprintln!("{}", err); eprintln!("{}", err);
exit(1);
} }
} }
}, },
Err(e) => { Err(e) => {
eprintln!("{}", e); eprintln!("{}", e);
exit(1);
} }
} }
} }

View file

@ -35,7 +35,7 @@ impl Type {
s.push('('); s.push('(');
for (i, t) in v.iter().enumerate() { for (i, t) in v.iter().enumerate() {
if i != 0 { s.push(' '); } if i != 0 { s.push(' '); }
s.push_str(&t.print().to_string()); s.push_str(&t.print());
} }
s.push(')'); s.push(')');
s s

View file

@ -9,6 +9,7 @@ pub enum Error {
UnknownFunctionCall(String), UnknownFunctionCall(String),
InvalidAriphmeticOperation, InvalidAriphmeticOperation,
FileError(String), FileError(String),
Throw(String),
} }
impl Display for Error { impl Display for Error {
@ -20,6 +21,7 @@ impl Display for Error {
Error::UnknownFunctionCall(function) => write!(f, "Unknown function call: {}", function), Error::UnknownFunctionCall(function) => write!(f, "Unknown function call: {}", function),
Error::InvalidAriphmeticOperation => write!(f, "Invalid ariphmetic operation"), Error::InvalidAriphmeticOperation => write!(f, "Invalid ariphmetic operation"),
Error::FileError(msg) => write!(f, "Could not open file: {}", msg), Error::FileError(msg) => write!(f, "Could not open file: {}", msg),
Error::Throw(msg) => write!(f, "{}", msg),
} }
} }
} }
@ -226,7 +228,11 @@ impl VM {
Ok(_) => Ok(self.stack.push(Type::String(result))), Ok(_) => Ok(self.stack.push(Type::String(result))),
Err(e) => Err(Error::FileError(e.to_string())), Err(e) => Err(Error::FileError(e.to_string())),
} }
} },
"throw" => {
let value = self.stack.pop().unwrap();
return Err(Error::Throw(value.print()));
},
_ => { dbg!(function); Err(Error::UnknownFunctionCall(function.to_string())) }, _ => { dbg!(function); Err(Error::UnknownFunctionCall(function.to_string())) },
} }
} }

View file

@ -1,4 +1,3 @@
(fun str "Hello, world!") (fun main (do
(def str "Hello, world!")
(fun main (print (str))))
(print (str)))

View file

@ -1,3 +0,0 @@
(fun cool_number (/ (+ 345 345) 10))
(fun main
(print cool_number))

2
example/throw.blsp Normal file
View file

@ -0,0 +1,2 @@
(fun main
(throw "error :("))