Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn is_at_end(&self) -> bool {
- self.position >= self.input.len()
- }
- }
- // ============================================================================
- // src/compiler/parser.rs - Parser Implementation
- // ============================================================================
- use super::ast::*;
- use super::lexer::{Token, TokenType};
- use crate::diagnostics::{DiagnosticEngine, Error, Result, Span};
- pub struct Parser<'a> {
- tokens: Vec<Token>,
- current: usize,
- diagnostics: &'a mut DiagnosticEngine,
- }
- impl<'a> Parser<'a> {
- pub fn new(tokens: Vec<Token>, diagnostics: &'a mut DiagnosticEngine) -> Self {
- Self {
- tokens,
- current: 0,
- diagnostics,
- }
- }
- pub fn parse(&mut self) -> Result<Program> {
- let mut imports = Vec::new();
- let mut items = Vec::new();
- // Parse imports first
- while self.match_token(&TokenType::Import) {
- imports.push(self.parse_import()?);
- }
- // Parse items
- while !self.is_at_end() {
- if self.match_token(&TokenType::Newline) {
- continue; // Skip newlines
- }
- items.push(self.parse_item()?);
- }
- Ok(Program { items, imports })
- }
- fn parse_import(&mut self) -> Result<Import> {
- let start_span = self.previous().span.clone();
- if let TokenType::Identifier(module_path) = &self.advance().token_type {
- Ok(Import {
- module_path: module_path.clone(),
- span: start_span,
- })
- } else {
- Err(Error::ParseError("Expected module name after 'import'".to_string()))
- }
- }
- fn parse_item(&mut self) -> Result<Item> {
- match &self.peek().token_type {
- TokenType::Fn => Ok(Item::Function(self.parse_function()?)),
- TokenType::Struct => Ok(Item::Struct(self.parse_struct()?)),
- TokenType::Let => Ok(Item::Constant(self.parse_constant()?)),
- TokenType::Var => Ok(Item::Variable(self.parse_variable()?)),
- _ => Err(Error::ParseError("Expected function, struct, let, or var".to_string())),
- }
- }
- fn parse_function(&mut self) -> Result<Function> {
- let start_span = self.advance().span.clone(); // consume 'fn'
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected function name".to_string()));
- };
- self.consume(&TokenType::LeftParen, "Expected '(' after function name")?;
- let mut parameters = Vec::new();
- if !self.check(&TokenType::RightParen) {
- loop {
- parameters.push(self.parse_parameter()?);
- if !self.match_token(&TokenType::Comma) {
- break;
- }
- }
- }
- self.consume(&TokenType::RightParen, "Expected ')' after parameters")?;
- self.consume(&TokenType::Arrow, "Expected '->' before return type")?;
- let return_type = self.parse_type()?;
- let body = self.parse_block()?;
- Ok(Function {
- name,
- parameters,
- return_type,
- body,
- span: start_span,
- })
- }
- fn parse_parameter(&mut self) -> Result<Parameter> {
- let start_span = self.peek().span.clone();
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected parameter name".to_string()));
- };
- self.consume(&TokenType::Colon, "Expected ':' after parameter name")?;
- let param_type = self.parse_type()?;
- let default_value = if self.match_token(&TokenType::Assign) {
- Some(self.parse_expression()?)
- } else {
- None
- };
- Ok(Parameter {
- name,
- param_type,
- default_value,
- span: start_span,
- })
- }
- fn parse_struct(&mut self) -> Result<Struct> {
- let start_span = self.advance().span.clone(); // consume 'struct'
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected struct name".to_string()));
- };
- self.consume(&TokenType::LeftBrace, "Expected '{' after struct name")?;
- let mut fields = Vec::new();
- while !self.check(&TokenType::RightBrace) && !self.is_at_end() {
- fields.push(self.parse_field()?);
- if self.match_token(&TokenType::Comma) {
- continue;
- }
- }
- self.consume(&TokenType::RightBrace, "Expected '}' after struct fields")?;
- Ok(Struct {
- name,
- fields,
- span: start_span,
- })
- }
- fn parse_field(&mut self) -> Result<Field> {
- let start_span = self.peek().span.clone();
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected field name".to_string()));
- };
- self.consume(&TokenType::Colon, "Expected ':' after field name")?;
- let field_type = self.parse_type()?;
- Ok(Field {
- name,
- field_type,
- span: start_span,
- })
- }
- fn parse_constant(&mut self) -> Result<Constant> {
- let start_span = self.advance().span.clone(); // consume 'let'
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected constant name".to_string()));
- };
- self.consume(&TokenType::Colon, "Expected ':' after constant name")?;
- let const_type = self.parse_type()?;
- self.consume(&TokenType::Assign, "Expected '=' after constant type")?;
- let value = self.parse_expression()?;
- Ok(Constant {
- name,
- const_type,
- value,
- span: start_span,
- })
- }
- fn parse_variable(&mut self) -> Result<Variable> {
- let start_span = self.advance().span.clone(); // consume 'var'
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected variable name".to_string()));
- };
- self.consume(&TokenType::Colon, "Expected ':' after variable name")?;
- let var_type = self.parse_type()?;
- self.consume(&TokenType::Assign, "Expected '=' after variable type")?;
- let initializer = self.parse_expression()?;
- Ok(Variable {
- name,
- var_type,
- initializer,
- mutable: true,
- span: start_span,
- })
- }
- fn parse_type(&mut self) -> Result<Type> {
- match &self.advance().token_type {
- TokenType::IntType => Ok(Type::Int),
- TokenType::FloatType => Ok(Type::Float),
- TokenType::StrType => Ok(Type::Str),
- TokenType::BoolType => Ok(Type::Bool),
- TokenType::VoidType => Ok(Type::Void),
- TokenType::LeftBracket => {
- let inner_type = self.parse_type()?;
- self.consume(&TokenType::RightBracket, "Expected ']' after list type")?;
- Ok(Type::List(Box::new(inner_type)))
- }
- TokenType::Identifier(name) => Ok(Type::Struct(name.clone())),
- _ => Err(Error::ParseError("Expected type".to_string())),
- }
- }
- fn parse_block(&mut self) -> Result<Block> {
- let start_span = self.peek().span.clone();
- self.consume(&TokenType::LeftBrace, "Expected '{'")?;
- let mut statements = Vec::new();
- while !self.check(&TokenType::RightBrace) && !self.is_at_end() {
- if self.match_token(&TokenType::Newline) {
- continue;
- }
- statements.push(self.parse_statement()?);
- }
- self.consume(&TokenType::RightBrace, "Expected '}'")?;
- Ok(Block {
- statements,
- span: start_span,
- })
- }
- fn parse_statement(&mut self) -> Result<Statement> {
- match &self.peek().token_type {
- TokenType::Let => {
- let var = self.parse_constant()?;
- Ok(Statement::Variable(Variable {
- name: var.name,
- var_type: var.const_type,
- initializer: var.value,
- mutable: false,
- span: var.span,
- }))
- }
- TokenType::Var => Ok(Statement::Variable(self.parse_variable()?)),
- TokenType::If => Ok(Statement::If(self.parse_if_statement()?)),
- TokenType::For => Ok(Statement::For(self.parse_for_loop()?)),
- TokenType::Try => Ok(Statement::Try(self.parse_try_statement()?)),
- TokenType::Return => Ok(Statement::Return(self.parse_return_statement()?)),
- _ => {
- // Check if it's an assignment or expression
- let expr = self.parse_expression()?;
- if self.match_token(&TokenType::Assign) {
- let value = self.parse_expression()?;
- Ok(Statement::Assignment(Assignment {
- target: expr,
- value,
- span: self.previous().span.clone(),
- }))
- } else {
- Ok(Statement::Expression(expr))
- }
- }
- }
- }
- fn parse_if_statement(&mut self) -> Result<IfStatement> {
- let start_span = self.advance().span.clone(); // consume 'if'
- let condition = self.parse_expression()?;
- let then_block = self.parse_block()?;
- let mut else_ifs = Vec::new();
- while self.match_token(&TokenType::Else) && self.check(&TokenType::If) {
- self.advance(); // consume 'if'
- let else_if_condition = self.parse_expression()?;
- let else_if_block = self.parse_block()?;
- else_ifs.push((else_if_condition, else_if_block));
- }
- let else_block = if self.match_token(&TokenType::Else) {
- Some(self.parse_block()?)
- } else {
- None
- };
- Ok(IfStatement {
- condition,
- then_block,
- else_ifs,
- else_block,
- span: start_span,
- })
- }
- fn parse_for_loop(&mut self) -> Result<ForLoop> {
- let start_span = self.advance().span.clone(); // consume 'for'
- let variable = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected variable name in for loop".to_string()));
- };
- self.consume(&TokenType::In, "Expected 'in' after for loop variable")?;
- let iterable = self.parse_expression()?;
- let body = self.parse_block()?;
- Ok(ForLoop {
- variable,
- iterable,
- body,
- span: start_span,
- })
- }
- fn parse_try_statement(&mut self) -> Result<TryStatement> {
- let start_span = self.advance().span.clone(); // consume 'try'
- let try_block = self.parse_block()?;
- let mut catch_clauses = Vec::new();
- while self.match_token(&TokenType::Catch) {
- let exception_type = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected exception type after 'catch'".to_string()));
- };
- let handler_block = self.parse_block()?;
- catch_clauses.push(CatchClause {
- exception_type,
- handler_block,
- span: self.previous().span.clone(),
- });
- }
- Ok(TryStatement {
- try_block,
- catch_clauses,
- span: start_span,
- })
- }
- fn parse_return_statement(&mut self) -> Result<ReturnStatement> {
- let start_span = self.advance().span.clone(); // consume 'return'
- let value = if !self.check(&TokenType::Newline) && !self.check(&TokenType::RightBrace) {
- Some(self.parse_expression()?)
- } else {
- None
- };
- Ok(ReturnStatement {
- value,
- span: start_span,
- })
- }
- fn parse_expression(&mut self) -> Result<Expression> {
- self.parse_or()
- }
- fn parse_or(&mut self) -> Result<Expression> {
- let mut expr = self.parse_and()?;
- while self.match_token(&TokenType::Or) {
- let operator = BinaryOperator::Or;
- let right = self.parse_and()?;
- expr = Expression::Binary(BinaryOp {
- left: Box::new(expr),
- operator,
- right: Box::new(right),
- span: self.previous().span.clone(),
- });
- }
- Ok(expr)
- }
- fn parse_and(&mut self) -> Result<Expression> {
- let mut expr = self.parse_equality()?;
- while self.match_token(&TokenType::And) {
- let operator = BinaryOperator::And;
- let right = self.parse_equality()?;
- expr = Expression::Binary(BinaryOp {
- left: Box::new(expr),
- operator,
- right: Box::new(right),
- span: self.previous().span.clone(),
- });
- }
- Ok(expr)
- }
- fn parse_equality(&mut self) -> Result<Expression> {
- let mut expr = self.parse_comparison()?;
- while let Some(op) = self.match_equality_operator() {
- let right = self.parse_comparison()?;
- expr = Expression::Binary(BinaryOp {
- left: Box::new(expr),
- operator: op,
- right: Box::new(right),
- span: self.previous().span.clone(),
- });
- }
- Ok(expr)
- }
- fn parse_comparison(&mut self) -> Result<Expression> {
- let mut expr = self.parse_term()?;
- while let Some(op) = self.match_comparison_operator() {
- let right = self.parse_term()?;
- expr = Expression::Binary(BinaryOp {
- left: Box::new(expr),
- operator: op,
- right: Box::new(right),
- span: self.previous().span.clone(),
- });
- }
- Ok(expr)
- }
- fn parse_term(&mut self) -> Result<Expression> {
- let mut expr = self.parse_factor()?;
- while let Some(op) = self.match_term_operator() {
- let right = self.parse_factor()?;
- expr = Expression::Binary(BinaryOp {
- left: Box::new(expr),
- operator: op,
- right: Box::new(right),
- span: self.previous().span.clone(),
- });
- }
- Ok(expr)
- }
- fn parse_factor(&mut self) -> Result<Expression> {
- let mut expr = self.parse_unary()?;
- while let Some(op) = self.match_factor_operator() {
- let right = self.parse_unary()?;
- expr = Expression::Binary(BinaryOp {
- left: Box::new(expr),
- operator: op,
- right: Box::new(right),
- span: self.previous().span.clone(),
- });
- }
- Ok(expr)
- }
- fn parse_unary(&mut self) -> Result<Expression> {
- if let Some(op) = self.match_unary_operator() {
- let operand = self.parse_unary()?;
- Ok(Expression::Unary(UnaryOp {
- operator: op,
- operand: Box::new(operand),
- span: self.previous().span.clone(),
- }))
- } else {
- self.parse_call()
- }
- }
- fn parse_call(&mut self) -> Result<Expression> {
- let mut expr = self.parse_primary()?;
- loop {
- if self.match_token(&TokenType::LeftParen) {
- expr = self.finish_call(expr)?;
- } else if self.match_token(&TokenType::Dot) {
- let name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected property name after '.'".to_string()));
- };
- expr = Expression::MemberAccess(MemberAccess {
- object: Box::new(expr),
- member: name,
- span: self.previous().span.clone(),
- });
- } else {
- break;
- }
- }
- Ok(expr)
- }
- fn finish_call(&mut self, callee: Expression) -> Result<Expression> {
- let mut arguments = Vec::new();
- if !self.check(&TokenType::RightParen) {
- loop {
- arguments.push(self.parse_expression()?);
- if !self.match_token(&TokenType::Comma) {
- break;
- }
- }
- }
- self.consume(&TokenType::RightParen, "Expected ')' after arguments")?;
- Ok(Expression::Call(FunctionCall {
- function: Box::new(callee),
- arguments,
- span: self.previous().span.clone(),
- }))
- }
- fn parse_primary(&mut self) -> Result<Expression> {
- match &self.advance().token_type {
- TokenType::Boolean(b) => Ok(Expression::Literal(Literal::Boolean(*b))),
- TokenType::Integer(n) => Ok(Expression::Literal(Literal::Integer(*n))),
- TokenType::Float(f) => Ok(Expression::Literal(Literal::Float(*f))),
- TokenType::String(s) => Ok(Expression::Literal(Literal::String(s.clone()))),
- TokenType::Identifier(name) => {
- if self.match_token(&TokenType::LeftBrace) {
- // Struct initialization
- let mut fields = std::collections::HashMap::new();
- while !self.check(&TokenType::RightBrace) && !self.is_at_end() {
- let field_name = if let TokenType::Identifier(name) = &self.advance().token_type {
- name.clone()
- } else {
- return Err(Error::ParseError("Expected field name".to_string()));
- };
- self.consume(&TokenType::Colon, "Expected ':' after field name")?;
- let field_value = self.parse_expression()?;
- fields.insert(field_name, field_value);
- if !self.match_token(&TokenType::Comma) {
- break;
- }
- }
- self.consume(&TokenType::RightBrace, "Expected '}' after struct fields")?;
- Ok(Expression::StructInit(StructInitializer {
- struct_name: name.clone(),
- fields,
- span: self.previous().span.clone(),
Advertisement
Add Comment
Please, Sign In to add comment