use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Const {
Int(i64),
Float(f64),
Str(String),
Name(String),
Names(Vec<String>),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum CaptureSrc {
Local(u16),
Upval(u16),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum Instr {
Const(u32),
Unit,
True,
False,
LoadLocal(u16),
StoreLocal(u16),
LoadUpval(u16),
LoadGlobal(u32),
StoreGlobal(u32),
NewCell,
CellGet,
CellSet,
MakeList(u16),
MakeTuple(u16),
MakeRecord(u32),
RecordUpdate(u32),
GetField(u32),
Index,
MakeVariantPos {
tag: u32,
count: u16,
},
MakeVariantNamed {
tag: u32,
names: u32,
},
MakeVariantUnit {
tag: u32,
},
Add,
Sub,
Mul,
Div,
Mod,
Pow,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
Neg,
Not,
MakeRange {
inclusive: bool,
},
Jump(u32),
JumpIfFalse(u32),
JumpIfFalsePeek(u32),
JumpIfTruePeek(u32),
MatchPat {
pat: u32,
fail: u32,
},
MakeClosure {
fn_id: u32,
captures: u32,
},
Call(u8),
TailCall(u8),
Invoke {
name: u32,
global: Option<u32>,
argc: u8,
},
Ret,
Deref,
Try,
Fault(u32),
Pop,
Dup,
IterNext {
iter: u16,
idx: u16,
end: u32,
},
Nop,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Pat {
Wildcard,
Bind(u16),
LitInt(i64),
LitFloat(f64),
LitStr(String),
LitBool(bool),
LitUnit,
VariantPos {
tag: String,
items: Vec<Pat>,
},
VariantNamed {
tag: String,
fields: Vec<(String, Pat)>,
rest: bool,
},
Record {
fields: Vec<(String, Pat)>,
rest: bool,
},
Tuple(Vec<Pat>),
List {
items: Vec<Pat>,
rest: Option<Option<u16>>,
},
Range {
lo: i64,
hi: i64,
inclusive: bool,
},
Or(Vec<Pat>),
As(Box<Pat>, u16),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FnProto {
pub name: String,
pub arity: u8,
pub num_locals: u16,
pub num_upvals: u16,
pub code: Vec<Instr>,
pub consts: Vec<Const>,
pub pats: Vec<Pat>,
pub lines: Vec<u32>,
pub closure_captures: Vec<Vec<CaptureSrc>>,
}
impl FnProto {
pub fn line_at(&self, ip: usize) -> u32 {
self.lines.get(ip).copied().unwrap_or(0)
}
}