Constants work and *finally* fix the off-by-one in lexing
This commit is contained in:
		
							parent
							
								
									47477732ba
								
							
						
					
					
						commit
						74b29455e5
					
				
					 1 changed files with 36 additions and 4 deletions
				
			
		| 
						 | 
					@ -120,6 +120,8 @@ impl Atom {
 | 
				
			||||||
			Atom::Const(c) => match c {
 | 
								Atom::Const(c) => match c {
 | 
				
			||||||
				Const::Pi => 3.141592653589793238462643383279,
 | 
									Const::Pi => 3.141592653589793238462643383279,
 | 
				
			||||||
				Const::E => 2.718281828459045235360287471352,
 | 
									Const::E => 2.718281828459045235360287471352,
 | 
				
			||||||
 | 
									Const::Inf => f64::INFINITY,
 | 
				
			||||||
 | 
									Const::Nan => f64::NAN,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -167,8 +169,23 @@ impl Func {
 | 
				
			||||||
enum Const {
 | 
					enum Const {
 | 
				
			||||||
	Pi,
 | 
						Pi,
 | 
				
			||||||
	E,
 | 
						E,
 | 
				
			||||||
 | 
						Inf,
 | 
				
			||||||
 | 
						Nan,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Const {
 | 
				
			||||||
 | 
						fn names() -> &'static [(Const, &'static [&'static str])] {
 | 
				
			||||||
 | 
							&[
 | 
				
			||||||
 | 
								(Const::Pi, &["pi", "PI", "π"]),
 | 
				
			||||||
 | 
								(Const::E, &["e", "euler"]),
 | 
				
			||||||
 | 
								(Const::Inf, &["inf", "infinity", "∞"]),
 | 
				
			||||||
 | 
								(Const::Nan, &["nan", "NaN"])
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Copy, Clone, PartialEq)]
 | 
					#[derive(Debug, Copy, Clone, PartialEq)]
 | 
				
			||||||
enum ParseErr {
 | 
					enum ParseErr {
 | 
				
			||||||
	Eof,
 | 
						Eof,
 | 
				
			||||||
| 
						 | 
					@ -224,12 +241,22 @@ impl Lexer<'_> {
 | 
				
			||||||
						let len = self.data_ptr.chars().count();
 | 
											let len = self.data_ptr.chars().count();
 | 
				
			||||||
						for (f, names) in Func::names() {
 | 
											for (f, names) in Func::names() {
 | 
				
			||||||
							for name in *names {
 | 
												for name in *names {
 | 
				
			||||||
								if self.data_ptr.starts_with(name) {
 | 
													let n_len = name.chars().count();
 | 
				
			||||||
									self.next_by = if self.data_ptr.len() > name.len() { name.chars().count() + 1} else { name.chars().count() };
 | 
													if self.data_ptr.starts_with(name) && (len == n_len || !self.data_ptr.chars().nth(n_len).unwrap().is_alphabetic()) {
 | 
				
			||||||
 | 
														self.next_by = name.chars().count();
 | 
				
			||||||
									return Ok(Token::Op(Op::Func(*f)));
 | 
														return Ok(Token::Op(Op::Func(*f)));
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
											for (f, names) in Const::names() {
 | 
				
			||||||
 | 
												for name in *names {
 | 
				
			||||||
 | 
													let n_len = name.chars().count();
 | 
				
			||||||
 | 
													if self.data_ptr.starts_with(name) && (len == n_len || !self.data_ptr.chars().nth(n_len).unwrap().is_alphabetic()) {
 | 
				
			||||||
 | 
														self.next_by = name.chars().count();
 | 
				
			||||||
 | 
														return Ok(Token::Atom(Atom::Const(*f)));
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
						debug!("got invalid char '{}'", val);
 | 
											debug!("got invalid char '{}'", val);
 | 
				
			||||||
						Err(ParseErr::Invalid)
 | 
											Err(ParseErr::Invalid)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
| 
						 | 
					@ -299,8 +326,13 @@ impl Parser<'_> {
 | 
				
			||||||
				Token::Op(op) => match op {
 | 
									Token::Op(op) => match op {
 | 
				
			||||||
					Op::LParen => {
 | 
										Op::LParen => {
 | 
				
			||||||
						let val = self.parse_expr(0.0);
 | 
											let val = self.parse_expr(0.0);
 | 
				
			||||||
						assert_eq!(self.lex.next(), Ok(Token::Op(Op::RParen)));
 | 
											if self.lex.next() != Ok(Token::Op(Op::RParen)) {
 | 
				
			||||||
						val
 | 
												debug!("Unclosed parens");
 | 
				
			||||||
 | 
												Err(ParseErr::Invalid)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else {
 | 
				
			||||||
 | 
												val
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
					// Op::Func(f) => Ok(Expr::Node(Op::Func(f), vec![self.parse_expr(op.get_lbp())?])),
 | 
										// Op::Func(f) => Ok(Expr::Node(Op::Func(f), vec![self.parse_expr(op.get_lbp())?])),
 | 
				
			||||||
					_ => match op.bp_prefix() {
 | 
										_ => match op.bp_prefix() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue