Something went wrong. Try again.
An experiment in static, refcounted, procedural language with ownership
Something went wrong. Try again.
6.9 kB · 322 lines
Rust
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323use core::fmt;
use compiler_data_structures::index_vec::Key as _;use compiler_helpers::create_bool_enum;use ustr::Ustr;
use crate::{ db::DefId, span::{Span, Spanned}, ty::Ty, word::Word,};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]pub enum Vis { #[default] Private = 0, Public = 1,}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]pub enum Mutability { Imm, Mut,}
impl Mutability { pub fn is_imm(self) -> bool { matches!(self, Mutability::Imm) }
pub fn is_mut(self) -> bool { matches!(self, Mutability::Mut) }
pub fn as_str(self) -> &'static str { match self { Mutability::Imm => "imm", Mutability::Mut => "mut", } }}
impl Default for Mutability { fn default() -> Self { Self::Imm }}
impl fmt::Display for Mutability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) }}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum BinOp { Add, Sub, Mul, Div, Rem, Shl, Shr, BitAnd, BitOr, BitXor, And, Or, Cmp(CmpOp),}
impl BinOp { pub fn as_str(self) -> &'static str { match self { Self::Add => "+", Self::Sub => "-", Self::Mul => "*", Self::Div => "/", Self::Rem => "%", Self::Shl => "<<", Self::Shr => ">>", Self::BitAnd => "&", Self::BitOr => "|", Self::BitXor => "^", Self::And => "&&", Self::Or => "||", Self::Cmp(CmpOp::Eq) => "==", Self::Cmp(CmpOp::Ne) => "!=", Self::Cmp(CmpOp::Lt) => "<", Self::Cmp(CmpOp::Le) => "<=", Self::Cmp(CmpOp::Gt) => ">", Self::Cmp(CmpOp::Ge) => ">=", } }
#[allow(unused)] pub fn name(self) -> &'static str { match self { Self::Add => "add", Self::Sub => "sub", Self::Mul => "mul", Self::Div => "div", Self::Rem => "mod", Self::Shl => "shl", Self::Shr => "shr", Self::BitAnd => "bitand", Self::BitOr => "bitor", Self::BitXor => "bitxor", Self::And => "and", Self::Or => "or", Self::Cmp(CmpOp::Eq) => "eq", Self::Cmp(CmpOp::Ne) => "ne", Self::Cmp(CmpOp::Lt) => "lt", Self::Cmp(CmpOp::Le) => "le", Self::Cmp(CmpOp::Gt) => "gt", Self::Cmp(CmpOp::Ge) => "ge", } }
pub fn precedence(self) -> usize { match self { Self::Mul | Self::Div | Self::Rem => 7, Self::Add | Self::Sub => 6, Self::Shl | Self::Shr => 5, Self::BitAnd | Self::BitXor | Self::BitOr => 4, Self::Cmp(..) => 3, Self::And => 2, Self::Or => 1, } }}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum CmpOp { Eq, Ne, Lt, Le, Gt, Ge,}
impl fmt::Display for BinOp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) }}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum UnOp { Neg, Not, Ref(Mutability),}
impl fmt::Display for UnOp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) }}
impl UnOp { pub fn as_str(self) -> &'static str { match self { Self::Neg => "-", Self::Not => "!", Self::Ref(Mutability::Imm) => "&", Self::Ref(Mutability::Mut) => "&mut", } }}
#[derive(Debug, Clone)]pub enum TyExpr { Fn(TyExprFn), Slice(Box<Self>, Span), Ref(Box<Self>, Mutability, Span), Path(Vec<Word>, Option<Vec<Self>>, Span), Hole(Span), Group(Box<Self>, Span),}
impl Spanned for TyExpr { fn span(&self) -> Span { match self { Self::Fn(TyExprFn { span, .. }) | Self::Slice(_, span) | Self::Ref(_, _, span) | Self::Path(_, _, span) | Self::Hole(span) | Self::Group(_, span) => *span, } }}
#[derive(Debug, Clone)]pub struct TyExprFn { pub params: Vec<TyExpr>, pub ret: Box<TyExpr>, pub is_extern: bool, pub is_c_variadic: bool, pub callconv: CallConv, pub span: Span,}
#[derive(Debug, Clone)]pub enum Pat { Name(NamePat), Discard(Span),}
impl Pat { pub fn any(&self, mut f: impl FnMut(&NamePat) -> bool) -> bool { self.any_(&mut f) }
fn any_(&self, f: &mut impl FnMut(&NamePat) -> bool) -> bool { match self { Self::Name(n) => f(n), Self::Discard(_) => false, } }
pub fn word(&self) -> Option<Word> { match self { Pat::Name(n) => Some(n.word), Pat::Discard(_) => None, } }
pub fn param_name(&self) -> Option<Ustr> { match self { Pat::Name(NamePat { word, named: true, .. }) => Some(word.name()), _ => None, } }}
impl fmt::Display for Pat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Pat::Name(n) => n.word.fmt(f), Pat::Discard(_) => f.write_str("_"), } }}
impl Spanned for Pat { fn span(&self) -> Span { match self { Pat::Name(n) => n.span(), Pat::Discard(span) => *span, } }}
#[derive(Debug, Clone)]pub struct NamePat { pub id: DefId, pub word: Word, pub mutability: Mutability, pub vis: Vis, pub ty: Ty, pub named: bool, // Used for named function paramters}
impl NamePat { pub fn new_anon(word: Word, ty: Ty) -> Self { Self { id: DefId::null(), word, mutability: Mutability::Imm, vis: Vis::Public, ty, named: false, } }}
impl Spanned for NamePat { fn span(&self) -> Span { self.word.span() }}
#[derive(Debug, Clone)]pub struct TyParam { pub id: DefId, pub word: Word, pub ty: Ty,}
create_bool_enum!(IsUfcs);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]pub enum CallConv { #[default] Jin, C,}
impl<'a> TryFrom<&'a str> for CallConv { type Error = ();
fn try_from(value: &'a str) -> Result<Self, Self::Error> { match value { "jin" => Ok(CallConv::Jin), "c" => Ok(CallConv::C), _ => Err(()), } }}
impl fmt::Display for CallConv { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { CallConv::Jin => "jin", CallConv::C => "c", }) }}