192 lines
4.5 KiB
Rust
192 lines
4.5 KiB
Rust
use crate::tokens::Token;
|
|
|
|
/* --------- *
|
|
* AST nodes *
|
|
* --------- */
|
|
|
|
/// The AST node for the program
|
|
#[derive(Default, Debug, Clone)]
|
|
pub struct ProgramNode(pub Vec<StmtNode>);
|
|
|
|
/// A function declaration.
|
|
#[derive(Debug, Clone)]
|
|
pub struct FunDecl {
|
|
pub name: Token,
|
|
pub params: Vec<Token>,
|
|
pub body: Vec<StmtNode>,
|
|
}
|
|
|
|
/// The declaration of a class member.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub enum ClassMemberKind {
|
|
Method,
|
|
Getter,
|
|
Setter,
|
|
}
|
|
|
|
/// The declaration of a class member.
|
|
#[derive(Debug, Clone)]
|
|
pub struct ClassMemberDecl {
|
|
pub kind: ClassMemberKind,
|
|
pub is_static: bool,
|
|
pub fun_decl: FunDecl,
|
|
}
|
|
|
|
/// A class declaration.
|
|
#[derive(Debug, Clone)]
|
|
pub struct ClassDecl {
|
|
/// The token that represents the name of the class.
|
|
pub name: Token,
|
|
/// The token indicating the name of the parent class, if any.
|
|
pub superclass: Option<Token>,
|
|
/// The list of class members.
|
|
pub members: Vec<ClassMemberDecl>,
|
|
}
|
|
|
|
/// An AST node that represents a statement.
|
|
#[derive(Debug, Clone)]
|
|
pub enum StmtNode {
|
|
/// A variable declaration
|
|
VarDecl(Token, Option<ExprNode>),
|
|
/// A function declaration
|
|
FunDecl(FunDecl),
|
|
/// A class declaration
|
|
ClassDecl(ClassDecl),
|
|
/// An single expression
|
|
Expression(ExprNode),
|
|
/// The print statement
|
|
Print(ExprNode),
|
|
/// A block containing multiple statements.
|
|
Block(Vec<StmtNode>),
|
|
/// A conditional statement.
|
|
If {
|
|
condition: ExprNode,
|
|
then_branch: Box<StmtNode>,
|
|
else_branch: Option<Box<StmtNode>>,
|
|
},
|
|
/// Loop statement.
|
|
Loop {
|
|
label: Option<Token>,
|
|
condition: ExprNode,
|
|
body: Box<StmtNode>,
|
|
after_body: Option<Box<StmtNode>>,
|
|
},
|
|
/// Break or continue statement.
|
|
LoopControl {
|
|
is_break: bool,
|
|
loop_name: Option<Token>,
|
|
},
|
|
/// Return statement.
|
|
Return {
|
|
token: Token,
|
|
value: Option<ExprNode>,
|
|
},
|
|
}
|
|
|
|
impl StmtNode {
|
|
/// Extract the list of statements from a block. Panic if the statement
|
|
/// is not a block.
|
|
pub fn extract_block_statements(self) -> Vec<StmtNode> {
|
|
match self {
|
|
Self::Block(stmts) => stmts,
|
|
_ => panic!("Statement is not a block"),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A getter expression.
|
|
#[derive(Debug, Clone)]
|
|
pub struct GetExpr {
|
|
/// The instance being accessed.
|
|
pub instance: Box<ExprNode>,
|
|
/// The name of the property.
|
|
pub name: Token,
|
|
}
|
|
|
|
/// A setter expression.
|
|
#[derive(Debug, Clone)]
|
|
pub struct SetExpr {
|
|
/// The instance being accessed.
|
|
pub instance: Box<ExprNode>,
|
|
/// The name of the property.
|
|
pub name: Token,
|
|
/// The value to set
|
|
pub value: Box<ExprNode>,
|
|
}
|
|
|
|
/// A binary expression.
|
|
#[derive(Debug, Clone)]
|
|
pub struct BinaryExpr {
|
|
/// The left side expression
|
|
pub left: Box<ExprNode>,
|
|
/// The operator
|
|
pub operator: Token,
|
|
/// The right side expression
|
|
pub right: Box<ExprNode>,
|
|
}
|
|
|
|
/// A variable reference expression.
|
|
#[derive(Debug, Clone)]
|
|
pub struct VariableExpr {
|
|
/// The name of the variable, or the "this" keyword.
|
|
pub token: Token,
|
|
/// Identifier used for variable resolution.
|
|
pub id: usize,
|
|
}
|
|
|
|
/// An AST node that represents an expression.
|
|
#[derive(Debug, Clone)]
|
|
pub enum ExprNode {
|
|
/// Assignment to a variable.
|
|
Assignment {
|
|
name: Token,
|
|
value: Box<ExprNode>,
|
|
/// Identifier used for variable resolution.
|
|
id: usize,
|
|
},
|
|
|
|
/// Logical binary expression.
|
|
Logical(BinaryExpr),
|
|
|
|
/// Binary expression.
|
|
Binary(BinaryExpr),
|
|
|
|
/// Unary expression.
|
|
Unary {
|
|
operator: Token,
|
|
right: Box<ExprNode>,
|
|
},
|
|
|
|
/// Grouping expression, containing a sub-expression.
|
|
Grouping { expression: Box<ExprNode> },
|
|
|
|
/// A litteral value, represented by the corresponding token.
|
|
Litteral { value: Token },
|
|
|
|
/// A reference to a variable.
|
|
Variable(VariableExpr),
|
|
/// The "this" keyword.
|
|
This(VariableExpr),
|
|
|
|
/// A lambda function.
|
|
Lambda {
|
|
params: Vec<Token>,
|
|
body: Vec<StmtNode>,
|
|
},
|
|
|
|
/// A function call.
|
|
Call {
|
|
/// Expression that corresponds to the callable.
|
|
callee: Box<ExprNode>,
|
|
/// Right parenthesis that closes the list of arguments. Used to
|
|
/// report errors.
|
|
right_paren: Token,
|
|
/// The list of function arguments.
|
|
arguments: Vec<ExprNode>,
|
|
},
|
|
|
|
/// A get expression.
|
|
Get(GetExpr),
|
|
/// A set expression.
|
|
Set(SetExpr),
|
|
}
|