#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Span {
pub offset: usize,
pub line: u32,
pub column: usize,
pub len: usize,
}
impl Span {
pub fn dummy() -> Self {
Self {
offset: 0,
line: 1,
column: 1,
len: 0,
}
}
pub fn to_lsp_range(&self) -> (u32, u32, u32, u32) {
let start_line = self.line.saturating_sub(1);
let start_char = self.column.saturating_sub(1);
let end_char = start_char.saturating_add(self.len);
(start_line, start_char as u32, start_line, end_char as u32)
}
}
#[cfg(test)]
mod tests {
use super::Span;
#[test]
fn span_dummy() {
let s = Span::dummy();
assert_eq!(s.offset, 0);
assert_eq!(s.line, 1);
assert_eq!(s.column, 1);
assert_eq!(s.len, 0);
}
}
#[derive(Debug, Clone)]
pub struct Node<T> {
pub span: Span,
pub value: T,
}
impl<T: PartialEq> PartialEq for Node<T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: Eq> Eq for Node<T> {}
impl<T> Node<T> {
pub fn new(span: Span, value: T) -> Self {
Self { span, value }
}
}
impl<T> std::ops::Deref for Node<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}
pub trait AstNode {
fn span(&self) -> Span;
}
impl<T> AstNode for Node<T> {
fn span(&self) -> Span {
self.span.clone()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Expression {
LiteralInteger(i64),
LiteralReal(String),
LiteralString(String),
LiteralBoolean(bool),
FeatureRef(String),
MemberAccess(Box<Node<Expression>>, String),
Index {
base: Box<Node<Expression>>,
index: Box<Node<Expression>>,
},
Bracket(Box<Node<Expression>>),
LiteralWithUnit {
value: Box<Node<Expression>>,
unit: Box<Node<Expression>>,
},
BinaryOp {
op: String,
left: Box<Node<Expression>>,
right: Box<Node<Expression>>,
},
UnaryOp {
op: String,
operand: Box<Node<Expression>>,
},
Invocation {
callee: Box<Node<Expression>>,
args: Vec<Node<Expression>>,
},
Tuple(Vec<Node<Expression>>),
Null,
}