use crate::{
interner::{Symbol, TypeNodeId},
types::TypeSize,
};
use std::{cell::OnceCell, sync::Arc};
pub mod print;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Argument(pub Symbol, pub TypeNodeId);
pub type VReg = u64;
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum Value {
Global(VPtr),
Argument(usize, Arc<Argument>), Register(VReg),
State(VPtr),
Function(usize),
ExtFunction(Symbol, TypeNodeId),
None,
}
pub type VPtr = Arc<Value>;
#[derive(Debug, Clone, PartialEq)]
pub enum Instruction {
Uinteger(u64),
Integer(i64),
Float(f64),
String(Symbol),
Alloc(TypeNodeId),
Load(VPtr, TypeNodeId),
Store(VPtr, VPtr, TypeNodeId),
GetElement {
value: VPtr,
ty: TypeNodeId,
array_idx: u64,
tuple_offset: u64,
},
Call(VPtr, Vec<(VPtr, TypeNodeId)>, TypeNodeId),
CallCls(VPtr, Vec<(VPtr, TypeNodeId)>, TypeNodeId),
GetGlobal(VPtr, TypeNodeId),
SetGlobal(VPtr, VPtr, TypeNodeId),
Closure(VPtr),
CloseUpValues(VPtr, TypeNodeId),
GetUpValue(u64, TypeNodeId),
SetUpValue(u64, VPtr, TypeNodeId),
PushStateOffset(Vec<StateSize>),
PopStateOffset(Vec<StateSize>),
GetState(TypeNodeId),
JmpIf(VPtr, u64, u64, u64),
Jmp(i16),
Phi(VPtr, VPtr),
Return(VPtr, TypeNodeId),
ReturnFeed(VPtr, TypeNodeId),
Delay(u64, VPtr, VPtr),
Mem(VPtr),
AddF(VPtr, VPtr),
SubF(VPtr, VPtr),
MulF(VPtr, VPtr),
DivF(VPtr, VPtr),
ModF(VPtr, VPtr),
NegF(VPtr),
AbsF(VPtr),
SinF(VPtr),
CosF(VPtr),
PowF(VPtr, VPtr),
LogF(VPtr),
SqrtF(VPtr),
AddI(VPtr, VPtr),
SubI(VPtr, VPtr),
MulI(VPtr, VPtr),
DivI(VPtr, VPtr),
ModI(VPtr, VPtr),
NegI(VPtr),
AbsI(VPtr),
PowI(VPtr),
LogI(VPtr, VPtr),
Not(VPtr),
Eq(VPtr, VPtr),
Ne(VPtr, VPtr),
Gt(VPtr, VPtr),
Ge(VPtr, VPtr),
Lt(VPtr, VPtr),
Le(VPtr, VPtr),
And(VPtr, VPtr),
Or(VPtr, VPtr),
CastFtoI(VPtr),
CastItoF(VPtr),
CastItoB(VPtr),
Error,
}
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Block(pub Vec<(VPtr, Instruction)>);
#[derive(Debug, Clone, PartialEq)]
pub enum UpIndex {
Local(usize), Upvalue(usize), }
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct OpenUpValue {
pub pos: usize,
pub size: TypeSize,
pub is_closure: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Function {
pub index: usize,
pub label: Symbol,
pub args: Vec<Arc<Value>>,
pub argtypes: Vec<TypeNodeId>,
pub return_type: OnceCell<TypeNodeId>, pub upindexes: Vec<Arc<Value>>,
pub upperfn_i: Option<usize>,
pub body: Vec<Block>,
pub state_sizes: Vec<StateSize>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct StateSize {
pub size: u64,
pub ty: TypeNodeId,
}
impl Function {
pub fn new(
index: usize,
name: Symbol,
args: &[VPtr],
argtypes: &[TypeNodeId],
upperfn_i: Option<usize>,
) -> Self {
Self {
index,
label: name,
args: args.to_vec(),
argtypes: argtypes.to_vec(),
return_type: OnceCell::new(),
upindexes: vec![],
upperfn_i,
body: vec![Block::default()],
state_sizes: vec![],
}
}
pub fn add_new_basicblock(&mut self) -> usize {
self.body.push(Block(vec![]));
self.body.len() - 1
}
pub fn get_or_insert_upvalue(&mut self, v: &Arc<Value>) -> usize {
self.upindexes
.iter()
.position(|vt| v == vt)
.unwrap_or_else(|| {
self.upindexes.push(v.clone());
self.upindexes.len() - 1
})
}
}
#[derive(Debug, Clone, Default)]
pub struct Mir {
pub functions: Vec<Function>,
pub file_path: Option<Symbol>,
}
impl Mir {
pub fn new(file_path: Option<Symbol>) -> Self {
Self {
file_path,
..Default::default()
}
}
}