pub mod command;
pub mod fmt;
pub mod mem;
use super::{ast, lexer};
pub use crate::{
syntax::SourcePos,
symbol::Symbol,
};
pub use command::{
ArgPart,
ArgUnit,
Argument,
BasicCommand,
Command,
CommandBlock,
CommandBlockKind,
Redirection,
RedirectionTarget,
};
#[derive(Debug, Default)]
pub struct Block(pub Box<[Statement]>);
impl From<Box<[Statement]>> for Block {
fn from(block: Box<[Statement]>) -> Self {
Self(block)
}
}
#[derive(Debug)]
pub enum Literal {
Nil,
Bool(bool),
Int(i64),
Float(f64),
Byte(u8),
String(Box<[u8]>),
Array(Box<[Expr]>),
Dict(Box<[(Symbol, Expr)]>),
Function {
params: u32,
frame_info: mem::FrameInfo,
body: Block,
},
Identifier(Symbol),
}
#[derive(Debug)]
pub enum UnaryOp {
Minus, Not, Try, }
impl UnaryOp {
pub fn is_postfix(&self) -> bool {
matches!(self, Self::Try)
}
}
impl From<ast::UnaryOp> for UnaryOp {
fn from(op: ast::UnaryOp) -> Self {
match op {
ast::UnaryOp::Minus => UnaryOp::Minus,
ast::UnaryOp::Not => UnaryOp::Not,
ast::UnaryOp::Try => UnaryOp::Try,
}
}
}
#[derive(Debug)]
pub enum BinaryOp {
Plus, Minus, Times, Div, Mod,
Equals, NotEquals, Greater, GreaterEquals, Lower, LowerEquals,
And, Or,
Concat, }
impl From<ast::BinaryOp> for BinaryOp {
fn from(op: ast::BinaryOp) -> Self {
match op {
ast::BinaryOp::Plus => BinaryOp::Plus,
ast::BinaryOp::Minus => BinaryOp::Minus,
ast::BinaryOp::Times => BinaryOp::Times,
ast::BinaryOp::Div => BinaryOp::Div,
ast::BinaryOp::Mod => BinaryOp::Mod,
ast::BinaryOp::Equals => BinaryOp::Equals,
ast::BinaryOp::NotEquals => BinaryOp::NotEquals,
ast::BinaryOp::Greater => BinaryOp::Greater,
ast::BinaryOp::GreaterEquals => BinaryOp::GreaterEquals,
ast::BinaryOp::Lower => BinaryOp::Lower,
ast::BinaryOp::LowerEquals => BinaryOp::LowerEquals,
ast::BinaryOp::And => BinaryOp::And,
ast::BinaryOp::Or => BinaryOp::Or,
ast::BinaryOp::Concat => BinaryOp::Concat,
}
}
}
#[derive(Debug)]
pub enum Expr {
Identifier {
slot_ix: mem::SlotIx,
pos: SourcePos,
},
Literal {
literal: Literal,
pos: SourcePos,
},
UnaryOp {
op: UnaryOp,
operand: Box<Expr>,
pos: SourcePos,
},
BinaryOp {
left: Box<Expr>,
op: BinaryOp,
right: Box<Expr>,
pos: SourcePos,
},
If {
condition: Box<Expr>,
then: Block,
otherwise: Block,
pos: SourcePos,
},
Access {
object: Box<Expr>,
field: Box<Expr>,
pos: SourcePos,
},
Call {
function: Box<Expr>,
args: Box<[Expr]>,
pos: SourcePos,
},
CommandBlock {
block: CommandBlock,
pos: SourcePos,
},
}
#[derive(Debug)]
pub enum Lvalue {
Identifier {
slot_ix: mem::SlotIx,
pos: SourcePos,
},
Access {
object: Box<Expr>,
field: Box<Expr>,
pos: SourcePos,
},
}
#[derive(Debug)]
pub enum Statement {
Assign {
left: Lvalue,
right: Expr,
},
Return {
expr: Expr,
},
Break,
While {
condition: Expr,
block: Block,
},
For {
slot_ix: mem::SlotIx,
expr: Expr,
block: Block,
},
Expr(Expr),
}
#[derive(Debug)]
pub struct Program {
pub source: Symbol,
pub statements: Block,
pub root_slots: mem::SlotIx,
}