summaryrefslogtreecommitdiff
path: root/doc/api/libstd/varargs.txt
blob: b0eaf3e971ac2a1433f866d3461c8c71847b722f (plain)
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
{
        title:  Varargs
        description:  libstd: Varargs
}

Varargs
-------

    pkg std =
            type typedesc = union
                    `Tynone
                    
                    /* atomic types */
                    `Tyvoid
                    `Tybool
                    `Tychar
                    
                    `Tyint8
                    `Tyint16
                    `Tyint
                    `Tyint32
                    `Tyint64
                    
                    `Tybyte
                    `Tyuint8
                    `Tyuint16
                    `Tyuint
                    `Tyuint32
                    `Tyuint64
                    `Tyflt32
                    `Tyflt64
                    `Tyvalist
                    
                    /* compound types */
                    `Typtr byte[:]
                    `Tyfunc	typecursor
                    `Tyslice byte[:]
                    `Tyarray (size, byte[:])
                    
                    /* aggregate types */
                    `Tytuple	typecursor
                    `Tystruct	typecursor
                    `Tyunion	typecursor
                    /* name info */
                    `Tyname (byte[:], byte[:])
            ;;

            type typecursor = struct
                    nelt	: size
            ;;

            type typeinfo = struct
                    size	: size
                    align	: size
            ;;

            generic typeof	: (v : @a -> byte[:])
            const typeenc	: (p : ...# -> typecursor)
            const typeenccursor	: (e : byte[:] -> typecursor)
            const typedesc	: (e : byte[:] -> typedesc)
            const typeinfo	: (e : byte[:] -> typeinfo)
            const tcnext	: (t : typecursor# -> byte[:])
            const tcpeek	: (t : typecursor# -> byte[:])
            const ncpeek	: (t : typecursor# -> (byte[:], byte[:]))
            const ncnext	: (t : typecursor# -> (byte[:], byte[:]))

            const vastart	: (args : ...# -> valist)
            const vatype	: (ap : valist# -> byte[:])
            const vabytes	: (ap : valist# -> byte[:])
            const vaenter	: (ap : valist# -> valist)
            generic vanext	: (ap : valist# -> @a)
    ;;

Overview
--------

Type descriptions are encoded byte strings. 

Types
-----


    type typedesc = union
            ...
    ;;


Typedesc provides a description of a type. It can be paired with a valist for
walking over the contents of a value, but this is ugly.


    type typecursor = struct
            nelt	: size
    ;;

A type cursor allows for iterating over the subtypes of a type. It exposes the
number of elements in the subtype.

    type typeinfo = struct
            size	: size
            align	: size
    ;;

Typeinfo contains all of the attributes that we care about for the type. This
may expand in the future.


Type iteration
---------

    generic typeof	: (v : @a -> byte[:])

Typeof takes any arbitrary value, and returns an encoded type description for
the type of the value. It would be better to provide a first class interface
for finding type encodings, but this needs thought.

    const typeenc	: (p : ...# -> typecursor)

Typeenc returns a type cursor for an argument list, allowing for iteration
over the type of values within it.

    const typeenccursor	: (e : byte[:] -> typecursor)

Typeenccursor takes a type encoding, and converts it to a cursor with a single
type. Iterating the cursor will return only the one type encoding that was
passed to this function.

    const typedesc	: (e : byte[:] -> typedesc)

Typedesc extracts a typedesc from an encoded type. The type description
may contain other type cursors for iterating over subtypes.

    const typeinfo	: (e : byte[:] -> typeinfo)

Typeinfo extracts a typeinfo from an encoded type. The type description
contains attributes about the type, such as the size and alignment.

    const tcnext	: (t : typecursor# -> byte[:])

Tcnext pulls an encoded subtype from a type cursor and advances it.
Calling this on a cursor that has a name is acceptable, and will
discard the name.

    const tcpeek	: (t : typecursor# -> byte[:])

Tcnext pulls an encoded subtype from a type cursor and does not it.
Calling this on a cursor that has a name is acceptable, and will
discard the name.

    const ncnext	: (t : typecursor# -> (byte[:], byte[:]))

Ncnext pulls an encoded subtype from a type cursor for a type with named
subtypes, and advances the type cursor. such as a struct or union, and returns
the name and encoded type.

    const ncpeek	: (t : typecursor# -> (byte[:], byte[:]))

Ncpeek pulls an encoded subtype from a type cursor for a type with named
subtypes, such as a struct or union, and returns the name and encoded
type. This does not advance the cursor.

Variadic Arguments
-----------------

    const vastart	: (args : ...# -> valist)

Vastart takes a pointer to a variadic argument list, and returns a valist,
which is basically an iterator for arguments.

    const vatype	: (ap : valist# -> byte[:])

Vatype returns a type encoding for the current variadic argument that the
valist is pointing to.

    generic vanext	: (ap : valist# -> @a)

Vanext returns the next value for the variadic type, and advances the valist.

    const vabytes	: (ap : valist# -> byte[:])

Vanext returns a slice to the bytes of the variadic argument, and advances the
valist.

    const vaenter	: (ap : valist# -> valist)

Vaenter does not advance the valist, but returns a new valist for the
argument, allowing iteration over the fields within the argument. For example,
if you had a struct passed as a variadic argument, calling 'vaenter' on it
would allow iterating over the members of the struct.