Skip to content

Commit

Permalink
🚧 (parser): Work on parser
Browse files Browse the repository at this point in the history
semver: chore
  • Loading branch information
Somfic committed Jun 29, 2024
1 parent e9eaa7b commit 0857862
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 49 deletions.
73 changes: 33 additions & 40 deletions src/files.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
use std::collections::HashMap;

#[derive(Default)]
use codespan_reporting::files::SimpleFiles;

pub struct Files<'a> {
pub files: HashMap<&'a str, &'a str>,
files: SimpleFiles<&'a str, &'a str>,
file_handles: HashMap<&'a str, usize>,
}

impl<'a> Default for Files<'a> {
fn default() -> Self {
Self {
files: SimpleFiles::new(),
file_handles: HashMap::new(),
}
}
}

impl<'a> Files<'a> {
pub fn insert(&mut self, file_id: &'a str, source: &'a str) {
self.files.insert(file_id, source);
let handle = self.files.add(source, source);
self.file_handles.insert(file_id, handle);
}

pub fn file_ids(&self) -> Vec<&'a str> {
self.files.keys().copied().collect()
pub fn get(&self, file_id: impl Into<&'a str>) -> Option<&'a str> {
let handle = self.file_handles.get(file_id.into())?;
Some(self.files.get(*handle).unwrap().source())
}

pub fn get(&self, file_id: impl Into<&'a str>) -> Option<&'a str> {
self.files.get(file_id.into()).copied()
pub fn file_ids<'b>(&'b self) -> impl Iterator<Item = &'a str> + 'b {
self.file_handles.keys().copied()
}
}

Expand All @@ -25,60 +38,40 @@ impl<'a> codespan_reporting::files::Files<'a> for Files<'a> {
type Source = &'a str;

fn name(&'a self, id: Self::FileId) -> Result<Self::Name, codespan_reporting::files::Error> {
self.files
.keys()
.find(|key| **key == id)
.copied()
.ok_or(codespan_reporting::files::Error::FileMissing)
Ok(id)
}

fn source(
&'a self,
id: Self::FileId,
) -> Result<Self::Source, codespan_reporting::files::Error> {
self.files
.get(id)
self.get(id)
.ok_or(codespan_reporting::files::Error::FileMissing)
.copied()
}

fn line_index(
&'a self,
id: Self::FileId,
byte_index: usize,
) -> Result<usize, codespan_reporting::files::Error> {
self.get(id)
.ok_or(codespan_reporting::files::Error::FileMissing)
.map(|source| {
source
.char_indices()
.take_while(|(index, _)| *index < byte_index)
.filter(|(_, character)| *character == '\n')
.count()
})
let handle = self
.file_handles
.get(id)
.ok_or(codespan_reporting::files::Error::FileMissing)?;

self.files.line_index(*handle, byte_index)
}

fn line_range(
&'a self,
id: Self::FileId,
line_index: usize,
) -> Result<std::ops::Range<usize>, codespan_reporting::files::Error> {
self.get(id)
.ok_or(codespan_reporting::files::Error::FileMissing)
.map(|source| {
let start = source
.lines()
.take(line_index)
.map(|line| line.len() + 1)
.sum::<usize>();

let end = source
.lines()
.take(line_index + 1)
.map(|line| line.len() + 1)
.sum::<usize>();
let handle = self
.file_handles
.get(id)
.ok_or(codespan_reporting::files::Error::FileMissing)?;

start..end
})
self.files.line_range(*handle, line_index)
}
}
12 changes: 7 additions & 5 deletions src/parser/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ macro_rules! expect_any_token {
Err(vec![crate::diagnostic::Error::primary(
token.range.file_id,
$cursor,
1,
0,
format!("Expected {}", expected_token_types.join(" or ")),
)])
}
Expand Down Expand Up @@ -102,7 +102,9 @@ macro_rules! expect_tokens {
invalid_indecies.push((i, $token_type));
}
}
_ => {}
_ => {

}
};

i += 1;
Expand All @@ -119,11 +121,11 @@ macro_rules! expect_tokens {

errors.push(crate::diagnostic::Error::primary(
$parser.tokens.get(0).unwrap().range.file_id,
$cursor + invalid_index,
1,
$cursor,
0,
format!("Expected {}", expected_token_type)
).with_note(
format!("Expected {}, got {}", expected_token_type, actual_token.token_type)
format!("Expected {}, found {} ({})", expected_token_type, actual_token.token_type, actual_token.value)
));
}

Expand Down
17 changes: 14 additions & 3 deletions src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ pub fn parse_enum<'a>(
let identifier = expect_token_value!(tokens[1], TokenValue::Identifier);

let mut new_cursor = cursor;
let mut members: HashSet<String> = HashSet::new();
let mut members: HashMap<String, Token> = HashMap::new();
let mut errors = Vec::new();

while let Some(token) = parser.tokens.get(new_cursor) {
let (member_name, cursor) = match token.token_type {
Expand All @@ -153,10 +154,20 @@ pub fn parse_enum<'a>(

new_cursor = cursor;
// TODO: Handle warning for overwritten members
members.insert(member_name);
if let Some(overwritten_key) = members.insert(member_name, token.clone()) {
errors.push(
Error::primary(
overwritten_key.range.file_id,
overwritten_key.range.position,
1,
"This member was overwritten",
)
.with_note("This member was overwritten since it was already declared"),
);
}
}

let (_, cursor) = expect_tokens!(parser, new_cursor, TokenType::Semicolon)?;

Ok((Statement::Enum(identifier, members), cursor))
Ok(((Statement::Enum(identifier, members), cursor)), errors))
}
14 changes: 14 additions & 0 deletions src/scanner/lexeme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ pub enum TokenValue {
Identifier(String),
}

impl Display for TokenValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TokenValue::None => write!(f, "none"),
TokenValue::Boolean(value) => write!(f, "{}", value),
TokenValue::Integer(value) => write!(f, "{}", value),
TokenValue::Decimal(value) => write!(f, "{}", value),
TokenValue::String(value) => write!(f, "{}", value),
TokenValue::Character(value) => write!(f, "{}", value),
TokenValue::Identifier(value) => write!(f, "{}", value),
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum TokenType {
/// A token that should be ignored. This is used for whitespace, comments, etc.
Expand Down
2 changes: 1 addition & 1 deletion test.som
Original file line number Diff line number Diff line change
@@ -1 +1 @@
enum color: green blue red yellow 12
enum color: green blue red yellow 12 green greeen green

0 comments on commit 0857862

Please sign in to comment.