1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-09-28 07:17:41 +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)?);
}
}
"list" => {
let mut joined = Vec::new();
for c in cdr { joined.push(c); }
result.append(&mut self.compile_quoted(&joined)?);
}
"if" => {
// TODO: Remove .clone()
let mut cond = self.compile(cdr[0].clone(), depth + 1)?;
@ -102,6 +107,17 @@ impl Compiler {
}
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> {
let mut result = Vec::new();
@ -112,25 +128,25 @@ impl Compiler {
value: Type::Int(*i),
label: self.next_label(),
});
}
},
Float(f) => {
result.push(Instr::Push {
value: Type::Float(*f),
label: self.next_label(),
});
}
},
Boolean(b) => {
result.push(Instr::Push {
value: Type::Boolean(*b),
label: self.next_label(),
});
}
},
Str(s) => {
result.push(Instr::Push {
value: Type::String(s.clone()),
label: self.next_label(),
});
}
},
_ => {
result.append(&mut self.compile(atom.clone(), depth + 1)?);
}

View file

@ -58,7 +58,7 @@ impl Parser {
match self.peek() {
Some(s) => match s.as_str() {
")" => 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_atom(),
}
@ -84,6 +84,24 @@ impl Parser {
self.next();
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 {
let token = self.next().unwrap();

View file

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

View file

@ -10,6 +10,7 @@ pub enum Type {
Float(f64),
Boolean(bool),
String(String),
Array(Vec<Type>),
}
impl Type {
@ -20,6 +21,7 @@ impl Type {
Type::Int(i) => *i != 0,
Type::Float(f) => *f != 0.0,
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::Boolean(b) => Type::Boolean(*b),
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(),
},
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::Boolean(b) => write!(f, ":{}", b),
Type::String(s) => write!(f, "$\"{}\"", s),
Type::Array(a) => {
write!(f, "[[")?;
for t in a {
write!(f, "{}", t)?;
write!(f, ", ")?;
}
write!(f, "]]")
}
}
}
}