forked from asklyphe-public/asklyphe
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