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