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

fix: changed quote algo

This commit is contained in:
Natapat Samutpong 2022-01-27 15:25:21 +07:00
parent 5fb47a32ca
commit a3d1075a57
4 changed files with 64 additions and 9 deletions

View file

@ -47,6 +47,11 @@ impl Compiler {
result.append(&mut self.compile(c, depth + 1)?); result.append(&mut self.compile(c, depth + 1)?);
} }
} }
"list" => {
let mut joined = Vec::new();
for c in cdr { joined.push(c); }
result.append(&mut self.compile_quoted(&joined)?);
}
"if" => { "if" => {
// TODO: Remove .clone() // TODO: Remove .clone()
let mut cond = self.compile(cdr[0].clone(), depth + 1)?; let mut cond = self.compile(cdr[0].clone(), depth + 1)?;
@ -103,6 +108,17 @@ impl Compiler {
Ok(result) Ok(result)
} }
fn compile_quoted(&mut self, atom: &Vec<Sexpr>) -> Result<Vec<Instr>, String> {
let mut result = Vec::new();
result.push(Instr::Push {
value: Type::String(format!("({})", atom.iter().map(|x| format!("{}", x)).collect::<Vec<String>>().join(" "))),
label: self.next_label(),
});
Ok(result)
}
fn compile_atom(&mut self, atom: &Sexpr, depth: usize) -> Result<Vec<Instr>, String> { fn compile_atom(&mut self, atom: &Sexpr, depth: usize) -> Result<Vec<Instr>, String> {
let mut result = Vec::new(); let mut result = Vec::new();
@ -112,25 +128,25 @@ impl Compiler {
value: Type::Int(*i), value: Type::Int(*i),
label: self.next_label(), label: self.next_label(),
}); });
} },
Float(f) => { Float(f) => {
result.push(Instr::Push { result.push(Instr::Push {
value: Type::Float(*f), value: Type::Float(*f),
label: self.next_label(), label: self.next_label(),
}); });
} },
Boolean(b) => { Boolean(b) => {
result.push(Instr::Push { result.push(Instr::Push {
value: Type::Boolean(*b), value: Type::Boolean(*b),
label: self.next_label(), label: self.next_label(),
}); });
} },
Str(s) => { Str(s) => {
result.push(Instr::Push { result.push(Instr::Push {
value: Type::String(s.clone()), value: Type::String(s.clone()),
label: self.next_label(), label: self.next_label(),
}); });
} },
_ => { _ => {
result.append(&mut self.compile(atom.clone(), depth + 1)?); result.append(&mut self.compile(atom.clone(), depth + 1)?);
} }

View file

@ -58,7 +58,7 @@ impl Parser {
match self.peek() { match self.peek() {
Some(s) => match s.as_str() { Some(s) => match s.as_str() {
")" => Err(format!("Unexpected ')' at position {}", self.position)), ")" => Err(format!("Unexpected ')' at position {}", self.position)),
"'" => { self.next(); Ok(Cons(Box::new(Str("quote".to_string())), vec![self.parse()?])) }, "'" => { self.next(); self.parse_quote_sequence(")")},
"(" => self.parse_sequence(")"), "(" => self.parse_sequence(")"),
_ => self.parse_atom(), _ => self.parse_atom(),
} }
@ -85,6 +85,24 @@ impl Parser {
Ok(Sexpr::Cons(Box::new(car), cdr)) Ok(Sexpr::Cons(Box::new(car), cdr))
} }
fn parse_quote_sequence(&mut self, end: &str) -> ParseResult {
let car = Symbol("list".to_string());
self.next();
let mut cdr = Vec::new();
loop {
let token = match self.peek() {
Some(token) => token,
None => return Err(format!("Unexpected end of input, expected '{}'", end)),
};
if token == end { break; }
cdr.push(self.parse()?)
}
self.next();
Ok(Sexpr::Cons(Box::new(car), cdr))
}
fn parse_atom(&mut self) -> ParseResult { fn parse_atom(&mut self) -> ParseResult {
let token = self.next().unwrap(); let token = self.next().unwrap();
match token.as_str() { match token.as_str() {

View file

@ -33,7 +33,7 @@ fn main() {
// Compile // Compile
(true, false) => { (true, false) => {
let src = read_to_string(&args.file).unwrap(); let src = read_to_string(&args.file).unwrap();
compile_src(src, args.output, args.file, start); compile_src(src, args.output, args.file, debug, start);
}, },
// Run // Run
(false, true) => { (false, true) => {
@ -43,7 +43,7 @@ fn main() {
(false, false) => { (false, false) => {
if args.file.extension() == Some("blsp".as_ref()) { if args.file.extension() == Some("blsp".as_ref()) {
let src = read_to_string(&args.file).unwrap(); let src = read_to_string(&args.file).unwrap();
compile_src(src, args.output, args.file, start); compile_src(src, args.output, args.file, debug, start);
} else if args.file.extension() == Some("bsm".as_ref()) { } else if args.file.extension() == Some("bsm".as_ref()) {
let src = read_to_string(&args.file).unwrap(); let src = read_to_string(&args.file).unwrap();
run_src(src, debug); run_src(src, debug);
@ -55,7 +55,7 @@ fn main() {
} }
fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, start: Instant) { fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, debug: bool, start: Instant) {
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(),
@ -65,6 +65,7 @@ fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, start: Instant
let mut parser = Parser::new(tokens.clone()); let mut parser = Parser::new(tokens.clone());
let result = parser.parse(); let result = parser.parse();
if debug { println!("{:#?}", &result); }
match result { match result {
Ok(ast) => { Ok(ast) => {
let mut compiler = Compiler::new(); let mut compiler = Compiler::new();

View file

@ -10,6 +10,7 @@ pub enum Type {
Float(f64), Float(f64),
Boolean(bool), Boolean(bool),
String(String), String(String),
Array(Vec<Type>),
} }
impl Type { impl Type {
@ -20,6 +21,7 @@ impl Type {
Type::Int(i) => *i != 0, Type::Int(i) => *i != 0,
Type::Float(f) => *f != 0.0, Type::Float(f) => *f != 0.0,
Type::String(s) => !s.is_empty(), Type::String(s) => !s.is_empty(),
Type::Array(a) => !a.is_empty(),
} }
} }
@ -37,6 +39,7 @@ impl Type {
Type::Float(f) => Type::Float(*f), Type::Float(f) => Type::Float(*f),
Type::Boolean(b) => Type::Boolean(*b), Type::Boolean(b) => Type::Boolean(*b),
Type::String(s) => Type::String(s[1..s.len() - 1].to_string()), Type::String(s) => Type::String(s[1..s.len() - 1].to_string()),
Type::Array(a) => Type::Array(a.iter().map(|t| t.trim()).collect()),
} }
} }
@ -50,6 +53,15 @@ impl Type {
false => "false".to_string(), false => "false".to_string(),
}, },
Type::String(s) => s.clone(), Type::String(s) => s.clone(),
Type::Array(a) => {
let mut s = "[".to_string();
for t in a {
s.push_str(&t.fmt());
s.push_str(", ");
}
s.push_str("]");
s
}
} }
} }
} }
@ -119,6 +131,14 @@ impl Display for Type {
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),
Type::Array(a) => {
write!(f, "[[")?;
for t in a {
write!(f, "{}", t)?;
write!(f, ", ")?;
}
write!(f, "]]")
}
} }
} }
} }