use crate::parser::ast::stmt::*;
use crate::parser::core::error::{ParseError, ParseErrorKind};
use crate::parser::parsing::expr_parser::parse_expression_with_context;
use crate::parser::parsing::parse_context::ParseContext;
use crate::parser::TokenKind;
pub struct SessionParser;
impl Default for SessionParser {
fn default() -> Self {
Self
}
}
impl SessionParser {
pub fn new() -> Self {
Self
}
pub fn parse_let_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
let start_span = ctx.current_span();
ctx.expect_token(TokenKind::Let)?;
let _ = ctx.match_token(TokenKind::Dollar);
let name = match ctx.expect_identifier() {
Ok(name) => name,
Err(_) => {
let pos = ctx.current_position();
let display_name = ctx.current_token().lexeme.clone();
return Err(ParseError::new(
ParseErrorKind::SyntaxError,
format!("Invalid session variable name '{}'", display_name),
pos,
));
}
};
let valid = !name.is_empty()
&& name
.chars()
.next()
.is_some_and(|c| c.is_ascii_alphabetic() || c == '_')
&& name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_');
if !valid {
let pos = ctx.current_position();
return Err(ParseError::new(
ParseErrorKind::SyntaxError,
format!("Invalid session variable name '{}'", name),
pos,
));
}
if !ctx.check_token(TokenKind::Assign) {
let pos = ctx.current_position();
return Err(ParseError::new(
ParseErrorKind::SyntaxError,
"LET requires an assignment: LET $name = expr".to_string(),
pos,
));
}
ctx.expect_token(TokenKind::Assign)?;
let expression = parse_expression_with_context(ctx, ctx.expression_context_clone())?;
let span = ctx.span_since(start_span.start);
Ok(Stmt::AssignVariable(AssignVariableStmt {
span,
name,
expression,
}))
}
pub fn parse_kill_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
let start_span = ctx.current_span();
ctx.expect_token(TokenKind::Kill)?;
ctx.expect_token(TokenKind::Query)?;
let session_id = ctx.expect_integer_literal()?;
ctx.expect_token(TokenKind::Comma)?;
let plan_id = ctx.expect_integer_literal()?;
let span = ctx.span_since(start_span.start);
Ok(Stmt::KillQuery(KillQueryStmt {
span,
session_id,
plan_id,
}))
}
}