forked from AbleOS/ableos_userland
233 lines
4.9 KiB
Rust
233 lines
4.9 KiB
Rust
use std::{
|
|
fmt::Display,
|
|
ops::{Add, AddAssign, Range},
|
|
};
|
|
|
|
use logos::Logos;
|
|
|
|
#[derive(Logos, Debug, PartialEq, derive_more::Display, Clone)]
|
|
#[logos(skip r"[ \t\n\f]+")]
|
|
pub enum Token {
|
|
#[token("{")]
|
|
#[display(fmt = "{{")]
|
|
LeftCurly,
|
|
|
|
#[token("}")]
|
|
#[display(fmt = "}}")]
|
|
RightCurly,
|
|
|
|
#[token("(")]
|
|
#[display(fmt = "(")]
|
|
LeftParen,
|
|
|
|
#[token(")")]
|
|
#[display(fmt = ")")]
|
|
RightParen,
|
|
|
|
#[token(";")]
|
|
#[display(fmt = ";")]
|
|
Semicolon,
|
|
|
|
#[token(":")]
|
|
#[display(fmt = ":")]
|
|
Colon,
|
|
|
|
#[token("<")]
|
|
#[display(fmt = "<")]
|
|
LeftArrow,
|
|
|
|
#[token(">")]
|
|
#[display(fmt = ">")]
|
|
RightArrow,
|
|
|
|
#[token(",")]
|
|
#[display(fmt = ",")]
|
|
Comma,
|
|
|
|
#[token("=")]
|
|
#[display(fmt = "=")]
|
|
Equals,
|
|
|
|
#[token(".")]
|
|
#[display(fmt = ".")]
|
|
Dot,
|
|
|
|
// why
|
|
#[regex("\"(?s:[^\"\\\\]|\\\\.)*\"", |lex| lex.slice().strip_prefix('"')?.strip_suffix('"').map(ToOwned::to_owned))]
|
|
#[display(fmt = "\"{_0}\"")]
|
|
StringLiteral(String),
|
|
|
|
#[regex(r"'.'", |lex| lex.slice().strip_prefix('\'')?.strip_suffix('\'')?.parse().ok())]
|
|
#[display(fmt = "{_0}")]
|
|
CharLiteral(char),
|
|
|
|
#[regex(r#"(-)?\d+"#, |lex| lex.slice().parse().ok())]
|
|
#[display(fmt = "{_0}")]
|
|
NumberLiteral(i64),
|
|
|
|
#[regex(
|
|
"(ptr|u8|i8|u16|i16|u32|i32|u64|i64|f32|f64)",
|
|
|lex| NumberSuffix::lexer(lex.slice()).next().and_then(Result::ok)
|
|
)]
|
|
#[display(fmt = "{_0}")]
|
|
NumberSuffix(NumberSuffix),
|
|
|
|
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
|
|
#[display(fmt = "{_0}")]
|
|
Ident(Ident),
|
|
|
|
#[regex(r"//.*", |lex| lex.slice().parse().ok())]
|
|
#[display(fmt = "//{_0}")]
|
|
Comment(String),
|
|
}
|
|
|
|
#[derive(Logos, Debug, Clone, PartialEq, Eq, derive_more::Display)]
|
|
pub enum Ident {
|
|
#[token("Module")]
|
|
#[display(fmt = "Module")]
|
|
Module,
|
|
#[token("Interface")]
|
|
#[display(fmt = "Interface")]
|
|
Interface,
|
|
#[token("Function")]
|
|
#[display(fmt = "Function")]
|
|
Function,
|
|
#[token("Constant")]
|
|
#[display(fmt = "Constant")]
|
|
Constant,
|
|
#[token("Structure")]
|
|
#[display(fmt = "Structure")]
|
|
Structure,
|
|
#[token("Alias")]
|
|
#[display(fmt = "Alias")]
|
|
Alias,
|
|
#[token("Enumeration")]
|
|
#[display(fmt = "Enumeration")]
|
|
Enumeration,
|
|
#[token("Use")]
|
|
#[display(fmt = "Use")]
|
|
Use,
|
|
#[token("Make")]
|
|
#[display(fmt = "Make")]
|
|
Make,
|
|
#[token("Takes")]
|
|
#[display(fmt = "Takes")]
|
|
Takes,
|
|
#[token("Returns")]
|
|
#[display(fmt = "Returns")]
|
|
Returns,
|
|
#[token("_")]
|
|
#[display(fmt = "_")]
|
|
Underscore,
|
|
#[regex(r"[a-zA-Z_][a-zA-Z\d_]*", |lex| lex.slice().parse().ok())]
|
|
#[display(fmt = "{_0}")]
|
|
Other(String),
|
|
}
|
|
|
|
#[derive(Logos, Debug, Clone, Copy, PartialEq, Eq, derive_more::Display)]
|
|
pub enum NumberSuffix {
|
|
#[token("ptr")]
|
|
#[display(fmt = "ptr")]
|
|
Ptr,
|
|
#[token("u8")]
|
|
#[display(fmt = "u8")]
|
|
U8,
|
|
#[token("i8")]
|
|
#[display(fmt = "i8")]
|
|
I8,
|
|
#[token("u16")]
|
|
#[display(fmt = "u16")]
|
|
U16,
|
|
#[token("i16")]
|
|
#[display(fmt = "i16")]
|
|
I16,
|
|
#[token("u32")]
|
|
#[display(fmt = "u32")]
|
|
U32,
|
|
#[token("i32")]
|
|
#[display(fmt = "i32")]
|
|
I32,
|
|
#[token("u64")]
|
|
#[display(fmt = "u64")]
|
|
U64,
|
|
#[token("i64")]
|
|
#[display(fmt = "i64")]
|
|
I64,
|
|
#[token("f32")]
|
|
#[display(fmt = "f32")]
|
|
F32,
|
|
#[token("f64")]
|
|
#[display(fmt = "f64")]
|
|
F64,
|
|
}
|
|
|
|
impl NumberSuffix {
|
|
pub const ALL_SUFFIXES: [&str; 11] = [
|
|
"ptr",
|
|
"u8",
|
|
"i8",
|
|
"u16",
|
|
"i16",
|
|
"u32",
|
|
"i32",
|
|
"u64",
|
|
"i64",
|
|
"f32",
|
|
"f64"
|
|
];
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Span(pub Range<usize>);
|
|
impl Span {
|
|
pub const ZERO: Self = Self(0..0);
|
|
|
|
pub fn lower(&self) -> usize {
|
|
self.0.start
|
|
}
|
|
pub fn upper(&self) -> usize {
|
|
self.0.end
|
|
}
|
|
|
|
pub fn concat(self, other: Span) -> Self {
|
|
use std::cmp::{max, min};
|
|
|
|
Self(min(self.lower(), other.lower())..max(self.upper(), other.upper()))
|
|
}
|
|
}
|
|
impl Display for Span {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}..{}", self.lower(), self.upper())
|
|
}
|
|
}
|
|
impl Add for Span {
|
|
type Output = Self;
|
|
|
|
fn add(self, rhs: Self) -> Self::Output {
|
|
self.concat(rhs)
|
|
}
|
|
}
|
|
impl AddAssign for Span {
|
|
fn add_assign(&mut self, rhs: Self) {
|
|
*self = self.clone() + rhs;
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Spanned<T>(pub T, pub Span);
|
|
|
|
impl<T> Spanned<T> {
|
|
pub fn new<const N: usize>(thing: T, spans: [Span; N]) -> Self {
|
|
Self(thing, spans.into_iter().fold(Span::ZERO, Span::concat))
|
|
}
|
|
pub fn map<R>(self, f: impl Fn(T) -> R) -> Spanned<R> {
|
|
Spanned(f(self.0), self.1)
|
|
}
|
|
}
|
|
|
|
impl<T: Display> Display for Spanned<T> {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{} @ {}", self.0, self.1)
|
|
}
|
|
}
|