|
|
|
@ -1,7 +1,4 @@
|
|
|
|
|
use crate::{ |
|
|
|
|
data::text::{self, PosReader, Position}, |
|
|
|
|
vire::Number, |
|
|
|
|
}; |
|
|
|
|
use crate::data::text::{self, PosReader, Position}; |
|
|
|
|
use std::fmt; |
|
|
|
|
|
|
|
|
|
#[derive(Error, Debug)] |
|
|
|
@ -54,7 +51,7 @@ pub enum Data {
|
|
|
|
|
Bool(bool), |
|
|
|
|
Char(char), |
|
|
|
|
None, |
|
|
|
|
Numb(Number), |
|
|
|
|
Numb(i64), |
|
|
|
|
Strn(String), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -189,7 +186,7 @@ fn integer_rad(rd: &mut PosReader, rad: u32) -> Result<Token, Err> {
|
|
|
|
|
false |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let mut n: Number = 0; |
|
|
|
|
let mut n = 0_i64; |
|
|
|
|
|
|
|
|
|
loop { |
|
|
|
|
match rd.next() { |
|
|
|
@ -221,13 +218,12 @@ fn is_sym_init(c: char) -> bool {
|
|
|
|
|
| '/' | ':' | '<' |
|
|
|
|
| '=' | '>' | '?' |
|
|
|
|
| '~' | '_' | '^' |
|
|
|
|
| '+' | '-' |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn is_sym_subs(c: char) -> bool { |
|
|
|
|
is_sym_init(c) |
|
|
|
|
|| c.is_numeric() |
|
|
|
|
|| matches!(c, '0'..='9' | '.' | '+' | '-' | '@') |
|
|
|
|
is_sym_init(c) || c.is_numeric() || matches!(c, '0'..='9' | '.' | '@') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn symbol(rd: &mut PosReader, c: char) -> Result<Token, Err> { |
|
|
|
@ -287,81 +283,83 @@ fn block_comment(rd: &mut PosReader) -> Result<(), Err> {
|
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn tokenize_from(name: &str, data: &str) -> Result<Vec<Token>, Err> { |
|
|
|
|
use self::Type::*; |
|
|
|
|
impl Token { |
|
|
|
|
pub fn read_all(name: &str, data: &str) -> Result<Vec<Self>, Err> { |
|
|
|
|
use self::Type::*; |
|
|
|
|
|
|
|
|
|
let mut tokens = Vec::new(); |
|
|
|
|
let rd = &mut PosReader::new(data, text::ellipsize_small_str(name)); |
|
|
|
|
let mut tokens = Vec::new(); |
|
|
|
|
let rd = &mut PosReader::new(data, text::ellipsize_small_str(name)); |
|
|
|
|
|
|
|
|
|
while let Some(c) = rd.next() { |
|
|
|
|
let tk = match c { |
|
|
|
|
// line comments
|
|
|
|
|
';' => { |
|
|
|
|
line_comment(rd)?; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
while let Some(c) = rd.next() { |
|
|
|
|
let tk = match c { |
|
|
|
|
// line comments
|
|
|
|
|
';' => { |
|
|
|
|
line_comment(rd)?; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// basic tokens
|
|
|
|
|
'(' => new_tok(rd, Br1O, Data::None), |
|
|
|
|
')' => new_tok(rd, Br1C, Data::None), |
|
|
|
|
'[' => new_tok(rd, Br3O, Data::None), |
|
|
|
|
']' => new_tok(rd, Br3C, Data::None), |
|
|
|
|
// basic tokens
|
|
|
|
|
'(' => new_tok(rd, Br1O, Data::None), |
|
|
|
|
')' => new_tok(rd, Br1C, Data::None), |
|
|
|
|
'[' => new_tok(rd, Br3O, Data::None), |
|
|
|
|
']' => new_tok(rd, Br3C, Data::None), |
|
|
|
|
|
|
|
|
|
'.' => new_tok(delim_end(rd)?, Peri, Data::None), |
|
|
|
|
'.' => new_tok(delim_end(rd)?, Peri, Data::None), |
|
|
|
|
|
|
|
|
|
// quote abbreviations
|
|
|
|
|
'\'' => new_tok(rd, Quot, Data::None), |
|
|
|
|
'`' => new_tok(rd, QQuo, Data::None), |
|
|
|
|
',' => unquote(rd, UnQS, UnQu), |
|
|
|
|
// quote abbreviations
|
|
|
|
|
'\'' => new_tok(rd, Quot, Data::None), |
|
|
|
|
'`' => new_tok(rd, QQuo, Data::None), |
|
|
|
|
',' => unquote(rd, UnQS, UnQu), |
|
|
|
|
|
|
|
|
|
// tokens preceded by #
|
|
|
|
|
'#' => match rd.next().ok_or(Err::Eof)? { |
|
|
|
|
// block comments
|
|
|
|
|
'|' => { |
|
|
|
|
block_comment(rd)?; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
// tokens preceded by #
|
|
|
|
|
'#' => match rd.next().ok_or(Err::Eof)? { |
|
|
|
|
// block comments
|
|
|
|
|
'|' => { |
|
|
|
|
block_comment(rd)?; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// integers
|
|
|
|
|
'b' | 'B' => integer_rad(rd, 2)?, |
|
|
|
|
'o' | 'O' => integer_rad(rd, 8)?, |
|
|
|
|
'd' | 'D' => integer_rad(rd, 10)?, |
|
|
|
|
'x' | 'X' => integer_rad(rd, 16)?, |
|
|
|
|
// integers
|
|
|
|
|
'b' | 'B' => integer_rad(rd, 2)?, |
|
|
|
|
'o' | 'O' => integer_rad(rd, 8)?, |
|
|
|
|
'd' | 'D' => integer_rad(rd, 10)?, |
|
|
|
|
'x' | 'X' => integer_rad(rd, 16)?, |
|
|
|
|
|
|
|
|
|
// booleans
|
|
|
|
|
't' | 'T' => new_tok(delim_end(rd)?, Bool, Data::Bool(true)), |
|
|
|
|
'f' | 'F' => new_tok(delim_end(rd)?, Bool, Data::Bool(false)), |
|
|
|
|
// booleans
|
|
|
|
|
't' | 'T' => new_tok(delim_end(rd)?, Bool, Data::Bool(true)), |
|
|
|
|
'f' | 'F' => new_tok(delim_end(rd)?, Bool, Data::Bool(false)), |
|
|
|
|
|
|
|
|
|
// syntax abbreviations
|
|
|
|
|
'\'' => new_tok(rd, Synt, Data::None), |
|
|
|
|
'`' => new_tok(rd, QSyn, Data::None), |
|
|
|
|
',' => unquote(rd, UnSS, UnSy), |
|
|
|
|
// syntax abbreviations
|
|
|
|
|
'\'' => new_tok(rd, Synt, Data::None), |
|
|
|
|
'`' => new_tok(rd, QSyn, Data::None), |
|
|
|
|
',' => unquote(rd, UnSS, UnSy), |
|
|
|
|
|
|
|
|
|
// character literals
|
|
|
|
|
'\\' => char_lit(rd)?, |
|
|
|
|
// character literals
|
|
|
|
|
'\\' => char_lit(rd)?, |
|
|
|
|
|
|
|
|
|
c => return Err(Err::Char(rd.pos(), c)), |
|
|
|
|
}, |
|
|
|
|
c => return Err(Err::Char(rd.pos(), c)), |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
// strings
|
|
|
|
|
'"' => strn_lit(rd)?, |
|
|
|
|
// strings
|
|
|
|
|
'"' => strn_lit(rd)?, |
|
|
|
|
|
|
|
|
|
// integers without prefixes
|
|
|
|
|
c if c.is_digit(10) => integer_rad(rd, 10)?, |
|
|
|
|
// integers without prefixes
|
|
|
|
|
c if c.is_digit(10) => integer_rad(rd, 10)?, |
|
|
|
|
|
|
|
|
|
// symbols
|
|
|
|
|
c if is_sym_init(c) => symbol(rd, c)?, |
|
|
|
|
// symbols
|
|
|
|
|
c if is_sym_init(c) => symbol(rd, c)?, |
|
|
|
|
|
|
|
|
|
// skip whitespace
|
|
|
|
|
c if c.is_whitespace() => continue, |
|
|
|
|
// skip whitespace
|
|
|
|
|
c if c.is_whitespace() => continue, |
|
|
|
|
|
|
|
|
|
c => return Err(Err::Char(rd.pos(), c)), |
|
|
|
|
}; |
|
|
|
|
c => return Err(Err::Char(rd.pos(), c)), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
tokens.push(tk); |
|
|
|
|
} |
|
|
|
|
tokens.push(tk); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Ok(tokens) |
|
|
|
|
Ok(tokens) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// EOF
|