2024-01-27 11:55:54 +00:00
|
|
|
// Based on a cfg
|
|
|
|
|
2024-02-17 20:31:15 +00:00
|
|
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
2024-01-30 17:05:14 +00:00
|
|
|
|
2024-01-27 11:55:54 +00:00
|
|
|
use edlang_span::Span;
|
|
|
|
use smallvec::SmallVec;
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
pub mod scalar_int;
|
|
|
|
|
2024-02-08 10:58:10 +00:00
|
|
|
#[derive(Debug, Clone, Default)]
|
|
|
|
pub struct SymbolTable {
|
|
|
|
pub symbols: BTreeMap<DefId, String>,
|
|
|
|
pub modules: BTreeMap<String, DefId>,
|
|
|
|
pub functions: BTreeMap<String, DefId>,
|
|
|
|
pub constants: BTreeMap<String, DefId>,
|
|
|
|
pub structs: BTreeMap<String, DefId>,
|
|
|
|
pub types: BTreeMap<String, DefId>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Default)]
|
|
|
|
pub struct ProgramBody {
|
|
|
|
pub top_level_module_names: BTreeMap<String, DefId>,
|
|
|
|
/// The top level modules.
|
|
|
|
pub top_level_modules: Vec<DefId>,
|
|
|
|
/// All the modules in a flat map.
|
|
|
|
pub modules: BTreeMap<DefId, ModuleBody>,
|
|
|
|
/// This stores all the functions from all modules
|
|
|
|
pub functions: BTreeMap<DefId, Body>,
|
2024-02-17 17:41:33 +00:00
|
|
|
pub structs: BTreeMap<DefId, AdtBody>,
|
2024-02-08 10:58:10 +00:00
|
|
|
/// The function signatures.
|
|
|
|
pub function_signatures: BTreeMap<DefId, (Vec<TypeInfo>, TypeInfo)>,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ModuleBody {
|
2024-02-03 13:33:42 +00:00
|
|
|
pub module_id: DefId,
|
2024-02-08 10:58:10 +00:00
|
|
|
pub parent_ids: Vec<DefId>,
|
|
|
|
pub name: String,
|
|
|
|
pub symbols: SymbolTable,
|
|
|
|
/// Functions defined in this module.
|
|
|
|
pub functions: HashSet<DefId>,
|
|
|
|
/// Structs defined in this module.
|
|
|
|
pub structs: HashSet<DefId>,
|
|
|
|
/// Types defined in this module.
|
|
|
|
pub types: HashSet<DefId>,
|
|
|
|
/// Constants defined in this module.
|
|
|
|
pub constants: HashSet<DefId>,
|
|
|
|
/// Submodules defined in this module.
|
|
|
|
pub modules: HashSet<DefId>,
|
|
|
|
/// Imported items. symbol -> id
|
|
|
|
pub imports: BTreeMap<String, DefId>,
|
2024-01-30 17:05:14 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Definition id.
|
2024-02-03 13:33:42 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
2024-01-30 17:05:14 +00:00
|
|
|
pub struct DefId {
|
2024-02-08 10:58:10 +00:00
|
|
|
pub program_id: usize,
|
2024-01-30 17:05:14 +00:00
|
|
|
pub id: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct Body {
|
2024-01-30 17:05:14 +00:00
|
|
|
pub def_id: DefId,
|
|
|
|
pub is_pub: bool,
|
|
|
|
pub is_extern: bool,
|
2024-02-08 10:58:10 +00:00
|
|
|
pub name: String,
|
2024-01-27 11:55:54 +00:00
|
|
|
pub locals: SmallVec<[Local; 4]>,
|
|
|
|
pub blocks: SmallVec<[BasicBlock; 8]>,
|
2024-01-30 17:05:14 +00:00
|
|
|
pub fn_span: Span,
|
2024-01-27 11:55:54 +00:00
|
|
|
}
|
|
|
|
|
2024-02-03 19:14:29 +00:00
|
|
|
impl Body {
|
|
|
|
pub fn get_args(&self) -> SmallVec<[Local; 4]> {
|
|
|
|
let mut args = SmallVec::default();
|
|
|
|
|
|
|
|
for x in &self.locals {
|
|
|
|
if let LocalKind::Arg = x.kind {
|
|
|
|
args.push(x.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
args
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_return_local(&self) -> Local {
|
|
|
|
self.locals[0].clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-17 17:41:33 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct AdtBody {
|
|
|
|
pub def_id: DefId,
|
|
|
|
pub is_pub: bool,
|
|
|
|
pub name: String,
|
|
|
|
pub variants: Vec<AdtVariant>,
|
2024-02-17 20:31:15 +00:00
|
|
|
pub name_to_idx: HashMap<String, usize>,
|
2024-02-17 17:41:33 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// struct field or enum variant
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct AdtVariant {
|
|
|
|
pub def_id: DefId,
|
|
|
|
pub name: String,
|
|
|
|
pub ty: TypeInfo,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct DebugInfo {
|
|
|
|
pub id: usize,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct BasicBlock {
|
|
|
|
pub statements: SmallVec<[Statement; 8]>,
|
|
|
|
pub terminator: Terminator,
|
2024-02-14 10:21:33 +00:00
|
|
|
pub terminator_span: Option<Span>,
|
2024-01-27 11:55:54 +00:00
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct Local {
|
|
|
|
pub mutable: bool,
|
2024-01-30 17:05:14 +00:00
|
|
|
pub span: Option<Span>,
|
2024-02-08 10:58:10 +00:00
|
|
|
pub debug_name: Option<String>,
|
2024-01-30 17:05:14 +00:00
|
|
|
pub ty: TypeInfo,
|
2024-01-27 11:55:54 +00:00
|
|
|
pub kind: LocalKind,
|
|
|
|
}
|
|
|
|
|
2024-02-08 10:58:10 +00:00
|
|
|
impl Local {
|
|
|
|
pub fn new(
|
|
|
|
span: Option<Span>,
|
|
|
|
kind: LocalKind,
|
|
|
|
ty: TypeInfo,
|
|
|
|
debug_name: Option<String>,
|
|
|
|
mutable: bool,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
span,
|
|
|
|
kind,
|
|
|
|
ty,
|
|
|
|
debug_name,
|
|
|
|
mutable,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-14 09:13:28 +00:00
|
|
|
pub const fn temp(ty: TypeKind) -> Self {
|
2024-02-08 10:58:10 +00:00
|
|
|
Self {
|
|
|
|
span: None,
|
2024-02-14 09:13:28 +00:00
|
|
|
ty: TypeInfo {
|
|
|
|
span: None,
|
|
|
|
kind: ty,
|
|
|
|
},
|
2024-02-08 10:58:10 +00:00
|
|
|
kind: LocalKind::Temp,
|
|
|
|
debug_name: None,
|
|
|
|
mutable: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone, Copy)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum LocalKind {
|
|
|
|
Temp,
|
|
|
|
Arg,
|
|
|
|
ReturnPointer,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct Statement {
|
2024-01-30 17:05:14 +00:00
|
|
|
pub span: Option<Span>,
|
2024-01-27 11:55:54 +00:00
|
|
|
pub kind: StatementKind,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum StatementKind {
|
|
|
|
Assign(Place, RValue),
|
|
|
|
StorageLive(usize),
|
|
|
|
StorageDead(usize),
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum Terminator {
|
|
|
|
Target(usize),
|
|
|
|
Return,
|
2024-02-12 11:09:40 +00:00
|
|
|
SwitchInt {
|
|
|
|
discriminator: Operand,
|
|
|
|
targets: SwitchTarget,
|
|
|
|
},
|
2024-01-27 11:55:54 +00:00
|
|
|
Call {
|
2024-02-08 10:58:10 +00:00
|
|
|
/// The function to call.
|
|
|
|
func: DefId,
|
|
|
|
/// The arguments.
|
|
|
|
args: Vec<RValue>,
|
|
|
|
/// The place in memory to store the return value of the function call.
|
|
|
|
destination: Place,
|
|
|
|
/// What basic block to jump to after the function call, if the function is non-diverging (i.e it returns control back).
|
|
|
|
target: Option<usize>,
|
2024-01-27 11:55:54 +00:00
|
|
|
},
|
|
|
|
Unreachable,
|
|
|
|
}
|
|
|
|
|
2024-02-12 11:09:40 +00:00
|
|
|
/// Used for ifs, match
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct SwitchTarget {
|
|
|
|
pub values: Vec<ValueTree>,
|
|
|
|
pub targets: Vec<usize>,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct TypeInfo {
|
2024-01-30 17:05:14 +00:00
|
|
|
pub span: Option<Span>,
|
2024-01-27 11:55:54 +00:00
|
|
|
pub kind: TypeKind,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum TypeKind {
|
2024-02-03 11:06:16 +00:00
|
|
|
Unit,
|
2024-01-27 11:55:54 +00:00
|
|
|
Bool,
|
|
|
|
Char,
|
|
|
|
Int(IntTy),
|
|
|
|
Uint(UintTy),
|
2024-01-30 17:05:14 +00:00
|
|
|
Float(FloatTy),
|
2024-02-03 11:06:16 +00:00
|
|
|
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
2024-02-14 10:21:33 +00:00
|
|
|
Ptr(Box<TypeInfo>),
|
2024-02-17 11:37:28 +00:00
|
|
|
Ref(bool, Box<TypeInfo>),
|
2024-02-18 08:58:58 +00:00
|
|
|
Struct(DefId), // todo, add generics
|
2024-01-27 11:55:54 +00:00
|
|
|
}
|
|
|
|
|
2024-02-03 13:33:42 +00:00
|
|
|
impl TypeKind {
|
2024-02-17 16:19:36 +00:00
|
|
|
pub const fn is_unit(&self) -> bool {
|
2024-02-04 16:27:06 +00:00
|
|
|
matches!(self, Self::Unit)
|
|
|
|
}
|
|
|
|
|
2024-02-17 16:19:36 +00:00
|
|
|
pub const fn is_integer(&self) -> bool {
|
|
|
|
matches!(self, Self::Int(_) | Self::Uint(_))
|
|
|
|
}
|
|
|
|
|
2024-02-03 13:33:42 +00:00
|
|
|
pub fn get_falsy_value(&self) -> ValueTree {
|
|
|
|
match self {
|
|
|
|
Self::Bool => ValueTree::Leaf(ConstValue::Bool(false)),
|
|
|
|
Self::Char => todo!(),
|
|
|
|
Self::Int(ty) => match ty {
|
|
|
|
IntTy::I8 => ValueTree::Leaf(ConstValue::I8(0)),
|
|
|
|
IntTy::I16 => ValueTree::Leaf(ConstValue::I16(0)),
|
|
|
|
IntTy::I32 => ValueTree::Leaf(ConstValue::I32(0)),
|
|
|
|
IntTy::I64 => ValueTree::Leaf(ConstValue::I64(0)),
|
|
|
|
IntTy::I128 => ValueTree::Leaf(ConstValue::I128(0)),
|
|
|
|
IntTy::Isize => todo!(),
|
|
|
|
},
|
|
|
|
Self::Uint(ty) => match ty {
|
|
|
|
UintTy::U8 => ValueTree::Leaf(ConstValue::U8(0)),
|
|
|
|
UintTy::U16 => ValueTree::Leaf(ConstValue::U16(0)),
|
|
|
|
UintTy::U32 => ValueTree::Leaf(ConstValue::U32(0)),
|
|
|
|
UintTy::U64 => ValueTree::Leaf(ConstValue::U64(0)),
|
|
|
|
UintTy::U128 => ValueTree::Leaf(ConstValue::U128(0)),
|
|
|
|
UintTy::Usize => todo!(),
|
|
|
|
},
|
|
|
|
Self::Float(_) => todo!(),
|
|
|
|
TypeKind::Unit => unreachable!(),
|
|
|
|
TypeKind::FnDef(_, _) => unreachable!(),
|
2024-02-14 10:21:33 +00:00
|
|
|
TypeKind::Ptr(_pointee) => todo!(),
|
2024-02-17 11:37:28 +00:00
|
|
|
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
2024-02-17 17:41:33 +00:00
|
|
|
TypeKind::Struct(_) => todo!(),
|
2024-02-03 13:33:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum IntTy {
|
|
|
|
I128,
|
|
|
|
I64,
|
|
|
|
I32,
|
|
|
|
I16,
|
|
|
|
I8,
|
|
|
|
Isize,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum UintTy {
|
|
|
|
U128,
|
|
|
|
U64,
|
|
|
|
U32,
|
|
|
|
U16,
|
|
|
|
U8,
|
|
|
|
Usize,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum FloatTy {
|
2024-01-27 11:55:54 +00:00
|
|
|
F32,
|
|
|
|
F64,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct ConstData {
|
2024-01-30 17:05:14 +00:00
|
|
|
pub span: Option<Span>,
|
|
|
|
pub type_info: TypeInfo,
|
2024-01-27 11:55:54 +00:00
|
|
|
pub kind: ConstKind,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum ConstKind {
|
|
|
|
Value(ValueTree),
|
2024-02-03 11:06:16 +00:00
|
|
|
ZeroSized,
|
2024-01-27 11:55:54 +00:00
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum ValueTree {
|
2024-01-30 17:05:14 +00:00
|
|
|
Leaf(ConstValue),
|
2024-01-27 11:55:54 +00:00
|
|
|
Branch(Vec<Self>),
|
|
|
|
}
|
|
|
|
|
2024-02-12 11:09:40 +00:00
|
|
|
impl ValueTree {
|
|
|
|
pub fn get_type(&self) -> TypeKind {
|
|
|
|
match self {
|
|
|
|
ValueTree::Leaf(value) => match value {
|
|
|
|
ConstValue::Bool(_) => TypeKind::Bool,
|
|
|
|
ConstValue::I8(_) => TypeKind::Int(IntTy::I8),
|
|
|
|
ConstValue::I16(_) => TypeKind::Int(IntTy::I16),
|
|
|
|
ConstValue::I32(_) => TypeKind::Int(IntTy::I32),
|
|
|
|
ConstValue::I64(_) => TypeKind::Int(IntTy::I64),
|
|
|
|
ConstValue::I128(_) => TypeKind::Int(IntTy::I128),
|
|
|
|
ConstValue::U8(_) => TypeKind::Uint(UintTy::U8),
|
|
|
|
ConstValue::U16(_) => TypeKind::Uint(UintTy::U16),
|
|
|
|
ConstValue::U32(_) => TypeKind::Uint(UintTy::U32),
|
|
|
|
ConstValue::U64(_) => TypeKind::Uint(UintTy::U64),
|
|
|
|
ConstValue::U128(_) => TypeKind::Uint(UintTy::U8),
|
|
|
|
ConstValue::F32(_) => TypeKind::Float(FloatTy::F32),
|
|
|
|
ConstValue::F64(_) => TypeKind::Float(FloatTy::F64),
|
2024-02-14 10:21:33 +00:00
|
|
|
ConstValue::Char(_) => TypeKind::Char,
|
2024-02-12 11:09:40 +00:00
|
|
|
},
|
|
|
|
ValueTree::Branch(_) => todo!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum RValue {
|
|
|
|
Use(Operand),
|
2024-02-03 13:33:42 +00:00
|
|
|
Ref(bool, Operand),
|
2024-01-27 11:55:54 +00:00
|
|
|
BinOp(BinOp, Operand, Operand),
|
2024-02-03 13:33:42 +00:00
|
|
|
LogicOp(LogicalOp, Operand, Operand),
|
2024-01-27 11:55:54 +00:00
|
|
|
UnOp(UnOp, Operand),
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum Operand {
|
|
|
|
Copy(Place),
|
|
|
|
Move(Place),
|
|
|
|
Constant(ConstData),
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub struct Place {
|
|
|
|
pub local: usize,
|
|
|
|
pub projection: SmallVec<[PlaceElem; 1]>,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone, Copy)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum PlaceElem {
|
|
|
|
Deref,
|
2024-02-17 20:31:15 +00:00
|
|
|
Field { field_idx: usize },
|
2024-01-27 11:55:54 +00:00
|
|
|
Index { local: usize },
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TypeKind {
|
|
|
|
pub fn get_i128() -> Self {
|
|
|
|
Self::Int(IntTy::I128)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_i64() -> Self {
|
|
|
|
Self::Int(IntTy::I64)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_i32() -> Self {
|
|
|
|
Self::Int(IntTy::I32)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_i16() -> Self {
|
|
|
|
Self::Int(IntTy::I16)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_i8() -> Self {
|
|
|
|
Self::Int(IntTy::I8)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_u128() -> Self {
|
|
|
|
Self::Uint(UintTy::U128)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_u64() -> Self {
|
|
|
|
Self::Uint(UintTy::U64)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_u32() -> Self {
|
|
|
|
Self::Uint(UintTy::U32)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_u16() -> Self {
|
|
|
|
Self::Uint(UintTy::U16)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_u8() -> Self {
|
|
|
|
Self::Uint(UintTy::U8)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_f32() -> Self {
|
2024-01-30 17:05:14 +00:00
|
|
|
Self::Float(FloatTy::F32)
|
2024-01-27 11:55:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_f64() -> Self {
|
2024-01-30 17:05:14 +00:00
|
|
|
Self::Float(FloatTy::F64)
|
2024-01-27 11:55:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_bool() -> Self {
|
|
|
|
Self::Bool
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_char() -> Self {
|
|
|
|
Self::Char
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone, Copy)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum BinOp {
|
|
|
|
Add,
|
|
|
|
Sub,
|
|
|
|
Mul,
|
|
|
|
Div,
|
|
|
|
Rem,
|
|
|
|
BitXor,
|
|
|
|
BitAnd,
|
|
|
|
BitOr,
|
|
|
|
Shl,
|
|
|
|
Shr,
|
|
|
|
Eq,
|
|
|
|
Lt,
|
|
|
|
Le,
|
|
|
|
Ne,
|
|
|
|
Ge,
|
|
|
|
Gt,
|
|
|
|
Offset,
|
|
|
|
}
|
|
|
|
|
2024-02-03 13:33:42 +00:00
|
|
|
// Diferent than BinOp because operands needs to be lazily evaluated.
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub enum LogicalOp {
|
|
|
|
And,
|
|
|
|
Or,
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:05:14 +00:00
|
|
|
#[derive(Debug, Clone, Copy)]
|
2024-01-27 11:55:54 +00:00
|
|
|
pub enum UnOp {
|
|
|
|
Not,
|
|
|
|
Neg,
|
|
|
|
}
|
2024-01-30 17:05:14 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub enum ConstValue {
|
|
|
|
Bool(bool),
|
2024-02-14 10:21:33 +00:00
|
|
|
Char(char),
|
2024-01-30 17:05:14 +00:00
|
|
|
I8(i8),
|
|
|
|
I16(i16),
|
|
|
|
I32(i32),
|
|
|
|
I64(i64),
|
|
|
|
I128(i128),
|
|
|
|
U8(u8),
|
|
|
|
U16(u16),
|
|
|
|
U32(u32),
|
|
|
|
U64(u64),
|
|
|
|
U128(u128),
|
|
|
|
F32(f32),
|
|
|
|
F64(f64),
|
|
|
|
}
|