Skip to main content

swan_core/value/
undef.rs

1use super::*;
2
3
4
5
6// ----------------------------------------------------------------------------
7//  Undefined
8// ----------------------------------------------------------------------------
9
10/// Why a value is undefined: the payload of [`Value::Undefined`].
11///
12/// Positions (`pos`) are byte offsets in the evaluated source. Built-in
13/// functions use position `0`. Two `Undef`s are equal when they have the same
14/// variant and contents, regardless of position.
15///
16/// The Swan built-in `undef.inspect` exposes these fields to Swan code.
17#[derive(Debug, Clone)]
18pub enum Undef {
19
20    /// The result of a unary operation that is not defined for the operand type.
21    UnaryOperation {
22        /// Operation name (always a `&'static str` for built-in ops).
23        /// If dunder-method dispatch (`__neg__`, etc.) is added later and
24        /// user-defined error labels are needed, change this to `Rc<str>`.
25        op : &'static str,
26        /// The operand.
27        val: Box<Value>,
28        /// Source position of the operation.
29        pos: usize,
30    },
31
32    /// The result of a binary operation that is not defined for the operand types.
33    BinaryOperation {
34        /// Operation name, such as `"sum"` or `"application"`.
35        op : &'static str,
36        /// The left-hand operand.
37        lhv: Box<Value>,
38        /// The right-hand operand.
39        rhv: Box<Value>,
40        /// Source position of the operation.
41        pos: usize,
42    },
43
44    /// Syntax error: a group `(...)`, `[...]` or `{...}` without its closing
45    /// bracket.
46    Termination {
47        /// The missing closing bracket.
48        expected: char,
49        /// Source position where the bracket was expected.
50        pos: usize,
51    },
52
53    /// Syntax error: a token that is not valid where it appears.
54    Token {
55        /// A description of the token.
56        token: String,
57        /// Source position of the token.
58        pos: usize,
59    },
60
61    /// A name was expected (left of `=`, `:` or `->`, or after `$`), but
62    /// another expression was found.
63    Name {
64        /// Source position of the offending expression.
65        pos: usize
66    },
67
68    /// An undefined value created explicitly, for example by the Swan
69    /// built-in `undef.from`. It wraps an arbitrary value.
70    Value(Box<Value>),
71}
72
73impl PartialEq for Undef {
74    fn eq(&self, other: &Self) -> bool {
75        match (self, other) {
76            (Undef::UnaryOperation{op:op1, val:val1, ..}, 
77             Undef::UnaryOperation{op:op2, val:val2, ..}) => {
78                op1 == op2 && val1 == val2
79            }
80            (Undef::BinaryOperation{op:op1, lhv:lhv1, rhv:rhv1, ..}, 
81             Undef::BinaryOperation{op:op2, lhv:lhv2, rhv:rhv2, ..}) => {
82                op1 == op2 && lhv1 == lhv2 && rhv1 == rhv2
83            }
84            (Undef::Termination{expected:exp1, ..}, 
85             Undef::Termination{expected:exp2, ..}) => {
86                exp1 == exp2
87            }
88            (Undef::Token{token:token1, ..}, 
89             Undef::Token{token:token2, ..}) => {
90                token1 == token2
91            }
92            (Undef::Name{..}, 
93             Undef::Name{..}) => {
94                true
95            }
96            (Undef::Value(val1), 
97             Undef::Value(val2)) => {
98                val1 == val2
99            }
100            _ => false,
101        }
102    }
103}
104
105