226 lines
3.9 KiB
Rust
226 lines
3.9 KiB
Rust
use arcstr::Substr;
|
|
use derive_more::Deref;
|
|
use indexmap::IndexMap;
|
|
use std::ops::Range;
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Debug, Deref)]
|
|
pub struct Ident(pub Substr);
|
|
|
|
#[derive(Debug, Deref)]
|
|
pub struct Import(pub Expr);
|
|
|
|
#[derive(Debug)]
|
|
pub struct Number {
|
|
pub text: Substr,
|
|
pub r#type: Option<Ident>,
|
|
}
|
|
|
|
#[derive(derive_more::Debug)]
|
|
pub enum Expr {
|
|
#[debug("uninit")]
|
|
Uninit(Substr),
|
|
#[debug("Ident({:?})", _0.0)]
|
|
Ident(Ident),
|
|
#[debug("{_0:?}")]
|
|
Number(Number),
|
|
String(Substr),
|
|
#[debug("{_0:?}")]
|
|
Binary(Box<BinaryExpr>),
|
|
Index(Box<IndexingExpr>),
|
|
Access(Box<AccessExpr>),
|
|
Deref(Box<Expr>),
|
|
Tuple(Vec<Expr>),
|
|
List(Vec<Expr>),
|
|
Struct(Box<StructCtor>),
|
|
#[debug("{_0:?}")]
|
|
Block(Arc<Block>),
|
|
#[debug("{_0:?}")]
|
|
Func(Arc<Function>),
|
|
#[debug("{_0:?}")]
|
|
Type(Box<Type>),
|
|
|
|
#[debug("{_0:?}")]
|
|
ConstDecl(Box<ConstDecl>),
|
|
#[debug("{_0:?}")]
|
|
VarDecl(Box<VarDecl>),
|
|
#[debug("{_0:?}")]
|
|
For(Box<For>),
|
|
#[debug("{_0:?}")]
|
|
While(Box<While>),
|
|
#[debug("{_0:?}")]
|
|
If(Box<If>),
|
|
|
|
Call {
|
|
func: Box<Expr>,
|
|
args: Vec<Expr>,
|
|
},
|
|
}
|
|
|
|
impl Expr {
|
|
pub fn range(&self) -> Range<usize> {
|
|
match self {
|
|
Self::Ident(e) => e.range(),
|
|
Self::Access(e) => e.range(),
|
|
Self::Number(e) => e.text.range(),
|
|
_ => todo!("{self:?}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct BinaryExpr {
|
|
pub lhs: Expr,
|
|
pub op: BinaryOp,
|
|
pub rhs: Expr,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct IndexingExpr {
|
|
pub value: Expr,
|
|
pub index: Expr,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct AccessExpr {
|
|
pub value: Expr,
|
|
pub field: Ident,
|
|
}
|
|
|
|
impl AccessExpr {
|
|
pub fn range(&self) -> Range<usize> {
|
|
self.value.range().start..self.field.0.range().end
|
|
}
|
|
}
|
|
|
|
#[rustfmt::skip]
|
|
#[derive(derive_more::Debug)]
|
|
pub enum BinaryOp {
|
|
#[debug("{_0}")] Add(Substr),
|
|
#[debug("{_0}")] Sub(Substr),
|
|
#[debug("{_0}")] Mul(Substr),
|
|
#[debug("{_0}")] Div(Substr),
|
|
#[debug("{_0}")] Mod(Substr),
|
|
#[debug("{_0}")] Eq(Substr),
|
|
#[debug("{_0}")] Ne(Substr),
|
|
#[debug("{_0}")] Lt(Substr),
|
|
#[debug("{_0}")] Gt(Substr),
|
|
#[debug("{_0}")] Le(Substr),
|
|
#[debug("{_0}")] Ge(Substr),
|
|
#[debug("{_0}")] Range(Substr),
|
|
#[debug("{_0}")] Assign(Substr),
|
|
#[debug("{_0}")] Cast(Substr),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Type {
|
|
Ptr { base: Expr, mutable: Option<Substr> },
|
|
Struct(Struct),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct ConstDecl {
|
|
pub names: NamePattern,
|
|
pub r#type: Option<Expr>,
|
|
pub value: Expr,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct VarDecl {
|
|
pub names: NamePattern,
|
|
pub r#type: Option<Expr>,
|
|
pub value: Expr,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum NamePattern {
|
|
Single(Ident),
|
|
Tuple(Vec<Ident>),
|
|
List(Vec<Ident>),
|
|
}
|
|
|
|
impl NamePattern {
|
|
pub fn as_slice(&self) -> &[Ident] {
|
|
match self {
|
|
NamePattern::Single(ident) => std::slice::from_ref(ident),
|
|
NamePattern::Tuple(idents) => idents.as_slice(),
|
|
NamePattern::List(idents) => idents.as_slice(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Function {
|
|
pub text: Substr,
|
|
pub args: Vec<NameValuePair>,
|
|
pub ret: Option<Expr>,
|
|
pub block: Option<Arc<Block>>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct NameValuePair {
|
|
pub name: Ident,
|
|
pub value: Expr,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Struct {
|
|
pub fields: Vec<Field>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Field {
|
|
pub name: Ident,
|
|
pub ty: Expr,
|
|
pub public: Option<Substr>,
|
|
pub mutable: Option<Substr>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct StructCtor {
|
|
pub r#type: Option<Expr>,
|
|
pub r#values: IndexMap<Substr, NameValuePair>,
|
|
pub(crate) range: Range<usize>,
|
|
}
|
|
|
|
impl StructCtor {
|
|
pub fn range(&self) -> Range<usize> {
|
|
self.range.clone()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Block(pub Vec<Expr>);
|
|
|
|
#[derive(Debug)]
|
|
pub struct For {
|
|
pub names: NamePattern,
|
|
pub value: Expr,
|
|
pub block: Block,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct While {
|
|
pub cond: Expr,
|
|
pub block: Block,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct If {
|
|
pub cond: Expr,
|
|
pub block: Block,
|
|
pub else_: Option<Box<Else>>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Else {
|
|
If(If),
|
|
Block(Block),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct CompilationUnit {
|
|
pub imports: Vec<Import>,
|
|
pub decls: Vec<ConstDecl>,
|
|
}
|