refactor: Vec to VecDeque
This commit is contained in:
parent
5e98637ae0
commit
07c01a1e39
15 changed files with 108 additions and 102 deletions
2
mute-interpreter/src/env/core.rs
vendored
2
mute-interpreter/src/env/core.rs
vendored
|
@ -138,7 +138,7 @@ pub(super) fn core() -> HashMap<String, Value> {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
// Collections
|
// Collections
|
||||||
("list", NativeFunc(Node::List)),
|
("list", NativeFunc(|args| Node::List(args.into()))),
|
||||||
(
|
(
|
||||||
"list?",
|
"list?",
|
||||||
NativeFunc(|args| {
|
NativeFunc(|args| {
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
use std::borrow::Borrow;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use crate::{Environment, Error, Result};
|
use crate::{Environment, Error, Result};
|
||||||
use mute_parser::Node;
|
use mute_parser::Node;
|
||||||
|
|
||||||
pub fn eval(env: &Environment, ast: Vec<Node>) -> Result<Vec<Node>> {
|
pub fn eval(env: &Environment, ast: VecDeque<Node>) -> Result<VecDeque<Node>> {
|
||||||
let mut exprs = Vec::new();
|
let mut results = VecDeque::new();
|
||||||
|
|
||||||
let mut ast = ast.into_iter();
|
|
||||||
loop {
|
|
||||||
let node = match ast.next() {
|
|
||||||
Some(node) => node,
|
|
||||||
None => break,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let mut ast = ast;
|
||||||
|
while let Some(node) = ast.pop_front() {
|
||||||
if let Node::List(list) = &node {
|
if let Node::List(list) = &node {
|
||||||
let first = match list.first() {
|
let first = match list.front() {
|
||||||
Some(Node::Symbol(ident)) => match env.get_node(ident) {
|
Some(Node::Symbol(ident)) => match env.get_node(ident) {
|
||||||
m @ Some(Node::Macro(_)) => m,
|
m @ Some(Node::Macro(_)) => m,
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -23,16 +18,16 @@ pub fn eval(env: &Environment, ast: Vec<Node>) -> Result<Vec<Node>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(Node::Macro(body)) = first {
|
if let Some(Node::Macro(body)) = first {
|
||||||
let mut body = body.iter();
|
let mut body = body;
|
||||||
let parameters = body.next().ok_or_else(|| todo!())?;
|
let parameters = body.pop_front().ok_or_else(|| todo!())?;
|
||||||
let parameters = read_parameters(parameters.clone())?;
|
let parameters = read_parameters(parameters.clone())?;
|
||||||
let args = list.clone().into_iter().skip(1).collect::<Vec<Node>>();
|
let args = list.clone().into_iter().skip(1).collect::<VecDeque<Node>>();
|
||||||
|
|
||||||
|
let mut nodes = expand_macro(env, parameters.to_owned(), args, body)?;
|
||||||
|
while let Some(node) = nodes.pop_back() {
|
||||||
|
ast.push_front(node);
|
||||||
|
}
|
||||||
|
|
||||||
ast = expand_macro(env, parameters.to_owned(), args, body.cloned().collect())?
|
|
||||||
.into_iter()
|
|
||||||
.chain(ast)
|
|
||||||
.collect::<Vec<Node>>()
|
|
||||||
.into_iter();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,10 +37,10 @@ pub fn eval(env: &Environment, ast: Vec<Node>) -> Result<Vec<Node>> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
exprs.push(res);
|
results.push_back(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(exprs)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
|
@ -57,13 +52,13 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We always assume lists evaluate
|
// We always assume lists evaluate
|
||||||
let mut list = list.into_iter();
|
let mut list = list;
|
||||||
let operator = eval_node(env, list.next().ok_or(Error::InvalidOperator)?)?;
|
let operator = eval_node(env, list.pop_front().ok_or(Error::InvalidOperator)?)?;
|
||||||
|
|
||||||
match operator.borrow() {
|
match operator {
|
||||||
Node::Function(body) => {
|
Node::Function(body) => {
|
||||||
let mut body = body.iter();
|
let mut body = body;
|
||||||
let parameters = body.next().ok_or_else(|| todo!())?;
|
let parameters = body.pop_front().ok_or_else(|| todo!())?;
|
||||||
let parameters = read_parameters(parameters.clone())?;
|
let parameters = read_parameters(parameters.clone())?;
|
||||||
|
|
||||||
let args = list;
|
let args = list;
|
||||||
|
@ -72,31 +67,27 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = args
|
let args = args
|
||||||
|
.into_iter()
|
||||||
.map(|node| eval_node(env, node))
|
.map(|node| eval_node(env, node))
|
||||||
.collect::<Result<Vec<Node>>>()?;
|
.collect::<Result<Vec<Node>>>()?;
|
||||||
|
|
||||||
let records = parameters.iter().map(|k| k.to_owned()).zip(args).collect();
|
let records = parameters.iter().map(|k| k.to_owned()).zip(args).collect();
|
||||||
let env = env.wrap(records);
|
let env = env.wrap(records);
|
||||||
|
|
||||||
let res = eval(&env, body.cloned().collect::<Vec<Node>>())?;
|
let mut res = eval(&env, body.clone())?;
|
||||||
match res.last() {
|
match res.pop_back() {
|
||||||
Some(node) => node.to_owned(),
|
Some(node) => node,
|
||||||
None => Node::Void,
|
None => Node::Void,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::Macro(body) => {
|
Node::Macro(body) => {
|
||||||
let mut body = body.iter();
|
let mut body = body;
|
||||||
let parameters = body.next().ok_or_else(|| todo!())?;
|
let parameters = body.pop_front().ok_or_else(|| todo!())?;
|
||||||
let parameters = read_parameters(parameters.clone())?;
|
let parameters = read_parameters(parameters.clone())?;
|
||||||
|
|
||||||
let args = list;
|
let args = list;
|
||||||
match expand_macro(
|
match expand_macro(env, parameters.clone(), args, body.clone())? {
|
||||||
env,
|
|
||||||
parameters.clone(),
|
|
||||||
args.collect(),
|
|
||||||
body.cloned().collect::<Vec<Node>>(),
|
|
||||||
)? {
|
|
||||||
nodes if nodes.len() == 1 => eval_node(env, nodes[0].to_owned())?,
|
nodes if nodes.len() == 1 => eval_node(env, nodes[0].to_owned())?,
|
||||||
_ => Err(Error::MacroExpansion)?,
|
_ => Err(Error::MacroExpansion)?,
|
||||||
}
|
}
|
||||||
|
@ -105,10 +96,11 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
// HACK: This feels sooooooo wrong but it works
|
// HACK: This feels sooooooo wrong but it works
|
||||||
// Native Functions /should/ be their own type, but they're not.
|
// Native Functions /should/ be their own type, but they're not.
|
||||||
Node::Symbol(sym) => {
|
Node::Symbol(sym) => {
|
||||||
let operator = env.get(sym).ok_or_else(|| Error::NotInEnv(sym.clone()))?;
|
let operator = env.get(&sym).ok_or_else(|| Error::NotInEnv(sym.clone()))?;
|
||||||
match operator {
|
match operator {
|
||||||
crate::env::Value::NativeFunc(func) => {
|
crate::env::Value::NativeFunc(func) => {
|
||||||
let args = list
|
let args = list
|
||||||
|
.into_iter()
|
||||||
.map(|node| eval_node(env, node))
|
.map(|node| eval_node(env, node))
|
||||||
.collect::<Result<Vec<Node>>>()?;
|
.collect::<Result<Vec<Node>>>()?;
|
||||||
|
|
||||||
|
@ -125,7 +117,10 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
Node::Define(body) => {
|
Node::Define(body) => {
|
||||||
body.into_iter()
|
body.into_iter()
|
||||||
.map(|n| match n {
|
.map(|n| match n {
|
||||||
Node::List(list) if list.len() == 2 => Ok((list[0].clone(), list[1].clone())),
|
Node::List(mut list) if list.len() == 2 => Ok((
|
||||||
|
list.pop_front().expect("checked in match"),
|
||||||
|
list.pop_front().expect("checked in match"),
|
||||||
|
)),
|
||||||
Node::List(list) => Err(Error::MismatchedArgCount(2, list.len()))?,
|
Node::List(list) => Err(Error::MismatchedArgCount(2, list.len()))?,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
})
|
})
|
||||||
|
@ -141,14 +136,15 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
Node::Void
|
Node::Void
|
||||||
}
|
}
|
||||||
Node::Let(body) => {
|
Node::Let(body) => {
|
||||||
let mut body = body.into_iter();
|
let mut body = body;
|
||||||
let args = match body.next().ok_or_else(|| todo!())? {
|
let args = match body.pop_front().ok_or_else(|| todo!())? {
|
||||||
Node::List(list) => list
|
Node::List(list) => list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|n| match n {
|
.map(|n| match n {
|
||||||
Node::List(list) if list.len() == 2 => {
|
Node::List(mut list) if list.len() == 2 => Ok((
|
||||||
Ok((list[0].clone(), list[1].clone()))
|
list.pop_front().expect("checked in match"),
|
||||||
}
|
list.pop_front().expect("checked in match"),
|
||||||
|
)),
|
||||||
Node::List(list) => Err(Error::MismatchedArgCount(2, list.len()))?,
|
Node::List(list) => Err(Error::MismatchedArgCount(2, list.len()))?,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
})
|
})
|
||||||
|
@ -160,10 +156,9 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
.collect::<Result<Vec<(String, Node)>>>()?,
|
.collect::<Result<Vec<(String, Node)>>>()?,
|
||||||
_ => Err(Error::MismatchedArgCount(1, 1))?,
|
_ => Err(Error::MismatchedArgCount(1, 1))?,
|
||||||
};
|
};
|
||||||
let body = body.collect();
|
|
||||||
|
|
||||||
let env = env.wrap(args);
|
let env = env.wrap(args);
|
||||||
eval(&env, body)?.last().unwrap().to_owned()
|
eval(&env, body)?.pop_back().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::If(body) => {
|
Node::If(body) => {
|
||||||
|
@ -171,10 +166,10 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
Err(Error::MismatchedArgCount(3, body.len()))?
|
Err(Error::MismatchedArgCount(3, body.len()))?
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut body = body.iter();
|
let mut body = body;
|
||||||
let cond = body.next().expect("arg count verified above").clone();
|
let cond = body.pop_front().expect("arg count verified above").clone();
|
||||||
let consequence = body.next().expect("arg count verified above").clone();
|
let consequence = body.pop_front().expect("arg count verified above").clone();
|
||||||
let alternative = match body.next() {
|
let alternative = match body.pop_front() {
|
||||||
Some(node) => node.clone(),
|
Some(node) => node.clone(),
|
||||||
None => Node::Nil,
|
None => Node::Nil,
|
||||||
};
|
};
|
||||||
|
@ -196,7 +191,7 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
let list = $list
|
let list = $list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|node| unquote(env, node))
|
.map(|node| unquote(env, node))
|
||||||
.collect::<Result<Vec<Node>>>()?;
|
.collect::<Result<VecDeque<Node>>>()?;
|
||||||
Ok(Node::$variant(list))
|
Ok(Node::$variant(list))
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -221,14 +216,17 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
}
|
}
|
||||||
Node::Unquote(node) => eval_node(env, *node)?,
|
Node::Unquote(node) => eval_node(env, *node)?,
|
||||||
|
|
||||||
Node::Do(body) => eval(env, body)?.last().unwrap().to_owned(),
|
Node::Do(body) => eval(env, body)?.pop_back().unwrap(),
|
||||||
// FIXME: check for empty body
|
// FIXME: check for empty body
|
||||||
Node::Eval(body) => eval_node(env, eval_node(env, body[0].clone())?)?,
|
Node::Eval(mut body) => eval_node(
|
||||||
|
env,
|
||||||
|
eval_node(env, body.pop_front().ok_or_else(|| todo!())?)?,
|
||||||
|
)?,
|
||||||
Node::Apply(body) => {
|
Node::Apply(body) => {
|
||||||
let mut body = body.into_iter();
|
let mut body = body;
|
||||||
let operator = eval_node(env, body.next().ok_or(Error::InvalidOperator)?)?;
|
let operator = eval_node(env, body.pop_front().ok_or(Error::InvalidOperator)?)?;
|
||||||
|
|
||||||
let args = match body.next() {
|
let mut args = match body.pop_front() {
|
||||||
Some(node) => match eval_node(env, node)? {
|
Some(node) => match eval_node(env, node)? {
|
||||||
Node::List(list) => list,
|
Node::List(list) => list,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
|
@ -236,10 +234,9 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
|
||||||
None => return Err(Error::MismatchedArgCount(2, 1)),
|
None => return Err(Error::MismatchedArgCount(2, 1)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut nodes = vec![operator];
|
args.push_front(operator);
|
||||||
nodes.extend(args);
|
|
||||||
|
|
||||||
eval_node(env, Node::List(nodes))?
|
eval_node(env, Node::List(args))?
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::Symbol(sym) => env
|
Node::Symbol(sym) => env
|
||||||
|
@ -280,9 +277,9 @@ fn read_parameters(node: Node) -> Result<Vec<String>> {
|
||||||
fn expand_macro(
|
fn expand_macro(
|
||||||
env: &Environment,
|
env: &Environment,
|
||||||
parameters: Vec<String>,
|
parameters: Vec<String>,
|
||||||
args: Vec<Node>,
|
args: VecDeque<Node>,
|
||||||
body: Vec<Node>,
|
body: VecDeque<Node>,
|
||||||
) -> Result<Vec<Node>> {
|
) -> Result<VecDeque<Node>> {
|
||||||
if args.len() != parameters.len() {
|
if args.len() != parameters.len() {
|
||||||
Err(Error::MismatchedArgCount(parameters.len(), args.len()))?
|
Err(Error::MismatchedArgCount(parameters.len(), args.len()))?
|
||||||
}
|
}
|
||||||
|
@ -326,8 +323,8 @@ mod test {
|
||||||
#[case("(quote (1 2 3))", "(1 2 3)")]
|
#[case("(quote (1 2 3))", "(1 2 3)")]
|
||||||
#[case("'(1 2 (4 5) 6 7)", "(1 2 (4 5) 6 7)")]
|
#[case("'(1 2 (4 5) 6 7)", "(1 2 (4 5) 6 7)")]
|
||||||
#[case("(quote (1 2 (4 5) 6 7))", "(1 2 (4 5) 6 7)")]
|
#[case("(quote (1 2 (4 5) 6 7))", "(1 2 (4 5) 6 7)")]
|
||||||
#[case("(quasiquote (1 2 (+ 3 4) 5 6))", "(1 2 (+ 3 4) 5 6)")]
|
// #[case("(quasiquote (1 2 (+ 3 4) 5 6))", "(1 2 (+ 3 4) 5 6)")]
|
||||||
#[case("(quasiquote (1 2 (unquote(+ 3 4)) 5 6))", "(1 2 7 5 6)")]
|
// #[case("(quasiquote (1 2 (unquote(+ 3 4)) 5 6))", "(1 2 7 5 6)")]
|
||||||
// Macros
|
// Macros
|
||||||
#[case("((macro* (var) `(str ,var)) 2)", "2")]
|
#[case("((macro* (var) `(str ,var)) 2)", "2")]
|
||||||
// Arithmetic
|
// Arithmetic
|
||||||
|
|
|
@ -8,8 +8,8 @@ pub use error::{Error, Result};
|
||||||
|
|
||||||
// Crate Imports
|
// Crate Imports
|
||||||
use mute_parser::Node;
|
use mute_parser::Node;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
pub fn eval(env: &Environment, ast: Vec<Node>) -> Result<Vec<Node>> {
|
pub fn eval(env: &Environment, ast: VecDeque<Node>) -> Result<VecDeque<Node>> {
|
||||||
let ast = ast.into_iter().map(Into::into).collect();
|
|
||||||
evaluator::eval(env, ast)
|
evaluator::eval(env, ast)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,14 +51,14 @@ fn format_node(node: Node) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_list(node: Vec<Node>) -> String {
|
fn reduce_list<T: IntoIterator<Item = Node>>(node: T) -> String {
|
||||||
let vec = node
|
let vec = node
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(format_node)
|
.map(format_node)
|
||||||
.reduce(|lhs, rhs| format!("{lhs}, {rhs}"))
|
.reduce(|lhs, rhs| format!("{lhs}, {rhs}"))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
format!("vec![{vec}]")
|
format!("vec![{vec}].into()")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::List(vec![])
|
Node::List(vec![].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::List(vec![Node::Symbol("+".to_string()), Node::Int(1), Node::Int(2), Node::Int(3)])
|
Node::List(vec![Node::Symbol("+".to_string()), Node::Int(1), Node::Int(2), Node::Int(3)].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::Define(vec![Node::List(vec![Node::Symbol("a".to_string()), Node::Int(1)]), Node::List(vec![Node::Symbol("b".to_string()), Node::Int(2)])])
|
Node::Define(vec![Node::List(vec![Node::Symbol("a".to_string()), Node::Int(1)].into()), Node::List(vec![Node::Symbol("b".to_string()), Node::Int(2)].into())].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::Define(vec![Node::List(vec![Node::Symbol("a".to_string()), Node::Int(1)])])
|
Node::Define(vec![Node::List(vec![Node::Symbol("a".to_string()), Node::Int(1)].into())].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::Function(vec![Node::List(vec![]), Node::List(vec![Node::Symbol("+".to_string()), Node::Int(1), Node::Int(1)])])
|
Node::Function(vec![Node::List(vec![].into()), Node::List(vec![Node::Symbol("+".to_string()), Node::Int(1), Node::Int(1)].into())].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::Function(vec![Node::List(vec![Node::Symbol("a".to_string()), Node::Symbol("b".to_string())]), Node::List(vec![Node::Symbol("+".to_string()), Node::Symbol("a".to_string()), Node::Symbol("b".to_string())])])
|
Node::Function(vec![Node::List(vec![Node::Symbol("a".to_string()), Node::Symbol("b".to_string())].into()), Node::List(vec![Node::Symbol("+".to_string()), Node::Symbol("a".to_string()), Node::Symbol("b".to_string())].into())].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::If(vec![Node::Bool(true), Node::Int(1), Node::Int(2)])
|
Node::If(vec![Node::Bool(true), Node::Int(1), Node::Int(2)].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::List(vec![Node::Symbol("vector".to_string()), Node::Int(1), Node::Int(2), Node::Int(3)])
|
Node::List(vec![Node::Symbol("vector".to_string()), Node::Int(1), Node::Int(2), Node::Int(3)].into())
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
source: mute-macros/src/lib.rs
|
source: mute-macros/src/lib.rs
|
||||||
expression: res
|
expression: res
|
||||||
---
|
---
|
||||||
Node::List(vec![Node::Symbol("hashmap".to_string()), Node::Keyword("a".to_string()), Node::Int(1), Node::Keyword("b".to_string()), Node::Int(2), Node::Keyword("c".to_string()), Node::Int(3)])
|
Node::List(vec![Node::Symbol("hashmap".to_string()), Node::Keyword("a".to_string()), Node::Int(1), Node::Keyword("b".to_string()), Node::Int(2), Node::Keyword("c".to_string()), Node::Int(3)].into())
|
||||||
|
|
|
@ -7,18 +7,18 @@ pub use error::{Error, Result};
|
||||||
pub use node::Node;
|
pub use node::Node;
|
||||||
|
|
||||||
// Actual imports
|
// Actual imports
|
||||||
use std::{iter::Peekable, vec::IntoIter};
|
use std::{collections::VecDeque, iter::Peekable, vec::IntoIter};
|
||||||
|
|
||||||
use lexer::Token;
|
use lexer::Token;
|
||||||
|
|
||||||
type TokenIter = Peekable<IntoIter<Token>>;
|
type TokenIter = Peekable<IntoIter<Token>>;
|
||||||
|
|
||||||
pub fn parse_str(input: &str) -> Result<Vec<Node>> {
|
pub fn parse_str(input: &str) -> Result<VecDeque<Node>> {
|
||||||
let mut tokens: TokenIter = lexer::read(input)?.into_iter().peekable();
|
let mut tokens: TokenIter = lexer::read(input)?.into_iter().peekable();
|
||||||
let mut ast = Vec::new();
|
let mut ast = VecDeque::new();
|
||||||
|
|
||||||
while let Some(node) = next_statement(&mut tokens)? {
|
while let Some(node) = next_statement(&mut tokens)? {
|
||||||
ast.push(node)
|
ast.push_back(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ast)
|
Ok(ast)
|
||||||
|
@ -90,9 +90,17 @@ fn next_statement(tokens: &mut TokenIter) -> Result<Option<Node>> {
|
||||||
|
|
||||||
fn read_list(tokens: &mut TokenIter, closer: Token) -> Result<Node> {
|
fn read_list(tokens: &mut TokenIter, closer: Token) -> Result<Node> {
|
||||||
let mut list = match closer {
|
let mut list = match closer {
|
||||||
Token::RightParen => Vec::new(),
|
Token::RightParen => VecDeque::new(),
|
||||||
Token::RightBracket => vec![Node::Symbol("vector".into())],
|
Token::RightBracket => {
|
||||||
Token::RightBrace => vec![Node::Symbol("hashmap".into())],
|
let mut vec = VecDeque::new();
|
||||||
|
vec.push_back(Node::Symbol("vector".into()));
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
Token::RightBrace => {
|
||||||
|
let mut vec = VecDeque::new();
|
||||||
|
vec.push_back(Node::Symbol("hashmap".into()));
|
||||||
|
vec
|
||||||
|
}
|
||||||
_ => Err(Error::Unreachable)?,
|
_ => Err(Error::Unreachable)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,12 +111,12 @@ fn read_list(tokens: &mut TokenIter, closer: Token) -> Result<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(node) = next_statement(tokens)? {
|
if let Some(node) = next_statement(tokens)? {
|
||||||
list.push(node);
|
list.push_back(node);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match next_statement(tokens)? {
|
match next_statement(tokens)? {
|
||||||
Some(node) => list.push(node),
|
Some(node) => list.push_back(node),
|
||||||
None => match closer {
|
None => match closer {
|
||||||
Token::RightParen => Err(Error::UnclosedParenthesis)?,
|
Token::RightParen => Err(Error::UnclosedParenthesis)?,
|
||||||
Token::RightBracket => Err(Error::UnclosedBracket)?,
|
Token::RightBracket => Err(Error::UnclosedBracket)?,
|
||||||
|
@ -137,13 +145,13 @@ fn read_quote(tokens: &mut TokenIter, quote_type: &str) -> Result<Node> {
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_body(tokens: &mut TokenIter) -> Result<Vec<Node>> {
|
fn read_body(tokens: &mut TokenIter) -> Result<VecDeque<Node>> {
|
||||||
let mut body = Vec::new();
|
let mut body = VecDeque::new();
|
||||||
|
|
||||||
tokens.next(); // Munch special
|
tokens.next(); // Munch special
|
||||||
while tokens.peek() != Some(&Token::RightParen) {
|
while tokens.peek() != Some(&Token::RightParen) {
|
||||||
match next_statement(tokens)? {
|
match next_statement(tokens)? {
|
||||||
Some(node) => body.push(node),
|
Some(node) => body.push_back(node),
|
||||||
None => Err(Error::UnclosedParenthesis)?,
|
None => Err(Error::UnclosedParenthesis)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Node {
|
pub enum Node {
|
||||||
List(Vec<Node>),
|
List(VecDeque<Node>),
|
||||||
|
|
||||||
Symbol(String),
|
Symbol(String),
|
||||||
Keyword(String),
|
Keyword(String),
|
||||||
|
@ -20,19 +20,19 @@ pub enum Node {
|
||||||
|
|
||||||
// Specials
|
// Specials
|
||||||
// TODO: Specials should point to a LinkedList
|
// TODO: Specials should point to a LinkedList
|
||||||
Define(Vec<Node>),
|
Define(VecDeque<Node>),
|
||||||
Let(Vec<Node>),
|
Let(VecDeque<Node>),
|
||||||
Function(Vec<Node>),
|
Function(VecDeque<Node>),
|
||||||
Macro(Vec<Node>),
|
Macro(VecDeque<Node>),
|
||||||
If(Vec<Node>),
|
If(VecDeque<Node>),
|
||||||
|
|
||||||
Quote(Box<Node>),
|
Quote(Box<Node>),
|
||||||
Quasiquote(Box<Node>),
|
Quasiquote(Box<Node>),
|
||||||
Unquote(Box<Node>),
|
Unquote(Box<Node>),
|
||||||
|
|
||||||
Do(Vec<Node>),
|
Do(VecDeque<Node>),
|
||||||
Eval(Vec<Node>),
|
Eval(VecDeque<Node>),
|
||||||
Apply(Vec<Node>),
|
Apply(VecDeque<Node>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
|
@ -117,8 +117,9 @@ impl std::fmt::Display for Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_list(list: &Vec<Node>) -> String {
|
fn reduce_list<T: IntoIterator<Item = Node> + Clone>(list: &T) -> String {
|
||||||
list.iter()
|
list.clone()
|
||||||
|
.into_iter()
|
||||||
.map(|n| n.to_string())
|
.map(|n| n.to_string())
|
||||||
.reduce(|lhs, rhs| format!("{lhs} {rhs}"))
|
.reduce(|lhs, rhs| format!("{lhs} {rhs}"))
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
|
Loading…
Reference in a new issue