diff --git a/src/error/error.rs b/src/error/error.rs index 8b22307..e6cabb8 100644 --- a/src/error/error.rs +++ b/src/error/error.rs @@ -2,13 +2,35 @@ use crate::lexer::Token; #[derive(Debug)] pub enum RuntimeError { + LexError { message: String, line: usize, column: usize }, ParseError { message: String, token: Token }, RuntimeError { message: String, token: Option }, } +impl RuntimeError { + pub fn lex(message: impl Into, line: usize, column: usize) -> Self { + RuntimeError::LexError { + message: message.into(), + line, + column, + } + } + + pub fn parse(message: impl Into, token: Token) -> Self { + RuntimeError::ParseError { + message: message.into(), + token, + } + } + +} + impl std::fmt::Display for RuntimeError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + RuntimeError::LexError { message, line, column } => { + write!(f, "[Lex Error] {} at line {}, column {}", message, line, column) + } RuntimeError::ParseError { message, token } => { write!(f, "[Parse Error] {} at line {}, column {}", message, token.line, token.column) } diff --git a/src/lexer/lexer.rs b/src/lexer/lexer.rs index 5a9c36a..f12145d 100644 --- a/src/lexer/lexer.rs +++ b/src/lexer/lexer.rs @@ -1,6 +1,7 @@ // src/lexer/lexer.rs use super::{Token, TokenKind}; +use crate::error::RuntimeError; pub struct Lexer { src: Vec, @@ -19,11 +20,12 @@ impl Lexer { } } - pub fn tokenize(mut self) -> Vec { + pub fn tokenize(mut self) -> (Vec, Vec) { let mut tokens = Vec::new(); + let mut errors = Vec::new(); while !self.is_at_end() { - if let Some(token) = self.next_token() { + if let Some(token) = self.next_token(&mut errors) { tokens.push(token); } } @@ -34,10 +36,10 @@ impl Lexer { column: self.column, }); - tokens + (tokens, errors) } - fn next_token(&mut self) -> Option { + fn next_token(&mut self, errors: &mut Vec) -> Option { self.skip_whitespace(); if self.is_at_end() { @@ -140,7 +142,8 @@ impl Lexer { if self.match_char('&') { TokenKind::AndAnd } else { - panic!("Unexpected '&' at {}:{}", line, column); + errors.push(RuntimeError::lex("Unexpected '&'. Did you mean '&&'?", line, column)); + return None; } } @@ -148,11 +151,12 @@ impl Lexer { if self.match_char('|') { TokenKind::OrOr } else { - panic!("Unexpected '|' at {}:{}", line, column); + errors.push(RuntimeError::lex("Unexpected '|'. Did you mean '||'?", line, column)); + return None; } } - '"' => return Some(self.string_literal(line, column)), + '"' => return self.string_literal(line, column, errors), c if c.is_ascii_digit() => { return Some(self.number_literal(c, line, column)); @@ -163,7 +167,12 @@ impl Lexer { } _ => { - panic!("Unexpected character '{}' at {}:{}", c, line, column); + errors.push(RuntimeError::lex( + format!("Unexpected character '{}'", c), + line, + column, + )); + return None; } }; @@ -215,7 +224,12 @@ impl Lexer { self.current >= self.src.len() } - fn string_literal(&mut self, line: usize, column: usize) -> Token { + fn string_literal( + &mut self, + line: usize, + column: usize, + errors: &mut Vec, + ) -> Option { let mut value = String::new(); while !self.is_at_end() && self.peek() != '"' { @@ -223,16 +237,17 @@ impl Lexer { } if self.is_at_end() { - panic!("Unterminated string at {}:{}", line, column); + errors.push(RuntimeError::lex("Unterminated string literal", line, column)); + return None; } self.advance(); // consume closing " - Token { + Some(Token { kind: TokenKind::String(value), line, column, - } + }) } fn number_literal(&mut self, first: char, line: usize, column: usize) -> Token { diff --git a/src/main.rs b/src/main.rs index 554b434..cb9d4b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,21 +7,37 @@ mod error; use lexer::Lexer; use parser::Parser; use interpreter::Interpreter; +use error::RuntimeError; use std::env; use std::fs; use std::io::Write; use std::io::stdin; use std::io::stdout; +fn print_errors(errors: &[RuntimeError]) { + for err in errors { + eprintln!("{}", err); + } +} + fn run_file(src: String) { - let tokens = Lexer::new(&src).tokenize(); + let (tokens, lex_errors) = Lexer::new(&src).tokenize(); + if !lex_errors.is_empty() { + print_errors(&lex_errors); + std::process::exit(65); + } + let mut parser = Parser::new(tokens); - let stmts = parser.parse(); + let (stmts, parse_errors) = parser.parse(); + if !parse_errors.is_empty() { + print_errors(&parse_errors); + std::process::exit(65); + } let mut interpreter = Interpreter::new(); if let Err(e) = interpreter.interpret(stmts) { eprintln!("Error: {}", e); - std::process::exit(1); + std::process::exit(70); } } @@ -61,9 +77,18 @@ fn run_repl() { _ => {} } - let tokens = Lexer::new(line).tokenize(); + let (tokens, lex_errors) = Lexer::new(line).tokenize(); + if !lex_errors.is_empty() { + print_errors(&lex_errors); + continue; + } + let mut parser = Parser::new(tokens); - let stmts = parser.parse(); + let (stmts, parse_errors) = parser.parse(); + if !parse_errors.is_empty() { + print_errors(&parse_errors); + continue; + } if let Err(e) = interpreter.interpret(stmts) { eprintln!("Error: {}", e); diff --git a/src/parser/parser.rs b/src/parser/parser.rs index bcf18cf..7b7f645 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -12,17 +12,24 @@ impl Parser { Self { tokens, current: 0 } } - pub fn parse(&mut self) -> Vec { + pub fn parse(&mut self) -> (Vec, Vec) { let mut statements = Vec::new(); + let mut errors = Vec::new(); while !self.is_at_end() { - statements.push(self.declaration()); + match self.declaration() { + Ok(stmt) => statements.push(stmt), + Err(err) => { + errors.push(err); + self.synchronize(); + } + } } - statements + (statements, errors) } - fn declaration(&mut self) -> Stmt { + fn declaration(&mut self) -> Result { if self.match_kind(&[TokenKind::Let]) { self.let_declaration() } else if self.match_kind(&[TokenKind::Fn]) { @@ -32,7 +39,7 @@ impl Parser { } } - fn statement(&mut self) -> Stmt { + fn statement(&mut self) -> Result { if self.match_kind(&[TokenKind::If]) { self.if_statement() } else if self.match_kind(&[TokenKind::While]) { @@ -46,161 +53,161 @@ impl Parser { } else if self.match_kind(&[TokenKind::Return]) { self.return_statement() } else if self.match_kind(&[TokenKind::LeftBrace]) { - Stmt::Block(self.block()) + Ok(Stmt::Block(self.block()?)) } else { self.expression_statement() } } - fn let_declaration(&mut self) -> Stmt { - let name = self.consume_ident("Expected variable name.").unwrap(); - self.consume(TokenKind::Equal, "Expected '=' after variable name.").unwrap(); - let initializer = self.expression(); + fn let_declaration(&mut self) -> Result { + let name = self.consume_ident("Expected variable name.")?; + self.consume(TokenKind::Equal, "Expected '=' after variable name.")?; + let initializer = self.expression()?; self.match_kind(&[TokenKind::Semicolon]); // 分号可选 - Stmt::Let { name, initializer } + Ok(Stmt::Let { name, initializer }) } - fn fn_declaration(&mut self) -> Stmt { - let name = self.consume_ident("Expected function name.").unwrap(); - self.consume(TokenKind::LeftParen, "Expected '(' after function name.").unwrap(); + fn fn_declaration(&mut self) -> Result { + let name = self.consume_ident("Expected function name.")?; + self.consume(TokenKind::LeftParen, "Expected '(' after function name.")?; let mut params = Vec::new(); if !self.check(&TokenKind::RightParen) { loop { - params.push(self.consume_ident("Expected parameter name.").unwrap()); + params.push(self.consume_ident("Expected parameter name.")?); if !self.match_kind(&[TokenKind::Comma]) { break; } } } - self.consume(TokenKind::RightParen, "Expected ')' after parameters.").unwrap(); - self.consume(TokenKind::LeftBrace, "Expected '{' before function body.").unwrap(); - let body = self.block(); + self.consume(TokenKind::RightParen, "Expected ')' after parameters.")?; + self.consume(TokenKind::LeftBrace, "Expected '{' before function body.")?; + let body = self.block()?; - Stmt::Function { name, params, body } + Ok(Stmt::Function { name, params, body }) } - fn lambda_expr(&mut self) -> Expr { - self.consume(TokenKind::LeftParen, "Expected '(' after 'fn'.").unwrap(); + fn lambda_expr(&mut self) -> Result { + self.consume(TokenKind::LeftParen, "Expected '(' after 'fn'.")?; let mut params = Vec::new(); if !self.check(&TokenKind::RightParen) { loop { - params.push(self.consume_ident("Expected parameter name.").unwrap()); + params.push(self.consume_ident("Expected parameter name.")?); if !self.match_kind(&[TokenKind::Comma]) { break; } } } - self.consume(TokenKind::RightParen, "Expected ')' after parameters.").unwrap(); - self.consume(TokenKind::LeftBrace, "Expected '{' before function body.").unwrap(); - let body = self.block(); - Expr::Lambda { params, body } + self.consume(TokenKind::RightParen, "Expected ')' after parameters.")?; + self.consume(TokenKind::LeftBrace, "Expected '{' before function body.")?; + let body = self.block()?; + Ok(Expr::Lambda { params, body }) } - fn if_statement(&mut self) -> Stmt { - self.consume(TokenKind::LeftParen, "Expected '(' after 'if'.").unwrap(); - let condition = self.expression(); - self.consume(TokenKind::RightParen, "Expected ')' after condition.").unwrap(); + fn if_statement(&mut self) -> Result { + self.consume(TokenKind::LeftParen, "Expected '(' after 'if'.")?; + let condition = self.expression()?; + self.consume(TokenKind::RightParen, "Expected ')' after condition.")?; - let then_branch = Box::new(self.statement()); + let then_branch = Box::new(self.statement()?); let else_branch = if self.match_kind(&[TokenKind::Else]) { - Some(Box::new(self.statement())) + Some(Box::new(self.statement()?)) } else { None }; - Stmt::If { condition, then_branch, else_branch } + Ok(Stmt::If { condition, then_branch, else_branch }) } - fn while_statement(&mut self) -> Stmt { - self.consume(TokenKind::LeftParen, "Expected '(' after 'while'.").unwrap(); - let condition = self.expression(); - self.consume(TokenKind::RightParen, "Expected ')' after condition.").unwrap(); + fn while_statement(&mut self) -> Result { + self.consume(TokenKind::LeftParen, "Expected '(' after 'while'.")?; + let condition = self.expression()?; + self.consume(TokenKind::RightParen, "Expected ')' after condition.")?; - let body = Box::new(self.statement()); - Stmt::While { condition, body } + let body = Box::new(self.statement()?); + Ok(Stmt::While { condition, body }) } - fn for_statement(&mut self) -> Stmt { - self.consume(TokenKind::LeftParen, "Expected '(' after 'for'.").unwrap(); + fn for_statement(&mut self) -> Result { + self.consume(TokenKind::LeftParen, "Expected '(' after 'for'.")?; let initializer = if self.match_kind(&[TokenKind::Semicolon]) { None } else if self.match_kind(&[TokenKind::Let]) { - Some(self.let_declaration()) + Some(self.let_declaration()?) } else { - Some(self.expression_statement()) + Some(self.expression_statement()?) }; let condition = if !self.check(&TokenKind::Semicolon) { - Some(self.expression()) + Some(self.expression()?) } else { None }; - self.consume(TokenKind::Semicolon, "Expected ';' after loop condition.").unwrap(); + self.consume(TokenKind::Semicolon, "Expected ';' after loop condition.")?; let step = if !self.check(&TokenKind::RightParen) { - Some(self.expression()) + Some(self.expression()?) } else { None }; - self.consume(TokenKind::RightParen, "Expected ')' after for clauses.").unwrap(); - let body = Box::new(self.statement()); + self.consume(TokenKind::RightParen, "Expected ')' after for clauses.")?; + let body = Box::new(self.statement()?); - Stmt::For { + Ok(Stmt::For { initializer: initializer.map(Box::new), condition, step, body - } + }) } - fn break_statement(&mut self) -> Stmt { + fn break_statement(&mut self) -> Result { self.match_kind(&[TokenKind::Semicolon]); // 分号可选 - Stmt::Break + Ok(Stmt::Break) } - fn continue_statement(&mut self) -> Stmt { + fn continue_statement(&mut self) -> Result { self.match_kind(&[TokenKind::Semicolon]); // 分号可选 - Stmt::Continue + Ok(Stmt::Continue) } - fn return_statement(&mut self) -> Stmt { + fn return_statement(&mut self) -> Result { let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) { - Some(self.expression()) + Some(self.expression()?) } else { None }; self.match_kind(&[TokenKind::Semicolon]); // 分号可选 - Stmt::Return(value) + Ok(Stmt::Return(value)) } - fn block(&mut self) -> Vec { + fn block(&mut self) -> Result, RuntimeError> { let mut statements = Vec::new(); while !self.check(&TokenKind::RightBrace) && !self.is_at_end() { - statements.push(self.declaration()); + statements.push(self.declaration()?); } - self.consume(TokenKind::RightBrace, "Expected '}' after block.").unwrap(); - statements + self.consume(TokenKind::RightBrace, "Expected '}' after block.")?; + Ok(statements) } - fn expression_statement(&mut self) -> Stmt { - let expr = self.expression(); + fn expression_statement(&mut self) -> Result { + let expr = self.expression()?; self.match_kind(&[TokenKind::Semicolon]); // 分号可选 - Stmt::ExprStmt(expr) + Ok(Stmt::ExprStmt(expr)) } - fn expression(&mut self) -> Expr { + fn expression(&mut self) -> Result { self.assignment() } - fn assignment(&mut self) -> Expr { - let expr = self.logical_or(); + fn assignment(&mut self) -> Result { + let expr = self.logical_or()?; let op = if self.match_kind(&[TokenKind::Equal]) { Some(AssignOp::Equal) @@ -219,23 +226,23 @@ impl Parser { }; if let Some(op) = op { - let value = self.assignment(); + let value = self.assignment()?; return match expr { - Expr::Variable(name) => Expr::Assign { name, op, value: Box::new(value) }, - Expr::Get { object, name } => Expr::Set { object, name, op, value: Box::new(value) }, - Expr::IndexGet { array, index } => Expr::IndexSet { array, index, op, value: Box::new(value) }, - _ => panic!("Invalid assignment target."), + Expr::Variable(name) => Ok(Expr::Assign { name, op, value: Box::new(value) }), + Expr::Get { object, name } => Ok(Expr::Set { object, name, op, value: Box::new(value) }), + Expr::IndexGet { array, index } => Ok(Expr::IndexSet { array, index, op, value: Box::new(value) }), + _ => Err(RuntimeError::parse("Invalid assignment target.", self.previous().clone())), }; } - expr + Ok(expr) } - fn logical_or(&mut self) -> Expr { - let mut expr = self.logical_and(); + fn logical_or(&mut self) -> Result { + let mut expr = self.logical_and()?; while self.match_kind(&[TokenKind::OrOr]) { - let right = self.logical_and(); + let right = self.logical_and()?; expr = Expr::Logical { left: Box::new(expr), op: LogicalOp::Or, @@ -243,14 +250,14 @@ impl Parser { }; } - expr + Ok(expr) } - fn logical_and(&mut self) -> Expr { - let mut expr = self.equality(); + fn logical_and(&mut self) -> Result { + let mut expr = self.equality()?; while self.match_kind(&[TokenKind::AndAnd]) { - let right = self.equality(); + let right = self.equality()?; expr = Expr::Logical { left: Box::new(expr), op: LogicalOp::And, @@ -258,11 +265,11 @@ impl Parser { }; } - expr + Ok(expr) } - fn equality(&mut self) -> Expr { - let mut expr = self.comparison(); + fn equality(&mut self) -> Result { + let mut expr = self.comparison()?; while self.match_kind(&[TokenKind::EqualEqual, TokenKind::BangEqual]) { let op = match self.previous().kind { @@ -270,7 +277,7 @@ impl Parser { TokenKind::BangEqual => BinaryOp::NotEqual, _ => unreachable!(), }; - let right = self.comparison(); + let right = self.comparison()?; expr = Expr::Binary { left: Box::new(expr), op, @@ -278,11 +285,11 @@ impl Parser { }; } - expr + Ok(expr) } - fn comparison(&mut self) -> Expr { - let mut expr = self.term(); + fn comparison(&mut self) -> Result { + let mut expr = self.term()?; while self.match_kind(&[TokenKind::Greater, TokenKind::GreaterEqual, TokenKind::Less, TokenKind::LessEqual]) { let op = match self.previous().kind { @@ -292,7 +299,7 @@ impl Parser { TokenKind::LessEqual => BinaryOp::LessEqual, _ => unreachable!(), }; - let right = self.term(); + let right = self.term()?; expr = Expr::Binary { left: Box::new(expr), op, @@ -300,11 +307,11 @@ impl Parser { }; } - expr + Ok(expr) } - fn term(&mut self) -> Expr { - let mut expr = self.factor(); + fn term(&mut self) -> Result { + let mut expr = self.factor()?; while self.match_kind(&[TokenKind::Plus, TokenKind::Minus]) { let op = match self.previous().kind { @@ -312,7 +319,7 @@ impl Parser { TokenKind::Minus => BinaryOp::Sub, _ => unreachable!(), }; - let right = self.factor(); + let right = self.factor()?; expr = Expr::Binary { left: Box::new(expr), op, @@ -320,11 +327,11 @@ impl Parser { }; } - expr + Ok(expr) } - fn factor(&mut self) -> Expr { - let mut expr = self.unary(); + fn factor(&mut self) -> Result { + let mut expr = self.unary()?; while self.match_kind(&[TokenKind::Star, TokenKind::Slash, TokenKind::Percent]) { let op = match self.previous().kind { @@ -333,7 +340,7 @@ impl Parser { TokenKind::Percent => BinaryOp::Mod, _ => unreachable!(), }; - let right = self.unary(); + let right = self.unary()?; expr = Expr::Binary { left: Box::new(expr), op, @@ -341,54 +348,54 @@ impl Parser { }; } - expr + Ok(expr) } - fn unary(&mut self) -> Expr { + fn unary(&mut self) -> Result { if self.match_kind(&[TokenKind::Bang, TokenKind::Minus]) { let op = match self.previous().kind { TokenKind::Bang => UnaryOp::Not, TokenKind::Minus => UnaryOp::Negate, _ => unreachable!(), }; - let right = self.unary(); - return Expr::Unary { + let right = self.unary()?; + return Ok(Expr::Unary { op, right: Box::new(right), - }; + }); } self.call() } - fn call(&mut self) -> Expr { - let mut expr = self.primary(); + fn call(&mut self) -> Result { + let mut expr = self.primary()?; loop { if self.match_kind(&[TokenKind::LeftParen]) { let mut arguments = Vec::new(); if !self.check(&TokenKind::RightParen) { loop { - arguments.push(self.expression()); + arguments.push(self.expression()?); if !self.match_kind(&[TokenKind::Comma]) { break; } } } - self.consume(TokenKind::RightParen, "Expected ')' after arguments.").unwrap(); + self.consume(TokenKind::RightParen, "Expected ')' after arguments.")?; expr = Expr::Call { callee: Box::new(expr), arguments, }; } else if self.match_kind(&[TokenKind::Dot]) { - let name = self.consume_ident("Expected property name after '.'.").unwrap(); + let name = self.consume_ident("Expected property name after '.'.")?; expr = Expr::Get { object: Box::new(expr), name, }; } else if self.match_kind(&[TokenKind::LeftBracket]) { - let index = self.expression(); - self.consume(TokenKind::RightBracket, "Expected ']' after index.").unwrap(); + let index = self.expression()?; + self.consume(TokenKind::RightBracket, "Expected ']' after index.")?; expr = Expr::IndexGet { array: Box::new(expr), index: Box::new(index), @@ -398,39 +405,39 @@ impl Parser { } } - expr + Ok(expr) } - fn primary(&mut self) -> Expr { + fn primary(&mut self) -> Result { // 布尔值 if self.match_kind(&[TokenKind::True]) { - return Expr::Literal(Literal::Bool(true)); + return Ok(Expr::Literal(Literal::Bool(true))); } if self.match_kind(&[TokenKind::False]) { - return Expr::Literal(Literal::Bool(false)); + return Ok(Expr::Literal(Literal::Bool(false))); } if self.match_kind(&[TokenKind::Nil]) { - return Expr::Literal(Literal::Nil); + return Ok(Expr::Literal(Literal::Nil)); } // 数字 if let TokenKind::Number(n) = self.peek().kind { self.advance(); - return Expr::Literal(Literal::Number(n)); + return Ok(Expr::Literal(Literal::Number(n))); } // 字符串 if let TokenKind::String(s) = &self.peek().kind { let s = s.clone(); self.advance(); - return Expr::Literal(Literal::String(s)); + return Ok(Expr::Literal(Literal::String(s))); } // 标识符(变量) if let TokenKind::Identifier(name) = &self.peek().kind { let name = name.clone(); self.advance(); - return Expr::Variable(name); + return Ok(Expr::Variable(name)); } // 匿名函数(闭包): fn(params) { body } @@ -440,9 +447,9 @@ impl Parser { // 括号表达式 if self.match_kind(&[TokenKind::LeftParen]) { - let expr = self.expression(); - self.consume(TokenKind::RightParen, "Expected ')' after expression.").unwrap(); - return expr; + let expr = self.expression()?; + self.consume(TokenKind::RightParen, "Expected ')' after expression.")?; + return Ok(expr); } if self.match_kind(&[TokenKind::LeftBrace]) { @@ -453,7 +460,7 @@ impl Parser { return self.array_literal(); } - panic!("Expected expression at line {}", self.peek().line); + Err(RuntimeError::parse("Expected expression.", self.peek().clone())) } fn match_kind(&mut self, kinds: &[TokenKind]) -> bool { @@ -471,10 +478,7 @@ impl Parser { self.advance(); Ok(()) } else { - Err(RuntimeError::ParseError { - message: msg.to_string(), - token: self.peek().clone(), - }) + Err(RuntimeError::parse(msg, self.peek().clone())) } } @@ -485,10 +489,7 @@ impl Parser { self.advance(); Ok(name) } - _ => Err(RuntimeError::ParseError { - message: msg.to_string(), - token: self.peek().clone(), - }), + _ => Err(RuntimeError::parse(msg, self.peek().clone())), } } @@ -519,34 +520,56 @@ impl Parser { &self.tokens[self.current - 1] } - fn object_literal(&mut self) -> Expr { + fn object_literal(&mut self) -> Result { let mut properties = Vec::new(); if !self.check(&TokenKind::RightBrace) { loop { - let name = self.consume_ident("Expected property name in object literal").unwrap(); - self.consume(TokenKind::Colon, "Expected ':' after property name in object literal").unwrap(); - let value = self.expression(); + let name = self.consume_ident("Expected property name in object literal")?; + self.consume(TokenKind::Colon, "Expected ':' after property name in object literal")?; + let value = self.expression()?; properties.push((name, value)); if !self.match_kind(&[TokenKind::Comma]) { break; } } } - self.consume(TokenKind::RightBrace, "Expected '}' after object literal").unwrap(); - Expr::ObjectLiteral { properties } + self.consume(TokenKind::RightBrace, "Expected '}' after object literal")?; + Ok(Expr::ObjectLiteral { properties }) } - fn array_literal(&mut self) -> Expr { + fn array_literal(&mut self) -> Result { let mut elements = Vec::new(); if !self.check(&TokenKind::RightBracket) { loop { - elements.push(self.expression()); + elements.push(self.expression()?); if !self.match_kind(&[TokenKind::Comma]) { break; } } } - self.consume(TokenKind::RightBracket, "Expected ']' after array literal").unwrap(); - Expr::ArrayLiteral { elements } + self.consume(TokenKind::RightBracket, "Expected ']' after array literal")?; + Ok(Expr::ArrayLiteral { elements }) + } + + fn synchronize(&mut self) { + while !self.is_at_end() { + if self.current > 0 && matches!(self.previous().kind, TokenKind::Semicolon) { + return; + } + + match self.peek().kind { + TokenKind::Let + | TokenKind::Fn + | TokenKind::If + | TokenKind::While + | TokenKind::For + | TokenKind::Return + | TokenKind::Break + | TokenKind::Continue => return, + _ => { + self.advance(); + } + } + } } } \ No newline at end of file