a ton of stuff idk more ir work
This commit is contained in:
+51
-30
@@ -1,6 +1,4 @@
|
||||
use super::{
|
||||
CharCursor, MaybeParsable, ParserError, ParserErrors, Symbol, Token, TokenCursor,
|
||||
};
|
||||
use super::{CharCursor, MaybeParsable, ParserMsg, ParserOutput, Symbol, Token, TokenCursor};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
@@ -21,49 +19,72 @@ pub struct Number {
|
||||
impl MaybeParsable for Literal {
|
||||
fn maybe_parse(
|
||||
cursor: &mut TokenCursor,
|
||||
_: &mut ParserErrors,
|
||||
) -> Result<Option<Self>, ParserError> {
|
||||
_: &mut ParserOutput,
|
||||
) -> Result<Option<Self>, ParserMsg> {
|
||||
let inst = cursor.expect_peek()?;
|
||||
let mut res = match &inst.token {
|
||||
Ok(Some(match &inst.token {
|
||||
Token::Symbol(Symbol::SingleQuote) => {
|
||||
let chars = cursor.chars();
|
||||
let c = chars.expect_next()?;
|
||||
chars.expect('\'')?;
|
||||
cursor.next();
|
||||
Self::Char(c)
|
||||
}
|
||||
Token::Symbol(Symbol::DoubleQuote) => Self::String(string_from(cursor.chars())?),
|
||||
Token::Ident(text) => {
|
||||
Token::Symbol(Symbol::DoubleQuote) => {
|
||||
let res = Self::String(string_from(cursor.chars())?);
|
||||
cursor.next();
|
||||
res
|
||||
}
|
||||
Token::Word(text) => {
|
||||
let first = text.chars().next().unwrap();
|
||||
if first.is_ascii_digit() {
|
||||
Self::Number(Number {
|
||||
whole: text.to_string(),
|
||||
decimal: None,
|
||||
ty: None,
|
||||
})
|
||||
} else {
|
||||
if !first.is_ascii_digit() {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
_ => return Ok(None),
|
||||
};
|
||||
cursor.next();
|
||||
if let (Some(next), Self::Number(num)) = (cursor.peek(), &mut res) {
|
||||
if next.token.is_symbol(Symbol::Dot) {
|
||||
let (whole, ty) = parse_whole_num(text);
|
||||
let mut num = Number {
|
||||
whole,
|
||||
decimal: None,
|
||||
ty,
|
||||
};
|
||||
cursor.next();
|
||||
if let Some(next) = cursor.peek() {
|
||||
if let Token::Ident(i) = &next.token {
|
||||
if i.chars().next().unwrap().is_ascii_digit() {
|
||||
num.decimal = Some(i.to_string());
|
||||
cursor.next();
|
||||
if num.ty.is_none() && cursor.peek().is_some_and(|i| i.is_symbol(Symbol::Dot)) {
|
||||
cursor.next();
|
||||
if let Some(next) = cursor.peek() {
|
||||
if let Token::Word(i) = &next.token {
|
||||
if i.chars().next().unwrap().is_ascii_digit() {
|
||||
let (decimal, ty) = parse_whole_num(i);
|
||||
num.decimal = Some(decimal);
|
||||
num.ty = ty;
|
||||
cursor.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Self::Number(num)
|
||||
}
|
||||
}
|
||||
Ok(Some(res))
|
||||
_ => return Ok(None),
|
||||
}))
|
||||
}
|
||||
}
|
||||
pub fn string_from(cursor: &mut CharCursor) -> Result<String, ParserError> {
|
||||
|
||||
pub fn parse_whole_num(text: &str) -> (String, Option<String>) {
|
||||
let mut whole = String::new();
|
||||
let mut ty = String::new();
|
||||
for c in text.chars() {
|
||||
if ty.is_empty() {
|
||||
if c.is_ascii_digit() {
|
||||
whole.push(c);
|
||||
} else if c != '_' {
|
||||
ty.push(c);
|
||||
}
|
||||
} else {
|
||||
ty.push(c);
|
||||
}
|
||||
}
|
||||
(whole, if ty.is_empty() { None } else { Some(ty) })
|
||||
}
|
||||
|
||||
pub fn string_from(cursor: &mut CharCursor) -> Result<String, ParserMsg> {
|
||||
let mut str = String::new();
|
||||
loop {
|
||||
let c = cursor.expect_next()?;
|
||||
@@ -107,7 +128,7 @@ impl Debug for Number {
|
||||
write!(f, ".{}", d)?;
|
||||
}
|
||||
if let Some(ty) = &self.ty {
|
||||
write!(f, "T{}", ty)?;
|
||||
write!(f, "_{}", ty)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user