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

feat: read

This commit is contained in:
Natapat Samutpong 2022-02-05 09:48:52 +07:00
parent 8dcb8a0d9d
commit f355183b8d
6 changed files with 40 additions and 29 deletions

View file

@ -25,6 +25,7 @@ DONE:
- Function definition: `fun` - Function definition: `fun`
- Variable definition: `let` - Variable definition: `let`
- Do blocks: `do` - Do blocks: `do`
- User input: `read`
- Printing: `print` - Printing: `print`
- Condition: `if` - Condition: `if`
- Math: - Math:

View file

@ -106,6 +106,11 @@ impl Compiler {
result.push(Instr::Push { value: Type::Int(1) }); result.push(Instr::Push { value: Type::Int(1) });
result.push(Instr::Call); result.push(Instr::Call);
}, },
"read" => {
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

@ -13,7 +13,6 @@ pub enum Type {
} }
impl Type { impl Type {
pub fn is_null(&self) -> bool { pub fn is_null(&self) -> bool {
match self { match self {
Type::Null => true, Type::Null => true,
@ -102,10 +101,10 @@ impl Div for Type {
impl Display for Type { impl Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self { match self {
Type::Int(i) => write!(f, ":{}", i), Type::Int(i) => write!(f, "{}", i),
Type::Float(fl) => write!(f, ":{}", fl), Type::Float(fl) => write!(f, "{}", fl),
Type::Boolean(b) => write!(f, ":{}", b), Type::Boolean(b) => write!(f, "{}", b),
Type::String(s) => write!(f, "$\"{}\"", s), Type::String(s) => write!(f, "\"{}\"", s),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -115,11 +114,6 @@ impl FromStr for Type {
type Err = String; type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
if !s.starts_with("$") && !s.starts_with(":") {
return Err(format!("Invalid literal: {}", s));
}
let s = &s[1..];
match s { match s {
"true" => Ok(Type::Boolean(true)), "true" => Ok(Type::Boolean(true)),
"false" => Ok(Type::Boolean(false)), "false" => Ok(Type::Boolean(false)),

View file

@ -2,7 +2,7 @@ use regex::Regex;
use crate::vm::instr::*; use crate::vm::instr::*;
const REGEX: &str = r###"[^\s\$";]+|\$"[^"]*"|;.*"###; const REGEX: &str = r###"[^\s\$";]+|"[^"]*"|;.*"###;
macro_rules! value { ($s:expr) => { $s.parse::<Type>().unwrap() }; } macro_rules! value { ($s:expr) => { $s.parse::<Type>().unwrap() }; }
macro_rules! register { ($s:expr) => { $s.parse::<Register>().unwrap() }; } macro_rules! register { ($s:expr) => { $s.parse::<Register>().unwrap() }; }

View file

@ -1,4 +1,4 @@
use std::fmt::Display; use std::{io, fmt::Display};
use crate::vm::instr::{Instr::{self, *}, Type, Register}; use crate::vm::instr::{Instr::{self, *}, Type, Register};
@ -81,7 +81,7 @@ impl VM {
Call => { Call => {
let index = &self.stack.pop().unwrap(); let index = &self.stack.pop().unwrap();
let args = &self.stack.pop().unwrap(); let args = &self.stack.pop().unwrap();
call(index, args, self.instr_pointer)?; self.call(index, args, self.instr_pointer)?;
continue 'tco; continue 'tco;
}, },
Push { value } => { Push { value } => {
@ -176,6 +176,29 @@ impl VM {
} }
Err(Error::UnknownFunction(name)) Err(Error::UnknownFunction(name))
} }
fn call(&mut self, index: &Type, args: &Type, line: isize) -> Result<(), Error> {
match index {
Type::Int(i) => {
match i {
0 => Err(Error::UnknownFunctionCall(line, 0)),
1 => {
print!("{}", args.fmt());
Ok(())
},
2 => {
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let input = input.trim().parse::<Type>().unwrap();
self.stack.push(input);
Ok(())
}
_ => Err(Error::UnknownFunctionCall(line, *i as isize)),
}
}
_ => {dbg!(index); Err(Error::UnknownFunctionCall(line, -1))},
}
}
} }
fn print_debug(vm: &VM, curr_instr: &Instr) { fn print_debug(vm: &VM, curr_instr: &Instr) {
@ -184,20 +207,4 @@ fn print_debug(vm: &VM, curr_instr: &Instr) {
println!("regis: {:?}", regs); println!("regis: {:?}", regs);
println!("stack: {:?}", vm.stack); println!("stack: {:?}", vm.stack);
println!("currn: {} {}", vm.instr_pointer, curr_instr); println!("currn: {} {}", vm.instr_pointer, curr_instr);
}
fn call(index: &Type, args: &Type, line: isize) -> Result<(), Error> {
match index {
Type::Int(i) => {
match i {
0 => Err(Error::UnknownFunctionCall(line, 0)),
1 => {
println!("{}", args.fmt());
Ok(())
},
_ => Err(Error::UnknownFunctionCall(line, *i as isize)),
}
}
_ => {dbg!(index); Err(Error::UnknownFunctionCall(line, -1))},
}
} }

4
example/input.blsp Normal file
View file

@ -0,0 +1,4 @@
(fun main (do
(let in (read))
(print "Your input was: ")
(print in)))