use std::fmt::Display;
use inetnum::asn::Asn;
use symbol_table::GlobalSymbol;
use crate::parser::meta::Meta;
#[derive(Clone, Debug)]
pub struct SyntaxTree {
pub declarations: Vec<Declaration>,
}
#[derive(Clone, Debug)]
pub enum Declaration {
FilterMap(Box<FilterMap>),
Record(RecordTypeDeclaration),
Enum(VariantTypeDeclaration),
Function(FunctionDeclaration),
Test(Test),
Import(Vec<Meta<Path>>),
}
pub struct Signature {
pub type_params: Vec<Meta<Identifier>>,
pub params: Vec<Meta<TypeExpr>>,
pub ret: Option<Meta<TypeExpr>>,
}
#[derive(Clone, Debug)]
pub struct Params(pub Vec<(Meta<Identifier>, Meta<TypeExpr>)>);
#[derive(Clone, Debug)]
pub struct RecordTypeDeclaration {
pub ident: Meta<Identifier>,
pub type_params: Vec<Meta<Identifier>>,
pub record_type: RecordType,
}
#[derive(Clone, Debug)]
pub struct VariantTypeDeclaration {
pub ident: Meta<Identifier>,
pub type_params: Vec<Meta<Identifier>>,
pub variants: Meta<Vec<Variant>>,
}
#[derive(Clone, Debug)]
pub struct Variant {
pub ident: Meta<Identifier>,
pub fields: Vec<Meta<TypeExpr>>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FilterType {
FilterMap,
Filter,
}
#[derive(Clone, Debug)]
pub struct FilterMap {
pub filter_type: FilterType,
pub ident: Meta<Identifier>,
pub params: Meta<Params>,
pub body: Meta<Block>,
}
#[derive(Clone, Debug)]
pub struct FunctionDeclaration {
pub ident: Meta<Identifier>,
pub params: Meta<Params>,
pub ret: Option<Meta<TypeExpr>>,
pub body: Meta<Block>,
}
#[derive(Clone, Debug)]
pub struct Test {
pub ident: Meta<Identifier>,
pub body: Meta<Block>,
}
#[derive(Clone, Debug)]
pub struct Block {
pub imports: Vec<Meta<Path>>,
pub stmts: Vec<Meta<Stmt>>,
pub last: Option<Box<Meta<Expr>>>,
}
#[derive(Clone, Debug)]
pub enum Stmt {
Let(Meta<Identifier>, Option<Meta<TypeExpr>>, Meta<Expr>),
Expr(Meta<Expr>),
}
#[derive(Clone, Debug)]
pub struct Path {
pub idents: Vec<Meta<Identifier>>,
}
#[derive(Clone, Debug)]
pub enum TypeExpr {
Option(Box<Meta<TypeExpr>>),
Path(Meta<Path>, Option<Meta<Vec<Meta<TypeExpr>>>>),
Never,
Unit,
Record(RecordType),
}
#[derive(Clone, Debug)]
pub enum Expr {
Return(ReturnKind, Option<Box<Meta<Expr>>>),
Literal(Meta<Literal>),
Match(Box<Meta<Match>>),
FunctionCall(Box<Meta<Expr>>, Meta<Vec<Meta<Expr>>>),
Access(Box<Meta<Expr>>, Meta<Identifier>),
Path(Meta<Path>),
Record(Meta<Record>),
TypedRecord(Meta<Path>, Meta<Record>),
List(Vec<Meta<Expr>>),
Not(Box<Meta<Expr>>),
Assign(Meta<Path>, Box<Meta<Expr>>),
BinOp(Box<Meta<Expr>>, BinOp, Box<Meta<Expr>>),
Negate(Box<Meta<Expr>>),
IfElse(Box<Meta<Expr>>, Meta<Block>, Option<Meta<Block>>),
While(Box<Meta<Expr>>, Meta<Block>),
For(Meta<Identifier>, Box<Meta<Expr>>, Meta<Block>),
QuestionMark(Box<Meta<Expr>>),
FString(Vec<Meta<FStringPart>>),
}
#[derive(Clone, Debug)]
pub enum FStringPart {
String(String),
Expr(Meta<Expr>),
}
#[derive(Clone, Debug)]
pub enum ReturnKind {
Return,
Accept,
Reject,
}
impl ReturnKind {
pub fn str(&self) -> &'static str {
match self {
ReturnKind::Return => "return",
ReturnKind::Accept => "accept",
ReturnKind::Reject => "reject",
}
}
}
#[derive(Clone, Debug)]
pub struct Record {
pub fields: Vec<(Meta<Identifier>, Meta<Expr>)>,
}
#[derive(Clone, Debug)]
pub struct Match {
pub expr: Meta<Expr>,
pub arms: Vec<MatchArm>,
}
#[derive(Clone, Debug)]
pub struct MatchArm {
pub pattern: Meta<Pattern>,
pub guard: Option<Meta<Expr>>,
pub body: Meta<Block>,
}
#[derive(Clone, Debug)]
pub enum Pattern {
Underscore,
EnumVariant {
variant: Meta<Identifier>,
fields: Option<Meta<Vec<Meta<Identifier>>>>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Identifier(GlobalSymbol);
impl Display for Identifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl Identifier {
pub fn as_str(&self) -> &'static str {
self.0.as_str()
}
}
impl From<&str> for Identifier {
fn from(value: &str) -> Self {
Self(value.into())
}
}
impl From<&String> for Identifier {
fn from(value: &String) -> Self {
Self(value.into())
}
}
impl From<String> for Identifier {
fn from(value: String) -> Self {
Self(value.into())
}
}
#[derive(Clone, Debug)]
pub struct RecordType {
pub fields: Meta<Vec<(Meta<Identifier>, Meta<TypeExpr>)>>,
}
#[derive(Clone, Debug)]
pub enum Literal {
String(String),
Char(char),
Asn(Asn),
IpAddress(std::net::IpAddr),
Integer(i64),
Float(f64),
Bool(bool),
Unit,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BinOp {
And,
Or,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
In,
NotIn,
Add,
Sub,
Mul,
Div,
}
impl std::fmt::Display for BinOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::And => "&&",
Self::Or => "||",
Self::Eq => "==",
Self::Ne => "!=",
Self::Lt => "<=",
Self::Le => "<",
Self::Gt => ">=",
Self::Ge => "<",
Self::In => "in",
Self::Add => "+",
Self::Sub => "-",
Self::Mul => "*",
Self::Div => "/",
Self::NotIn => "not in",
}
)
}
}