able-script/src/ast.rs

150 lines
3.1 KiB
Rust
Raw Normal View History

//! AbleScript's Abstract Syntax tree
//!
//! Statements are the type which is AST made of, as they
//! express an effect.
//!
//! Expressions are just operations and they cannot be
//! used as statements. Functions in AbleScript are in fact
//! just plain subroutines and they do not return any value,
//! so their calls are statements.
2021-06-06 14:09:18 -05:00
use crate::variables::Value;
type Span = std::ops::Range<usize>;
#[derive(Debug, PartialEq, Clone)]
pub struct Iden {
pub iden: String,
pub span: Span,
}
2021-06-06 14:09:18 -05:00
impl Iden {
pub fn new(iden: String, span: Span) -> Self {
Self { iden, span }
}
}
#[derive(Debug, PartialEq, Clone)]
2021-06-06 14:09:18 -05:00
pub struct Block {
pub block: Vec<Stmt>,
}
/// A syntactic unit expressing an effect.
#[derive(Debug, PartialEq, Clone)]
2021-06-06 14:09:18 -05:00
pub struct Stmt {
pub kind: StmtKind,
pub span: Span,
}
#[derive(Debug, PartialEq, Clone)]
2021-06-06 14:09:18 -05:00
pub enum StmtKind {
// Control flow
If {
cond: Expr,
body: Block,
},
Loop {
body: Block,
},
Break,
HopBack,
Var {
iden: Iden,
init: Option<Expr>,
},
Assign {
iden: Iden,
value: Expr,
},
2021-06-06 14:09:18 -05:00
Functio {
iden: Iden,
params: Vec<Iden>,
2021-06-06 14:09:18 -05:00
body: Block,
},
2021-06-11 10:52:47 -05:00
BfFunctio {
iden: Iden,
tape_len: Option<Expr>,
2021-06-11 11:10:11 -05:00
code: Vec<u8>,
2021-06-11 10:52:47 -05:00
},
2021-06-06 14:09:18 -05:00
Call {
iden: Iden,
// NOTE(Alex): Function arguments are Iden's, not Expr's,
// because they're passed by reference rather than by value
// and therefore need to be assignable.
args: Vec<Iden>,
2021-06-06 14:09:18 -05:00
},
Print(Expr),
Melo(Iden),
2021-06-07 04:07:50 -05:00
Rlyeh,
2021-06-13 20:40:42 -05:00
Rickroll,
2021-06-06 14:09:18 -05:00
}
impl Stmt {
pub fn new(kind: StmtKind, span: Span) -> Self {
Self { kind, span }
}
}
/// Expression is parse unit which do not cause any effect,
/// like math and logical operations or values.
#[derive(Debug, PartialEq, Clone)]
2021-06-06 14:09:18 -05:00
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
2021-06-06 14:09:18 -05:00
}
#[derive(Debug, PartialEq, Clone)]
2021-06-06 14:09:18 -05:00
pub enum ExprKind {
BinOp {
2021-06-06 14:09:18 -05:00
lhs: Box<Expr>,
rhs: Box<Expr>,
kind: BinOpKind,
},
Not(Box<Expr>),
Literal(Value),
Variable(String),
2021-06-06 14:09:18 -05:00
}
impl Expr {
pub fn new(kind: ExprKind, span: Span) -> Self {
Self { kind, span }
}
}
#[derive(Debug, PartialEq, Clone)]
2021-06-06 14:09:18 -05:00
pub enum BinOpKind {
Add,
Subtract,
Multiply,
Divide,
Greater,
Less,
Equal,
NotEqual,
And,
Or,
}
2021-06-07 02:17:18 -05:00
impl BinOpKind {
pub fn from_token(t: crate::lexer::Token) -> Result<Self, crate::error::ErrorKind> {
use crate::lexer::Token;
match t {
Token::Plus => Ok(Self::Add),
Token::Minus => Ok(Self::Subtract),
Token::Star => Ok(Self::Multiply),
Token::FwdSlash => Ok(Self::Divide),
Token::GreaterThan => Ok(Self::Greater),
Token::LessThan => Ok(Self::Less),
Token::EqualEqual => Ok(Self::Equal),
Token::NotEqual => Ok(Self::NotEqual),
Token::And => Ok(Self::And),
Token::Or => Ok(Self::Or),
t => Err(crate::error::ErrorKind::UnexpectedToken(t)),
2021-06-07 02:17:18 -05:00
}
}
}