summaryrefslogtreecommitdiff
path: root/src/lang/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lang/parser.rs')
-rw-r--r--src/lang/parser.rs284
1 files changed, 206 insertions, 78 deletions
diff --git a/src/lang/parser.rs b/src/lang/parser.rs
index ec8ef40..ac7eccd 100644
--- a/src/lang/parser.rs
+++ b/src/lang/parser.rs
@@ -1,8 +1,11 @@
-use std::{mem, fmt};
-use std::error::Error;
+use super::{TokType, Token, Tokenizer};
+use crate::synth::{
+ all_factories, Environment, FactoryParameters, GenBox, GenFactoryErrorType, GeneratorFactory,
+ ParamValue, RelOp,
+};
use std::collections::HashMap;
-use super::*;
-use synth::*;
+use std::error::Error;
+use std::{fmt, mem};
/*
macro_rules! dprintln {
@@ -36,8 +39,12 @@ impl ErrorType {
};
ret.desc = match ret.kind {
- ErrorKind::Unexpected(found, expected) => format!("Found {:?}, expected {:?}", found, expected),
- ErrorKind::Unparseable(found, ref term) => format!("Cannot consume {:?} token in {}", found, term),
+ ErrorKind::Unexpected(found, expected) => {
+ format!("Found {:?}, expected {:?}", found, expected)
+ }
+ ErrorKind::Unparseable(found, ref term) => {
+ format!("Cannot consume {:?} token in {}", found, term)
+ }
ErrorKind::ExpectedOp(c, found) => format!("Expected {:?}, found {:?}", c, found),
ErrorKind::UnknownGen(ref s) => format!("Unknown generator name {}", s),
};
@@ -61,20 +68,20 @@ impl Error for ErrorType {
impl fmt::Display for ErrorType {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- write!(f, "{}", self.description())
+ write!(f, "{}", self.to_string())
}
}
-pub struct Parser<T: Iterator<Item=char>> {
+pub struct Parser<T: Iterator<Item = char>> {
tzr: Tokenizer<T>,
env: Environment,
token: Token,
pushback: Option<Token>,
- factories: HashMap<String, &'static GeneratorFactory>,
+ factories: HashMap<String, &'static dyn GeneratorFactory>,
}
-impl<T: Iterator<Item=char>> Parser<T> {
- pub fn new(mut tzr: Tokenizer<T>, env: Environment) -> Result<Parser<T>, Box<Error>> {
+impl<T: Iterator<Item = char>> Parser<T> {
+ pub fn new(mut tzr: Tokenizer<T>, env: Environment) -> Result<Parser<T>, Box<dyn Error>> {
let token = tzr.next_token()?;
Ok(Parser {
tzr: tzr,
@@ -89,7 +96,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
match self.pushback {
None => {
self.pushback = Some(tok);
- },
+ }
Some(_) => panic!("too many pushbacks on Parser"),
}
}
@@ -101,7 +108,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
}
}
- pub fn expect(&mut self, ty: TokType) -> Result<Token, Box<Error>> {
+ pub fn expect(&mut self, ty: TokType) -> Result<Token, Box<dyn Error>> {
if ty != self.cur_token().to_type() {
Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), ty)).into())
} else {
@@ -112,18 +119,23 @@ impl<T: Iterator<Item=char>> Parser<T> {
}
}
- pub fn expect_ident(&mut self) -> Result<String, Box<Error>> {
+ pub fn expect_ident(&mut self) -> Result<String, Box<dyn Error>> {
match self.expect(TokType::Ident)? {
Token::Ident(s) => Ok(s),
_ => unreachable!(),
}
}
- pub fn expect_op(&mut self, oper: char) -> Result<(), Box<Error>> {
+ pub fn expect_op(&mut self, oper: char) -> Result<(), Box<dyn Error>> {
dprintln!("expect_op: {:?} ({})", self.cur_token(), oper);
match *self.cur_token() {
- Token::Oper(c) if c == oper => { self.expect(TokType::Oper)?; Ok(()) },
- _ => Err(ErrorType::new(ErrorKind::ExpectedOp(oper, self.cur_token().to_type())).into()),
+ Token::Oper(c) if c == oper => {
+ self.expect(TokType::Oper)?;
+ Ok(())
+ }
+ _ => {
+ Err(ErrorType::new(ErrorKind::ExpectedOp(oper, self.cur_token().to_type())).into())
+ }
}
}
@@ -131,15 +143,14 @@ impl<T: Iterator<Item=char>> Parser<T> {
dprintln!("peek_op: {:?} ({})", self.cur_token(), oper);
match *self.cur_token() {
Token::Oper(c) if c == oper => true,
- _ => false
+ _ => false,
}
}
- pub fn parse_gen_vec(&mut self) -> Result<Vec<GenBox>, Box<Error>> {
+ pub fn parse_gen_vec(&mut self) -> Result<Vec<GenBox>, Box<dyn Error>> {
let mut ret: Vec<GenBox> = Vec::new();
self.expect_op('[')?;
-
loop {
if self.expect_op(']').is_ok() {
break;
@@ -156,37 +167,70 @@ impl<T: Iterator<Item=char>> Parser<T> {
Ok(ret)
}
- pub fn parse_gen_rel(&mut self) -> Result<GenBox, Box<Error>> {
+ pub fn parse_gen_rel(&mut self) -> Result<GenBox, Box<dyn Error>> {
let left = self.parse_gen_terms()?;
match *self.cur_token() {
Token::Oper(c) => {
- if c == '>' || c == '!' || c == '<' || c == '=' { // TODO: Conflict with param name
+ if c == '>' || c == '!' || c == '<' || c == '=' {
+ // TODO: Conflict with param name
self.expect(TokType::Oper)?;
let relop = match (c, self.cur_token()) {
- ('<', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::LessEqual },
- ('=', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::Equal },
- ('>', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::Greater },
- ('!', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::NotEqual },
+ ('<', &Token::Oper('=')) => {
+ self.expect(TokType::Oper)?;
+ RelOp::LessEqual
+ }
+ ('=', &Token::Oper('=')) => {
+ self.expect(TokType::Oper)?;
+ RelOp::Equal
+ }
+ ('>', &Token::Oper('=')) => {
+ self.expect(TokType::Oper)?;
+ RelOp::Greater
+ }
+ ('!', &Token::Oper('=')) => {
+ self.expect(TokType::Oper)?;
+ RelOp::NotEqual
+ }
('<', _) => RelOp::Less,
('>', _) => RelOp::Greater,
- _ => return Err(ErrorType::new(ErrorKind::Unparseable(TokType::Oper, "rel expr".to_string())).into()),
+ _ => {
+ return Err(ErrorType::new(ErrorKind::Unparseable(
+ TokType::Oper,
+ "rel expr".to_string(),
+ ))
+ .into())
+ }
+ };
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
};
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
- params.vars.insert("0".to_string(), ParamValue::Generator(left));
- params.vars.insert("1".to_string(), ParamValue::String(relop.to_param_string().to_string()));
- params.vars.insert("2".to_string(), ParamValue::Generator(self.parse_gen_rel()?));
- let factory = self.factories.get("rel").ok_or(ErrorType::new(ErrorKind::UnknownGen("rel".to_string())))?;
+ params
+ .vars
+ .insert("0".to_string(), ParamValue::Generator(left));
+ params.vars.insert(
+ "1".to_string(),
+ ParamValue::String(relop.to_param_string().to_string()),
+ );
+ params.vars.insert(
+ "2".to_string(),
+ ParamValue::Generator(self.parse_gen_rel()?),
+ );
+ let factory = self
+ .factories
+ .get("rel")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("rel".to_string())))?;
factory.new(&mut params).map_err(Into::into)
} else {
Ok(left)
}
- },
+ }
_ => Ok(left),
}
}
- pub fn parse_gen_terms(&mut self) -> Result<GenBox, Box<Error>> {
+ pub fn parse_gen_terms(&mut self) -> Result<GenBox, Box<dyn Error>> {
let mut gens: Vec<GenBox> = Vec::new();
gens.push(self.parse_gen_factors()?);
@@ -195,14 +239,27 @@ impl<T: Iterator<Item=char>> Parser<T> {
Token::Oper('+') => {
self.expect_op('+')?;
gens.push(self.parse_gen_factors()?);
- },
+ }
Token::Oper('-') => {
self.expect_op('-')?;
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
- params.vars.insert("0".to_string(), ParamValue::Generator(self.parse_gen_factors()?));
- let factory = self.factories.get("negate").ok_or(ErrorType::new(ErrorKind::UnknownGen("negate".to_string())))?;
- gens.push(factory.new(&mut params).map_err(GenFactoryErrorType::from)?);
- },
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
+ params.vars.insert(
+ "0".to_string(),
+ ParamValue::Generator(self.parse_gen_factors()?),
+ );
+ let factory = self
+ .factories
+ .get("negate")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("negate".to_string())))?;
+ gens.push(
+ factory
+ .new(&mut params)
+ .map_err(GenFactoryErrorType::from)?,
+ );
+ }
_ => break,
}
}
@@ -211,15 +268,23 @@ impl<T: Iterator<Item=char>> Parser<T> {
return Ok(gens.pop().unwrap());
}
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
for (idx, gen) in gens.into_iter().enumerate() {
- params.vars.insert(idx.to_string(), ParamValue::Generator(gen));
+ params
+ .vars
+ .insert(idx.to_string(), ParamValue::Generator(gen));
}
- let factory = self.factories.get("add").ok_or(ErrorType::new(ErrorKind::UnknownGen("add".to_string())))?;
+ let factory = self
+ .factories
+ .get("add")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("add".to_string())))?;
factory.new(&mut params).map_err(Into::into)
}
- pub fn parse_gen_factors(&mut self) -> Result<GenBox, Box<Error>> {
+ pub fn parse_gen_factors(&mut self) -> Result<GenBox, Box<dyn Error>> {
let mut gens: Vec<GenBox> = Vec::new();
gens.push(self.parse_gen()?);
@@ -228,14 +293,25 @@ impl<T: Iterator<Item=char>> Parser<T> {
Token::Oper('*') => {
self.expect_op('*')?;
gens.push(self.parse_gen()?);
- },
+ }
Token::Oper('/') => {
self.expect_op('/')?;
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
- params.vars.insert("0".to_string(), ParamValue::Generator(self.parse_gen()?));
- let factory = self.factories.get("reciprocate").ok_or(ErrorType::new(ErrorKind::UnknownGen("reciprocate".to_string())))?;
- gens.push(factory.new(&mut params).map_err(GenFactoryErrorType::from)?);
- },
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
+ params
+ .vars
+ .insert("0".to_string(), ParamValue::Generator(self.parse_gen()?));
+ let factory = self.factories.get("reciprocate").ok_or(ErrorType::new(
+ ErrorKind::UnknownGen("reciprocate".to_string()),
+ ))?;
+ gens.push(
+ factory
+ .new(&mut params)
+ .map_err(GenFactoryErrorType::from)?,
+ );
+ }
_ => break,
}
}
@@ -244,32 +320,56 @@ impl<T: Iterator<Item=char>> Parser<T> {
return Ok(gens.pop().unwrap());
}
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
for (idx, gen) in gens.into_iter().enumerate() {
- params.vars.insert(idx.to_string(), ParamValue::Generator(gen));
+ params
+ .vars
+ .insert(idx.to_string(), ParamValue::Generator(gen));
}
- let factory = self.factories.get("mul").ok_or(ErrorType::new(ErrorKind::UnknownGen("mul".to_string())))?;
+ let factory = self
+ .factories
+ .get("mul")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("mul".to_string())))?;
factory.new(&mut params).map_err(Into::into)
}
- pub fn parse_gen(&mut self) -> Result<GenBox, Box<Error>> {
+ pub fn parse_gen(&mut self) -> Result<GenBox, Box<dyn Error>> {
match *self.cur_token() {
Token::Integer(v) => {
self.expect(TokType::Integer)?;
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
- params.vars.insert("0".to_string(), ParamValue::String("_".to_string()));
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
+ params
+ .vars
+ .insert("0".to_string(), ParamValue::String("_".to_string()));
params.vars.insert("1".to_string(), ParamValue::Integer(v));
- let factory = self.factories.get("param").ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?;
+ let factory = self
+ .factories
+ .get("param")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?;
factory.new(&mut params).map_err(Into::into)
- },
+ }
Token::Float(v) => {
self.expect(TokType::Float)?;
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
- params.vars.insert("0".to_string(), ParamValue::String("_".to_string()));
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
+ params
+ .vars
+ .insert("0".to_string(), ParamValue::String("_".to_string()));
params.vars.insert("1".to_string(), ParamValue::Float(v));
- let factory = self.factories.get("param").ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?;
+ let factory = self
+ .factories
+ .get("param")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?;
factory.new(&mut params).map_err(Into::into)
- },
+ }
Token::Ident(_) => {
let name = self.expect_ident()?;
if self.peek_op('(') {
@@ -280,12 +380,20 @@ impl<T: Iterator<Item=char>> Parser<T> {
};
factory.new(&mut params).map_err(Into::into)
} else {
- let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() };
- params.vars.insert("0".to_string(), ParamValue::String(name));
- let factory = self.factories.get("param").ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?;
+ let mut params = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
+ params
+ .vars
+ .insert("0".to_string(), ParamValue::String(name));
+ let factory = self
+ .factories
+ .get("param")
+ .ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?;
factory.new(&mut params).map_err(Into::into)
}
- },
+ }
Token::Oper('(') => {
dprintln!("consuming paren in parse_gen");
self.expect(TokType::Oper)?;
@@ -293,16 +401,23 @@ impl<T: Iterator<Item=char>> Parser<T> {
dprintln!("parenthesized generator is concluding");
self.expect_op(')')?;
Ok(ret)
- },
- _ => Err(ErrorType::new(ErrorKind::Unparseable(self.cur_token().to_type(), "gen".to_string())).into()),
+ }
+ _ => Err(ErrorType::new(ErrorKind::Unparseable(
+ self.cur_token().to_type(),
+ "gen".to_string(),
+ ))
+ .into()),
}
}
- pub fn parse_factory_params(&mut self) -> Result<FactoryParameters, Box<Error>> {
+ pub fn parse_factory_params(&mut self) -> Result<FactoryParameters, Box<dyn Error>> {
dprintln!("consuming paren in factory_params");
self.expect_op('(')?;
- let mut params: FactoryParameters = FactoryParameters { env: self.env.clone(), ..Default::default() };
+ let mut params: FactoryParameters = FactoryParameters {
+ env: self.env.clone(),
+ ..Default::default()
+ };
let mut ctr = 0;
loop {
if self.expect_op(')').is_ok() {
@@ -313,7 +428,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
ctr = new_ctr;
dprintln!("before factory_params comma, tok is {:?}", self.cur_token());
- if self.expect_op(',').map_err(|e| dprintln!("factory_params consume comma failed: {:?}", e)).is_err() {
+ if self.expect_op(',').map_err(|_e| dprintln!("factory_params consume comma failed: {:?}", e)).is_err() {
dprintln!("factory_params is concluding");
self.expect_op(')')?;
break;
@@ -323,7 +438,10 @@ impl<T: Iterator<Item=char>> Parser<T> {
Ok(params)
}
- pub fn parse_param(&mut self, pos: usize) -> Result<(String, ParamValue, usize), Box<Error>> {
+ pub fn parse_param(
+ &mut self,
+ pos: usize,
+ ) -> Result<(String, ParamValue, usize), Box<dyn Error>> {
let mut ctr = pos;
let name = match self.expect_ident() {
Ok(nm) => {
@@ -334,19 +452,29 @@ impl<T: Iterator<Item=char>> Parser<T> {
ctr += 1;
(ctr - 1).to_string()
}
- },
+ }
Err(_) => {
ctr += 1;
(ctr - 1).to_string()
- },
+ }
};
dprintln!("about to consume param value, token is {:?}", self.cur_token());
- match self.cur_token().clone() { // FIXME: Does this really need to be cloned?
- Token::String(ref v) => { self.expect(TokType::String)?; Ok((name, ParamValue::String(v.clone()), ctr)) },
- Token::Integer(_) | Token::Float(_) | Token::Ident(_) | Token::Oper('(') => Ok((name, ParamValue::Generator(self.parse_gen_rel()?), ctr)),
- _ => Err(ErrorType::new(ErrorKind::Unparseable(self.cur_token().to_type(), "param value".to_string())).into()),
+ match self.cur_token().clone() {
+ // FIXME: Does this really need to be cloned?
+ Token::String(ref v) => {
+ self.expect(TokType::String)?;
+ Ok((name, ParamValue::String(v.clone()), ctr))
+ }
+ Token::Integer(_) | Token::Float(_) | Token::Ident(_) | Token::Oper('(') => {
+ Ok((name, ParamValue::Generator(self.parse_gen_rel()?), ctr))
+ }
+ _ => Err(ErrorType::new(ErrorKind::Unparseable(
+ self.cur_token().to_type(),
+ "param value".to_string(),
+ ))
+ .into()),
}
}
}