Initialize Aster project with basic structure, including Cargo configuration, lexer, parser, interpreter, and AST definitions. Add a sample script and README documentation. Implement basic error handling and environment management for variable storage.

This commit is contained in:
0264408
2026-02-04 16:42:51 +08:00
commit f86300f3ce
19 changed files with 1484 additions and 0 deletions
+431
View File
@@ -0,0 +1,431 @@
use crate::ast::*;
use crate::lexer::{Token, TokenKind};
use crate::error::RuntimeError;
pub struct Parser {
tokens: Vec<Token>,
current: usize,
}
impl Parser {
pub fn new(tokens: Vec<Token>) -> Self {
Self { tokens, current: 0 }
}
pub fn parse(&mut self) -> Vec<Stmt> {
let mut statements = Vec::new();
while !self.is_at_end() {
statements.push(self.declaration());
}
statements
}
fn declaration(&mut self) -> Stmt {
if self.match_kind(&[TokenKind::Let]) {
self.let_declaration()
} else if self.match_kind(&[TokenKind::Fn]) {
self.fn_declaration()
} else {
self.statement()
}
}
fn statement(&mut self) -> Stmt {
if self.match_kind(&[TokenKind::If]) {
self.if_statement()
} else if self.match_kind(&[TokenKind::While]) {
self.while_statement()
} else if self.match_kind(&[TokenKind::Return]) {
self.return_statement()
} else if self.match_kind(&[TokenKind::LeftBrace]) {
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();
self.match_kind(&[TokenKind::Semicolon]); // 分号可选
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();
let mut params = Vec::new();
if !self.check(&TokenKind::RightParen) {
loop {
params.push(self.consume_ident("Expected parameter name.").unwrap());
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();
Stmt::Function { name, params, body }
}
fn lambda_expr(&mut self) -> Expr {
self.consume(TokenKind::LeftParen, "Expected '(' after 'fn'.").unwrap();
let mut params = Vec::new();
if !self.check(&TokenKind::RightParen) {
loop {
params.push(self.consume_ident("Expected parameter name.").unwrap());
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 }
}
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();
let then_branch = Box::new(self.statement());
let else_branch = if self.match_kind(&[TokenKind::Else]) {
Some(Box::new(self.statement()))
} else {
None
};
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();
let body = Box::new(self.statement());
Stmt::While { condition, body }
}
fn return_statement(&mut self) -> Stmt {
let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) {
Some(self.expression())
} else {
None
};
self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::Return(value)
}
fn block(&mut self) -> Vec<Stmt> {
let mut statements = Vec::new();
while !self.check(&TokenKind::RightBrace) && !self.is_at_end() {
statements.push(self.declaration());
}
self.consume(TokenKind::RightBrace, "Expected '}' after block.").unwrap();
statements
}
fn expression_statement(&mut self) -> Stmt {
let expr = self.expression();
self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::ExprStmt(expr)
}
fn expression(&mut self) -> Expr {
self.assignment()
}
fn assignment(&mut self) -> Expr {
let expr = self.logical_or();
if self.match_kind(&[TokenKind::Equal]) {
let value = self.assignment();
if let Expr::Variable(name) = expr {
return Expr::Assign {
name,
value: Box::new(value),
};
} else {
panic!("Invalid assignment target.");
}
}
expr
}
fn logical_or(&mut self) -> Expr {
let mut expr = self.logical_and();
while self.match_kind(&[TokenKind::OrOr]) {
let right = self.logical_and();
expr = Expr::Logical {
left: Box::new(expr),
op: LogicalOp::Or,
right: Box::new(right),
};
}
expr
}
fn logical_and(&mut self) -> Expr {
let mut expr = self.equality();
while self.match_kind(&[TokenKind::AndAnd]) {
let right = self.equality();
expr = Expr::Logical {
left: Box::new(expr),
op: LogicalOp::And,
right: Box::new(right),
};
}
expr
}
fn equality(&mut self) -> Expr {
let mut expr = self.comparison();
while self.match_kind(&[TokenKind::EqualEqual, TokenKind::BangEqual]) {
let op = match self.previous().kind {
TokenKind::EqualEqual => BinaryOp::Equal,
TokenKind::BangEqual => BinaryOp::NotEqual,
_ => unreachable!(),
};
let right = self.comparison();
expr = Expr::Binary {
left: Box::new(expr),
op,
right: Box::new(right),
};
}
expr
}
fn comparison(&mut self) -> Expr {
let mut expr = self.term();
while self.match_kind(&[TokenKind::Greater, TokenKind::GreaterEqual, TokenKind::Less, TokenKind::LessEqual]) {
let op = match self.previous().kind {
TokenKind::Greater => BinaryOp::Greater,
TokenKind::GreaterEqual => BinaryOp::GreaterEqual,
TokenKind::Less => BinaryOp::Less,
TokenKind::LessEqual => BinaryOp::LessEqual,
_ => unreachable!(),
};
let right = self.term();
expr = Expr::Binary {
left: Box::new(expr),
op,
right: Box::new(right),
};
}
expr
}
fn term(&mut self) -> Expr {
let mut expr = self.factor();
while self.match_kind(&[TokenKind::Plus, TokenKind::Minus]) {
let op = match self.previous().kind {
TokenKind::Plus => BinaryOp::Add,
TokenKind::Minus => BinaryOp::Sub,
_ => unreachable!(),
};
let right = self.factor();
expr = Expr::Binary {
left: Box::new(expr),
op,
right: Box::new(right),
};
}
expr
}
fn factor(&mut self) -> Expr {
let mut expr = self.unary();
while self.match_kind(&[TokenKind::Star, TokenKind::Slash]) {
let op = match self.previous().kind {
TokenKind::Star => BinaryOp::Mul,
TokenKind::Slash => BinaryOp::Div,
_ => unreachable!(),
};
let right = self.unary();
expr = Expr::Binary {
left: Box::new(expr),
op,
right: Box::new(right),
};
}
expr
}
fn unary(&mut self) -> Expr {
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 {
op,
right: Box::new(right),
};
}
self.call()
}
fn call(&mut self) -> Expr {
let mut expr = self.primary();
while self.match_kind(&[TokenKind::LeftParen]) {
let mut arguments = Vec::new();
if !self.check(&TokenKind::RightParen) {
loop {
arguments.push(self.expression());
if !self.match_kind(&[TokenKind::Comma]) {
break;
}
}
}
self.consume(TokenKind::RightParen, "Expected ')' after arguments.").unwrap();
expr = Expr::Call {
callee: Box::new(expr),
arguments,
};
}
expr
}
fn primary(&mut self) -> Expr {
// 布尔值
if self.match_kind(&[TokenKind::True]) {
return Expr::Literal(Literal::Bool(true));
}
if self.match_kind(&[TokenKind::False]) {
return Expr::Literal(Literal::Bool(false));
}
if self.match_kind(&[TokenKind::Nil]) {
return Expr::Literal(Literal::Nil);
}
// 数字
if let TokenKind::Number(n) = self.peek().kind {
self.advance();
return 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));
}
// 标识符(变量)
if let TokenKind::Identifier(name) = &self.peek().kind {
let name = name.clone();
self.advance();
return Expr::Variable(name);
}
// 匿名函数(闭包): fn(params) { body }
if self.match_kind(&[TokenKind::Fn]) {
return self.lambda_expr();
}
// 括号表达式
if self.match_kind(&[TokenKind::LeftParen]) {
let expr = self.expression();
self.consume(TokenKind::RightParen, "Expected ')' after expression.").unwrap();
return expr;
}
panic!("Expected expression at line {}", self.peek().line);
}
fn match_kind(&mut self, kinds: &[TokenKind]) -> bool {
for kind in kinds {
if self.check(kind) {
self.advance();
return true;
}
}
false
}
fn consume(&mut self, kind: TokenKind, msg: &str) -> Result<(), RuntimeError> {
if self.check(&kind) {
self.advance();
Ok(())
} else {
Err(RuntimeError::ParseError {
message: msg.to_string(),
token: self.peek().clone(),
})
}
}
fn consume_ident(&mut self, msg: &str) -> Result<String, RuntimeError> {
match &self.peek().kind {
TokenKind::Identifier(name) => {
let name = name.clone();
self.advance();
Ok(name)
}
_ => Err(RuntimeError::ParseError {
message: msg.to_string(),
token: self.peek().clone(),
}),
}
}
fn check(&self, kind: &TokenKind) -> bool {
if self.is_at_end() {
return false;
}
std::mem::discriminant(&self.peek().kind)
== std::mem::discriminant(kind)
}
fn advance(&mut self) -> &Token {
if !self.is_at_end() {
self.current += 1;
}
self.previous()
}
fn is_at_end(&self) -> bool {
matches!(self.peek().kind, TokenKind::EOF)
}
fn peek(&self) -> &Token {
&self.tokens[self.current]
}
fn previous(&self) -> &Token {
&self.tokens[self.current - 1]
}
}