rev: 08a0786d94a50b3b229836c53a03976f10ab6bd7 scopes/lib/scopes/Option.sc -rw-r--r-- 1.7 KiB View raw Log this file
08a0786d94a5Shawn Walker-Salas * drop number sections in menu due to readthedocs theme incompatibility 19 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#
    The Scopes Compiler Infrastructure
    This file is distributed under the MIT License.
    See LICENSE.md for details.

""""Option
    ======

    Provides a value type that can be undefined.

using import .enum

spice option-rimply (other-cls cls T)
    if (other-cls == Nothing)
        return `(inline none-converter () (cls.None))
    other-cls as:= type
    T as:= type
    let conv = (imply-converter other-cls T false)
    if (operator-valid? conv)
        return `(inline (self) (cls.Some (conv self)))
    return `()

run-stage;

let extract-payload = Enum.unsafe-extract-payload

typedef UnwrapError : (tuple)
    inline __typecall (cls)
        bitcast none this-type

@@ memo
inline Option (T)
    T := (unqualified T)

    enum (.. "<Option " (tostring T) ">")
        None
        Some : T

        inline... __typecall
        case (cls : type,)
            this-type.None;
        case (cls : type, value)
            # follow same rules as assignment
            imply value this-type

        inline __tobool (self)
            dispatch self
            case None () false
            default true

        inline swap (self newvalue)
            let value = (deref (dupe self))
            assign (imply newvalue this-type) self
            value

        inline __imply (cls other-cls)
            static-if (T == bool)
                __tobool

        inline __rimply (other-cls cls)
            option-rimply other-cls cls T

        fn force-unwrap (self)
            assert self "unwrapping empty Option failed"
            extract-payload self T

        fn unwrap (self)
            if (not self)
                raise (UnwrapError)
            extract-payload self T

do
    let Option UnwrapError
    locals;