use crate::core::source::Span;
use crate::program::shared::ModifyOp;
use super::{ActionId, GlobalVarId, PlayerVarId, SubroutineId, ValueId};
#[derive(Debug, Clone)]
pub(crate) enum Action {
SetGlobalVariable {
variable: GlobalVarId,
value: ValueId,
span: Option<Span>,
target_span: Option<Span>,
},
ModifyGlobalVariable {
variable: GlobalVarId,
op: ModifyOp,
value: ValueId,
span: Option<Span>,
target_span: Option<Span>,
},
SetPlayerVariable {
player: ValueId,
variable: PlayerVarId,
value: ValueId,
span: Option<Span>,
target_span: Option<Span>,
},
ModifyPlayerVariable {
player: ValueId,
variable: PlayerVarId,
op: ModifyOp,
value: ValueId,
span: Option<Span>,
target_span: Option<Span>,
},
AssignMember {
target: ValueId,
op: Option<ModifyOp>,
value: ValueId,
span: Option<Span>,
},
CallSubroutine {
subroutine: SubroutineId,
span: Option<Span>,
callee_span: Option<Span>,
},
If {
branches: Vec<IfBranch>,
else_body: Option<Vec<ActionId>>,
span: Option<Span>,
},
While {
condition: ValueId,
body: Vec<ActionId>,
span: Option<Span>,
},
ForGlobalVariable {
variable: GlobalVarId,
start: ValueId,
stop: ValueId,
step: ValueId,
body: Vec<ActionId>,
span: Option<Span>,
target_span: Option<Span>,
},
ForPlayerVariable {
player: ValueId,
variable: PlayerVarId,
start: ValueId,
stop: ValueId,
step: ValueId,
body: Vec<ActionId>,
span: Option<Span>,
target_span: Option<Span>,
},
Disabled {
action: ActionId,
span: Option<Span>,
},
Call {
name: String,
args: Vec<ValueId>,
span: Option<Span>,
},
}
impl Action {
pub(crate) fn span(&self) -> Option<Span> {
match self {
Action::SetGlobalVariable { span, .. }
| Action::ModifyGlobalVariable { span, .. }
| Action::SetPlayerVariable { span, .. }
| Action::ModifyPlayerVariable { span, .. }
| Action::AssignMember { span, .. }
| Action::CallSubroutine { span, .. }
| Action::If { span, .. }
| Action::While { span, .. }
| Action::ForGlobalVariable { span, .. }
| Action::ForPlayerVariable { span, .. }
| Action::Disabled { span, .. }
| Action::Call { span, .. } => *span,
}
}
pub(crate) fn modify_op(&self) -> Option<ModifyOp> {
match self {
Action::ModifyGlobalVariable { op, .. } | Action::ModifyPlayerVariable { op, .. } => {
Some(*op)
}
Action::AssignMember { op, .. } => *op,
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub(crate) struct IfBranch {
pub(crate) condition: ValueId,
pub(crate) body: Vec<ActionId>,
}