forked from AbleOS/ableos_userland
114 lines
2.2 KiB
Rust
114 lines
2.2 KiB
Rust
use std::{ops::{Range, Add}, fmt::Display};
|
|
|
|
use logos::Logos;
|
|
|
|
#[derive(Logos, Debug, PartialEq)]
|
|
#[logos(skip r"[ \t\n\f]+")]
|
|
pub enum Token {
|
|
#[token("{")]
|
|
LeftBrace,
|
|
|
|
#[token("}")]
|
|
RightBrace,
|
|
|
|
#[token("(")]
|
|
LeftParen,
|
|
|
|
#[token(")")]
|
|
RightParen,
|
|
|
|
#[token(";")]
|
|
Semicolon,
|
|
|
|
#[token(":")]
|
|
Colon,
|
|
|
|
#[token("<")]
|
|
LeftArrow,
|
|
|
|
#[token(">")]
|
|
RightArrow,
|
|
|
|
#[token(",")]
|
|
Comma,
|
|
|
|
#[token("=")]
|
|
Equals,
|
|
|
|
#[token(".")]
|
|
Dot,
|
|
|
|
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
|
|
Ident(Ident),
|
|
|
|
#[regex(r"//.*", |lex| lex.slice().parse().ok())]
|
|
Comment(String),
|
|
}
|
|
|
|
#[derive(Logos, Debug, PartialEq, Eq)]
|
|
pub enum Ident {
|
|
#[token("Interface")]
|
|
Interface,
|
|
#[token("Function")]
|
|
Function,
|
|
#[token("Constant")]
|
|
Constant,
|
|
#[token("Structure")]
|
|
Structure,
|
|
#[token("Alias")]
|
|
Alias,
|
|
#[token("Use")]
|
|
Use,
|
|
#[regex(r"[A-z]+", |lex| lex.slice().parse().ok())]
|
|
Other(String)
|
|
}
|
|
|
|
#[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::{min, max};
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
#[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)
|
|
}
|
|
}
|