Initial commit with lexer

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-04-27 12:42:17 -04:00
commit 58421a0469
10 changed files with 759 additions and 0 deletions

150
src/syn/span.rs Normal file
View File

@@ -0,0 +1,150 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Pos {
pub source: usize,
pub line: usize,
pub col: usize,
pub byte: usize,
pub len: usize,
}
impl Default for Pos {
fn default() -> Self {
Pos {
source: 0,
line: 0,
col: 0,
byte: 0,
len: 1,
}
}
}
impl Pos {
pub fn from_char(c: char, source: usize, line: usize, col: usize, byte: usize) -> Self {
Pos {
source, line, col, byte, len: c.len_utf8(),
}
}
pub fn next_char(&self, c: char) -> Self {
Pos {
source: self.source + 1,
line: self.line,
col: self.col + 1,
byte: self.byte + self.len,
len: c.len_utf8(),
}
}
pub fn min(self, other: Self) -> Self {
if self.byte < other.byte {
self
} else {
other
}
}
pub fn max(self, other: Self) -> Self {
if self.byte > other.byte {
self
} else {
other
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Span {
pub start: Pos,
pub end: Pos,
}
impl Span {
pub fn union(self, other: Self) -> Self {
let start = self.start.min(other.start);
let end = self.end.max(other.end);
Span { start, end }
}
}
pub trait Spanned {
fn span(&self) -> Span;
fn text_at<'t>(&self, text: &'t str) -> &'t str {
let Span { start, end } = self.span();
&text[start.byte .. end.byte]
}
}
impl Spanned for Span {
fn span(&self) -> Span {
*self
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_pos_min() {
let small = Pos::default();
let large = Pos {
source: 1,
byte: 1,
..Default::default()
};
assert_eq!(small.min(large), small);
assert_eq!(large.min(small), small);
}
#[test]
fn test_pos_max() {
let small = Pos::default();
let large = Pos {
source: 1,
byte: 1,
..Default::default()
};
assert_eq!(small.max(large), large);
assert_eq!(large.max(small), large);
}
#[test]
fn test_span_union() {
let first = Span {
start: Pos::default(),
end: Pos {
source: 15,
col: 15,
byte: 15,
..Default::default()
}
};
let second = Span {
start: Pos {
source: 25,
col: 25,
byte: 25,
..Default::default()
},
end: Pos {
source: 27,
col: 27,
byte: 27,
..Default::default()
}
};
let expected = Span {
start: first.start,
end: second.end,
};
assert_eq!(first.union(second), expected);
assert_eq!(second.union(first), expected);
}
}