wip: ast/cst
Some checks are pending
/ build (push) Waiting to run

This commit is contained in:
🪞👃🪞 2025-05-25 22:48:29 +03:00
parent 31e84bf5b3
commit f1b24d436a
20 changed files with 1081 additions and 1103 deletions

View file

@ -1,110 +0,0 @@
use crate::*;
#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct Token<'source> {
pub source: &'source str,
pub start: usize,
pub length: usize,
pub value: Value<'source>,
}
#[derive(Debug, Copy, Clone, Default, PartialEq)] pub enum Value<'source> {
#[default] Nil,
Err(DslError),
Num(usize),
Sym(&'source str),
Key(&'source str),
Str(&'source str),
Exp(usize, TokenIter<'source>),
}
impl<'source> std::fmt::Display for Value<'source> {
fn fmt (&self, out: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(out, "{}", match self {
Nil => String::new(),
Err(e) => format!("[error: {e}]"),
Num(n) => format!("{n}"),
Sym(s) => format!("{s}"),
Key(s) => format!("{s}"),
Str(s) => format!("{s}"),
Exp(_, e) => format!("{e:?}"),
})
}
}
impl<'source> Token<'source> {
pub const fn new (
source: &'source str, start: usize, length: usize, value: Value<'source>
) -> Self {
Self { source, start, length, value }
}
pub const fn end (&self) -> usize {
self.start.saturating_add(self.length)
}
pub const fn slice (&'source self) -> &'source str {
self.slice_source(self.source)
}
pub const fn slice_source <'range> (&'source self, source: &'range str) -> &'range str {
str_range(source, self.start, self.end())
}
pub const fn slice_source_exp <'range> (&'source self, source: &'range str) -> &'range str {
str_range(source, self.start.saturating_add(1), self.end())
}
pub const fn with_value (self, value: Value<'source>) -> Self {
Self { value, ..self }
}
pub const fn value (&self) -> Value {
self.value
}
pub const fn error (self, error: DslError) -> Self {
Self { value: Value::Err(error), ..self }
}
pub const fn grow (self) -> Self {
Self { length: self.length.saturating_add(1), ..self }
}
pub const fn grow_num (self, m: usize, c: char) -> Self {
match to_digit(c) {
Ok(n) => Self { value: Num(10*m+n), ..self.grow() },
Result::Err(e) => Self { value: Err(e), ..self.grow() },
}
}
pub const fn grow_key (self) -> Self {
let token = self.grow();
token.with_value(Key(token.slice_source(self.source)))
}
pub const fn grow_sym (self) -> Self {
let token = self.grow();
token.with_value(Sym(token.slice_source(self.source)))
}
pub const fn grow_str (self) -> Self {
let token = self.grow();
token.with_value(Str(token.slice_source(self.source)))
}
pub const fn grow_exp (self) -> Self {
let token = self.grow();
if let Exp(depth, _) = token.value {
token.with_value(Exp(depth, TokenIter::new(token.slice_source_exp(self.source))))
} else {
unreachable!()
}
}
pub const fn grow_in (self) -> Self {
let token = self.grow_exp();
if let Value::Exp(depth, source) = token.value {
token.with_value(Value::Exp(depth.saturating_add(1), source))
} else {
unreachable!()
}
}
pub const fn grow_out (self) -> Self {
let token = self.grow_exp();
if let Value::Exp(depth, source) = token.value {
if depth > 0 {
token.with_value(Value::Exp(depth - 1, source))
} else {
return self.error(Unexpected(')'))
}
} else {
unreachable!()
}
}
}