summaryrefslogtreecommitdiff
path: root/src/lang
diff options
context:
space:
mode:
Diffstat (limited to 'src/lang')
-rw-r--r--src/lang/parser.rs226
-rw-r--r--src/lang/tokenizer.rs5
2 files changed, 184 insertions, 47 deletions
diff --git a/src/lang/parser.rs b/src/lang/parser.rs
index c49cf65..35df372 100644
--- a/src/lang/parser.rs
+++ b/src/lang/parser.rs
@@ -7,6 +7,7 @@ use synth::*;
#[derive(Debug)]
pub enum ErrorKind {
Unexpected(TokType, TokType),
+ Unparseable(TokType, String),
ExpectedOp(char, TokType),
UnknownGen(String),
}
@@ -26,6 +27,7 @@ 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::ExpectedOp(c, found) => format!("Expected {:?}, found {:?}", c, found),
ErrorKind::UnknownGen(ref s) => format!("Unknown generator name {}", s),
};
@@ -76,20 +78,27 @@ impl<T: Iterator<Item=char>> Parser<T> {
pub fn push_back(&mut self, tok: Token) {
match self.pushback {
None => {
- self.pushback = Some(mem::replace(&mut self.token, tok));
+ self.pushback = Some(tok);
},
Some(_) => panic!("too many pushbacks on Parser"),
}
}
+ pub fn cur_token(&self) -> &Token {
+ match self.pushback {
+ Some(ref tok) => tok,
+ None => &self.token,
+ }
+ }
+
pub fn expect(&mut self, ty: TokType) -> Result<Token, Box<Error>> {
- if ty == self.token.to_type() {
- Ok(mem::replace(&mut self.token, match self.pushback {
- Some(_) => mem::replace(&mut self.pushback, None).unwrap(),
- None => self.tzr.next_token()?,
- }))
- } else {
+ if ty != self.cur_token().to_type() {
Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), ty)).into())
+ } else {
+ Ok(match self.pushback {
+ Some(_) => mem::replace(&mut self.pushback, None).unwrap(),
+ None => mem::replace(&mut self.token, self.tzr.next_token()?),
+ })
}
}
@@ -101,9 +110,18 @@ impl<T: Iterator<Item=char>> Parser<T> {
}
pub fn expect_op(&mut self, oper: char) -> Result<(), Box<Error>> {
- match self.token {
+ eprintln!("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.token.to_type())).into()),
+ _ => Err(ErrorType::new(ErrorKind::ExpectedOp(oper, self.cur_token().to_type())).into()),
+ }
+ }
+
+ pub fn peek_op(&self, oper: char) -> bool {
+ eprintln!("peek_op: {:?} ({})", self.cur_token(), oper);
+ match *self.cur_token() {
+ Token::Oper(c) if c == oper => true,
+ _ => false
}
}
@@ -117,17 +135,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
break;
}
- /* TODO: Can't yet clone a GenBox safely
- let repeat = match self.token {
- Token::Integer(v) => {
- self.expect_op('*')?;
- v
- },
- _ => 1,
- };
- */
-
- ret.push(self.parse_gen()?);
+ ret.push(self.parse_gen_rel()?);
if self.expect_op(',').is_err() {
self.expect_op(']')?;
@@ -138,17 +146,150 @@ impl<T: Iterator<Item=char>> Parser<T> {
Ok(ret)
}
- pub fn parse_gen(&mut self) -> Result<GenBox, Box<Error>> {
- let name = self.expect_ident()?;
- let mut params = self.parse_factory_params()?;
- let factory = match self.factories.get(&name) {
- Some(fac) => fac,
- None => return Err(ErrorType::new(ErrorKind::UnknownGen(name)).into()),
- };
+ pub fn parse_gen_rel(&mut self) -> Result<GenBox, Box<Error>> {
+ let left = self.parse_gen_terms()?;
+
+ match *self.cur_token() {
+ Token::Oper(c) => {
+ 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 },
+ ('<', _) => RelOp::Less,
+ ('>', _) => RelOp::Greater,
+ _ => return Err(ErrorType::new(ErrorKind::Unparseable(TokType::Oper, "rel expr".to_string())).into()),
+ };
+ 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())))?;
+ factory.new(&mut params).map_err(Into::into)
+ } else {
+ Ok(left)
+ }
+ },
+ _ => Ok(left),
+ }
+ }
+
+ pub fn parse_gen_terms(&mut self) -> Result<GenBox, Box<Error>> {
+ let mut gens: Vec<GenBox> = Vec::new();
+ gens.push(self.parse_gen_factors()?);
+
+ loop {
+ match *self.cur_token() {
+ 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)?);
+ },
+ _ => break,
+ }
+ }
+
+ if gens.len() == 1 {
+ return Ok(gens.pop().unwrap());
+ }
+
+ 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));
+ }
+ 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>> {
+ let mut gens: Vec<GenBox> = Vec::new();
+ gens.push(self.parse_gen()?);
+
+ loop {
+ match *self.cur_token() {
+ 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)?);
+ },
+ _ => break,
+ }
+ }
+
+ if gens.len() == 1 {
+ return Ok(gens.pop().unwrap());
+ }
+
+ 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));
+ }
+ 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>> {
+ 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()));
+ params.vars.insert("1".to_string(), ParamValue::Integer(v));
+ 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()));
+ params.vars.insert("1".to_string(), ParamValue::Float(v));
+ 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('(') {
+ let mut params = self.parse_factory_params()?;
+ let factory = match self.factories.get(&name) {
+ Some(fac) => fac,
+ None => return Err(ErrorType::new(ErrorKind::UnknownGen(name)).into()),
+ };
+ 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())))?;
+ factory.new(&mut params).map_err(Into::into)
+ }
+ },
+ Token::Oper('(') => {
+ eprintln!("consuming paren in parse_gen");
+ self.expect(TokType::Oper)?;
+ let ret = self.parse_gen_rel()?;
+ eprintln!("parenthesized generator is concluding");
+ self.expect_op(')')?;
+ Ok(ret)
+ },
+ _ => 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>> {
+ eprintln!("consuming paren in factory_params");
self.expect_op('(')?;
let mut params: FactoryParameters = FactoryParameters { env: self.env.clone(), ..Default::default() };
@@ -161,7 +302,9 @@ impl<T: Iterator<Item=char>> Parser<T> {
params.vars.insert(nm, vl);
ctr = new_ctr;
- if self.expect_op(',').is_err() {
+ eprintln!("before factory_params comma, tok is {:?}", self.cur_token());
+ if self.expect_op(',').map_err(|e| eprintln!("factory_params consume comma failed: {:?}", e)).is_err() {
+ eprintln!("factory_params is concluding");
self.expect_op(')')?;
break;
}
@@ -177,14 +320,9 @@ impl<T: Iterator<Item=char>> Parser<T> {
if self.expect_op('=').is_ok() {
nm
} else {
- match self.token {
- Token::Oper(c) if c == '(' => {
- self.push_back(Token::Ident(nm));
- ctr += 1;
- (ctr - 1).to_string()
- },
- _ => return Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), TokType::Ident)).into()),
- }
+ self.push_back(Token::Ident(nm));
+ ctr += 1;
+ (ctr - 1).to_string()
}
},
Err(_) => {
@@ -193,16 +331,12 @@ impl<T: Iterator<Item=char>> Parser<T> {
},
};
- let ret = match self.token {
- Token::Integer(v) => Ok((name, ParamValue::Integer(v), ctr)),
- Token::Float(v) => Ok((name, ParamValue::Float(v), ctr)),
- Token::String(ref v) => Ok((name, ParamValue::String(v.clone()), ctr)),
- Token::Ident(_) => return Ok((name, ParamValue::Generator(self.parse_gen()?), ctr)),
- _ => return Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), TokType::Ident)).into()),
- };
+ eprintln!("about to consume param value, token is {:?}", self.cur_token());
- let tp = self.token.to_type();
- self.expect(tp)?;
- ret
+ 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()),
+ }
}
}
diff --git a/src/lang/tokenizer.rs b/src/lang/tokenizer.rs
index 1d62f3e..6de825b 100644
--- a/src/lang/tokenizer.rs
+++ b/src/lang/tokenizer.rs
@@ -425,9 +425,12 @@ impl<T: Iterator<Item=char>> Tokenizer<T> {
floating = true;
buffer.push(cc);
buffer.push(ncc);
- } else {
+ } else if ncc.is_digit(10) {
buffer.push(cc);
buffer.push(ncc);
+ } else {
+ self.push_back(ncc);
+ return Ok(Token::Integer(0));
}
} else {
buffer.push(cc);