use crate::common::interner::Interner;
use crate::common::symbol::Symbol;
use crate::lexer::lexer::Lexer;
use crate::lexer::spanned_token::Span;
use crate::lexer::token::{Token, TokenKind};
use crate::parser::parser_error::ParserError;
pub struct Parser<'a> {
pub source: &'a str,
pub lexer: Lexer<'a>,
pub current: Token,
pub peek: Token,
pub interner: Interner,
}
impl<'a> Parser<'a> {
pub fn new(source: &'a str) -> Self {
let mut lexer = Lexer::new(source);
let current = lexer.next_token();
let peek = lexer.next_token();
Self {
source,
lexer,
current,
peek,
interner: Interner::new(),
}
}
pub fn advance(&mut self) {
self.current = self.peek.clone();
self.peek = self.lexer.next_token();
}
pub fn current_token(&self) -> &TokenKind {
&self.current.kind
}
pub fn current_span(&self) -> &Span {
&self.current.span
}
pub fn peek_token(&self) -> &TokenKind {
&self.peek.kind
}
pub fn consume(&mut self, expected: &TokenKind) -> bool {
if self.current_token() == expected {
self.advance();
true
} else {
false
}
}
pub fn is_at_end(&self) -> bool {
*self.current_token() == TokenKind::Eof
}
pub fn peek_is(&self, token: &TokenKind) -> bool {
self.peek_token() == token
}
pub fn expect(&mut self, expected: TokenKind) -> Result<(), ParserError> {
if self.current.kind == expected {
self.advance();
Ok(())
} else {
Err(ParserError::new(
format!("Expected {:?}, found {:?}", expected, self.current.kind),
self.current.span.clone(),
))
}
}
pub fn expect_identifier(&mut self) -> Result<Symbol, ParserError> {
match self.current.kind {
TokenKind::Ident => {
let s = &self.source[self.current.span.start..self.current.span.end];
let sym = self.interner.intern(s);
self.advance();
Ok(sym)
}
TokenKind::QuotedIdent => {
let s = &self.source[self.current.span.start + 1..self.current.span.end - 1];
let sym = self.interner.intern(s);
self.advance();
Ok(sym)
}
_ => Err(ParserError::new(
format!("Expected identifier, found {:?}", self.current.kind),
self.current.span.clone(),
)),
}
}
pub fn expect_string_literal(&mut self) -> Result<Symbol, ParserError> {
match self.current_token() {
TokenKind::StringLit => {
let s = &self.source[self.current.span.start + 1..self.current.span.end - 1];
let sym = self.interner.intern(s);
self.advance();
Ok(sym)
}
_ => Err(ParserError::new(
format!("Expected string literal, found {:?}", self.current_token()),
self.current.span.clone(),
)),
}
}
pub fn expect_int_literal(&mut self) -> Result<u64, ParserError> {
match self.current_token().clone() {
TokenKind::IntLit(n) if n >= 0 => {
self.advance();
Ok(n as u64)
}
_ => Err(ParserError::new(
format!(
"Expected positive integer, found {:?}",
self.current_token()
),
self.current.span.clone(),
)),
}
}
pub fn expect_int(&mut self) -> Result<i64, ParserError> {
match self.current_token().clone() {
TokenKind::IntLit(n) => {
self.advance();
Ok(n)
}
TokenKind::Minus => {
self.advance();
match self.current_token().clone() {
TokenKind::IntLit(n) => {
self.advance();
Ok(-n)
}
_ => Err(ParserError::new(
"Expected integer after -",
self.current.span.clone(),
)),
}
}
_ => Err(ParserError::new(
format!("Expected integer, got {:?}", self.current_token()),
self.current.span.clone(),
)),
}
}
pub fn expect_float(&mut self) -> Result<f64, ParserError> {
match self.current_token().clone() {
TokenKind::FloatLit(f) => {
self.advance();
Ok(f)
}
TokenKind::IntLit(n) => {
self.advance();
Ok(n as f64)
}
TokenKind::Minus => {
self.advance();
match self.current_token().clone() {
TokenKind::FloatLit(f) => {
self.advance();
Ok(-f)
}
TokenKind::IntLit(n) => {
self.advance();
Ok(-(n as f64))
}
_ => Err(ParserError::new(
"Expected number after -",
self.current.span.clone(),
)),
}
}
_ => Err(ParserError::new(
format!("Expected number, got {:?}", self.current_token()),
self.current.span.clone(),
)),
}
}
pub fn parse_qualified_name(&mut self) -> Result<Vec<Symbol>, ParserError> {
let mut parts = vec![self.expect_identifier()?];
while self.consume(&TokenKind::Dot) {
parts.push(self.expect_identifier()?);
}
Ok(parts)
}
pub fn parse_if_not_exist(&mut self) -> Result<bool, ParserError> {
if self.consume(&TokenKind::If) {
self.expect(TokenKind::Not)?;
self.expect(TokenKind::Exists)?;
Ok(true)
} else {
Ok(false)
}
}
}