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)?);
|
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)?);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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, "]]")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue