1use crate::{span::Spanned, types::Type};
4
5#[derive(Debug, PartialEq)]
6pub enum Expr {
7 Bool(Box<ExprBool>),
8 Identifier(Box<ExprIdentifier>),
9 Call(Box<ExprCall>),
10 String(Box<ExprString>),
11 Error,
12}
13
14impl Expr {
15 pub fn identifier(identifier: &str) -> Self {
16 Self::Identifier(Box::new(ExprIdentifier::new(identifier)))
17 }
18
19 pub fn identifier_name(&self) -> Option<&str> {
20 match self {
21 Expr::Identifier(expr_identifier) => Some(expr_identifier.name()),
22 _ => None,
23 }
24 }
25
26 pub fn string(string: &str) -> Self {
27 Self::String(ExprString::new(string).into())
28 }
29
30 pub fn call(callee: ExprS, args: Vec<ExprS>) -> Self {
31 Self::Call(Box::new(ExprCall { callee, args }))
32 }
33
34 pub fn bool(value: bool) -> Self {
35 Self::Bool(Box::new(ExprBool::new(value)))
36 }
37
38 pub fn is_bool(&self) -> bool {
39 self.get_type() == Type::Bool
40 }
41
42 pub fn get_type(&self) -> Type {
43 match self {
44 Expr::Bool(_) => Type::Bool,
45 Expr::Identifier(_) => Type::Unknown,
46 Expr::Call(_) => Type::Unknown,
47 Expr::String(_) => Type::String,
48 Expr::Error => Type::Unknown,
49 }
50 }
51}
52
53#[derive(Debug, PartialEq)]
54pub struct ExprIdentifier(pub String);
55
56impl ExprIdentifier {
57 pub fn new(identifier: &str) -> Self {
58 Self(identifier.to_string())
59 }
60
61 pub fn name(&self) -> &str {
62 &self.0
63 }
64}
65
66#[derive(Debug, PartialEq)]
67pub struct ExprString(pub String);
68
69impl ExprString {
70 pub fn new(string: &str) -> Self {
71 Self(string.to_string())
72 }
73}
74
75#[derive(Debug, PartialEq)]
76pub struct ExprCall {
77 pub callee: ExprS,
78 pub args: Vec<ExprS>,
79}
80
81#[derive(Debug, PartialEq)]
82pub struct ExprBool(pub bool);
83
84impl ExprBool {
85 pub fn new(value: bool) -> Self {
86 Self(value)
87 }
88}
89
90pub type ExprS = Spanned<Expr>;