use crate::parser::{ProtoLineRange, ProtoSignature};
#[derive(Debug, Clone, PartialEq, Default)]
pub struct HirModule {
pub entry: HirProtoRef,
pub protos: Vec<HirProto>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirProto {
pub id: HirProtoRef,
pub source: Option<String>,
pub line_range: ProtoLineRange,
pub signature: ProtoSignature,
pub params: Vec<ParamId>,
pub param_debug_hints: Vec<Option<String>>,
pub locals: Vec<LocalId>,
pub local_debug_hints: Vec<Option<String>>,
pub upvalues: Vec<UpvalueId>,
pub upvalue_debug_hints: Vec<Option<String>>,
pub temps: Vec<TempId>,
pub temp_debug_locals: Vec<Option<String>>,
pub body: HirBlock,
pub children: Vec<HirProtoRef>,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct HirProtoRef(pub usize);
impl HirProtoRef {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct ParamId(pub usize);
impl ParamId {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct LocalId(pub usize);
impl LocalId {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct UpvalueId(pub usize);
impl UpvalueId {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct TempId(pub usize);
impl TempId {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct HirLabelId(pub usize);
impl HirLabelId {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct HirBlock {
pub stmts: Vec<HirStmt>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum HirStmt {
LocalDecl(Box<HirLocalDecl>),
Assign(Box<HirAssign>),
TableSetList(Box<HirTableSetList>),
ErrNil(Box<HirErrNil>),
ToBeClosed(Box<HirToBeClosed>),
Close(Box<HirClose>),
CallStmt(Box<HirCallStmt>),
Return(Box<HirReturn>),
If(Box<HirIf>),
While(Box<HirWhile>),
Repeat(Box<HirRepeat>),
NumericFor(Box<HirNumericFor>),
GenericFor(Box<HirGenericFor>),
Break,
Continue,
Goto(Box<HirGoto>),
Label(Box<HirLabel>),
Block(Box<HirBlock>),
Unstructured(Box<HirUnstructured>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum HirExpr {
Nil,
Boolean(bool),
Integer(i64),
Number(f64),
String(String),
Int64(i64),
UInt64(u64),
Complex { real: f64, imag: f64 },
ParamRef(ParamId),
LocalRef(LocalId),
UpvalueRef(UpvalueId),
TempRef(TempId),
GlobalRef(HirGlobalRef),
TableAccess(Box<HirTableAccess>),
Unary(Box<HirUnaryExpr>),
Binary(Box<HirBinaryExpr>),
LogicalAnd(Box<HirLogicalExpr>),
LogicalOr(Box<HirLogicalExpr>),
Decision(Box<HirDecisionExpr>),
Call(Box<HirCallExpr>),
VarArg,
TableConstructor(Box<HirTableConstructor>),
Closure(Box<HirClosureExpr>),
Unresolved(Box<HirUnresolvedExpr>),
}
impl HirExpr {
pub fn negate(self) -> Self {
match self {
HirExpr::Unary(unary) if unary.op == HirUnaryOpKind::Not => unary.expr,
expr => HirExpr::Unary(Box::new(HirUnaryExpr {
op: HirUnaryOpKind::Not,
expr,
})),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum HirLValue {
Temp(TempId),
Local(LocalId),
Upvalue(UpvalueId),
Global(HirGlobalRef),
TableAccess(Box<HirTableAccess>),
}
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct HirGlobalRef {
pub name: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirTableAccess {
pub base: HirExpr,
pub key: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirUnaryExpr {
pub op: HirUnaryOpKind,
pub expr: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirBinaryExpr {
pub op: HirBinaryOpKind,
pub lhs: HirExpr,
pub rhs: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirLogicalExpr {
pub lhs: HirExpr,
pub rhs: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirDecisionExpr {
pub entry: HirDecisionNodeRef,
pub nodes: Vec<HirDecisionNode>,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct HirDecisionNodeRef(pub usize);
impl HirDecisionNodeRef {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirDecisionNode {
pub id: HirDecisionNodeRef,
pub test: HirExpr,
pub truthy: HirDecisionTarget,
pub falsy: HirDecisionTarget,
}
#[derive(Debug, Clone, PartialEq)]
pub enum HirDecisionTarget {
Node(HirDecisionNodeRef),
CurrentValue,
Expr(HirExpr),
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum HirUnaryOpKind {
Not,
Neg,
BitNot,
Length,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum HirBinaryOpKind {
Add,
Sub,
Mul,
Div,
FloorDiv,
Mod,
Pow,
BitAnd,
BitOr,
BitXor,
Shl,
Shr,
Concat,
Eq,
Lt,
Le,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirCallExpr {
pub callee: HirExpr,
pub args: Vec<HirExpr>,
pub multiret: bool,
pub method: bool,
pub method_name: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirCallStmt {
pub call: HirCallExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirLocalDecl {
pub bindings: Vec<LocalId>,
pub values: Vec<HirExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirAssign {
pub targets: Vec<HirLValue>,
pub values: Vec<HirExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirTableSetList {
pub base: HirExpr,
pub start_index: u32,
pub values: Vec<HirExpr>,
pub trailing_multivalue: Option<HirExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirErrNil {
pub value: HirExpr,
pub name: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirToBeClosed {
pub reg_index: usize,
pub value: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirClose {
pub from_reg: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirReturn {
pub values: Vec<HirExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirIf {
pub cond: HirExpr,
pub then_block: HirBlock,
pub else_block: Option<HirBlock>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirWhile {
pub cond: HirExpr,
pub body: HirBlock,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirRepeat {
pub body: HirBlock,
pub cond: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirNumericFor {
pub binding: LocalId,
pub start: HirExpr,
pub limit: HirExpr,
pub step: HirExpr,
pub body: HirBlock,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirGenericFor {
pub bindings: Vec<LocalId>,
pub iterator: Vec<HirExpr>,
pub body: HirBlock,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirGoto {
pub target: HirLabelId,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirLabel {
pub id: HirLabelId,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirUnstructured {
pub body: HirBlock,
pub summary: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct HirTableConstructor {
pub fields: Vec<HirTableField>,
pub trailing_multivalue: Option<HirExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum HirTableField {
Array(HirExpr),
Record(HirRecordField),
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirRecordField {
pub key: HirTableKey,
pub value: HirExpr,
}
#[derive(Debug, Clone, PartialEq)]
pub enum HirTableKey {
Name(String),
Expr(HirExpr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirClosureExpr {
pub proto: HirProtoRef,
pub captures: Vec<HirCapture>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct HirCapture {
pub value: HirExpr,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HirUnresolvedExpr {
pub summary: String,
}