mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
fix: changed quote algo
This commit is contained in:
parent
5fb47a32ca
commit
a3d1075a57
|
@ -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)?);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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, "]]")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue