lib/var/var.x
Variant type for dynamic typing.
Primary API
| Function | Summary |
|---|---|
x2c_var_custom_descriptor | Returns a boxed custom object’s descriptor, or NULL for another value. |
x2c_var_declare | Returns the process-lifetime descriptor declared for custom tag, declaring it on first use. |
x2c_var_descriptor_index | Returns value’s dense built-in descriptor row, or -1 when it has none. |
x2c_var_tag_descriptor_index | Returns a built-in object or Symbol tag’s descriptor row, or -1. |
Var.box_record | Boxes a copy of the size-byte record at record as custom tag. |
Var.is | Reports whether value has the requested runtime tag. |
Var.is_floating | Reports whether v belongs to the floating runtime family. |
Var.is_integer | Reports whether v belongs to the integer runtime family. |
Var.is_nil | Reports whether v is the typed empty List. |
Var.is_null | Reports whether v is the all-zero Null value. |
Var.is_object | Reports whether v holds a registered boxed object. |
Var.is_pointer | Reports whether v holds a native pointer. |
Var.is_reference | Reports whether v holds a pointer to a boxed handle. |
Var.is_void | Reports whether v is the absence sentinel void. |
Var.new | Constructs a Var with tag from its tag-directed variadic payload. |
Var.null | Returns Null, the all-zero Var that stands for external nil. |
Var.tag_bottom | Returns the bottom encoding field of built-in tag. |
Var.tag_top | Returns the top encoding field of built-in tag. |
Functions
x2c_var_custom_descriptor
VarDescriptor *x2c_var_custom_descriptor(Var value)
Returns a boxed custom object’s descriptor, or NULL for another value.
Source: lib/var/classes.x:80
x2c_var_declare
VarDescriptor *x2c_var_declare(Symbol tag)
Returns the process-lifetime descriptor declared for custom tag,
declaring it on first use. The caller holds the descriptor lock and has
checked that registration is open and tag is not built in.
Source: lib/var/classes.x:222
x2c_var_descriptor_index
int x2c_var_descriptor_index(Var value)
Returns value’s dense built-in descriptor row, or -1 when it has none.
The row is the tag’s offset from <array> and includes the Symbol row.
Numbers, pointers, references, custom tags, and invalid encodings have no
built-in row.
Source: lib/var/encoding.x:273
x2c_var_tag_descriptor_index
int x2c_var_tag_descriptor_index(Symbol tag)
Returns a built-in object or Symbol tag’s descriptor row, or -1.
Source: lib/var/encoding.x:289
Var
Var.box_record
Var Var.box_record(Symbol tag, const void *record, size_t size)
Boxes a copy of the size-byte record at record as custom tag.
The copy is allocated in the active Scope. Once the direct custom rows
are taken, the copy carries its descriptor in front of it.
Raises: <bad-target> when tag names no declared class, or
<alloc-fail> when the copy cannot be allocated.
Source: lib/var/classes.x:96
Var.is
int Var.is(Var var, Symbol tag)
Reports whether value has the requested runtime tag.
This tests one family. A Var holding an unsigned char answers 0 for
<i32> even though both are integers. When any integer will do, ask
Var.is_integer, or compare Var.kind.
As with Var.tag, validate externally constructed bits first: an invalid
encoding uses the <f64> fallback.
Source: lib/var/encoding.x:165
Var.is_floating
meta native int Var.is_floating(Var v)
Reports whether v belongs to the floating runtime family.
True for <f32>, <f64>, and <ldouble>, and for the discrete <nan>,
<+inf>, and <-inf> values. Read the payload with Var.floating, or
with Var.long_double_value when the tag is <ldouble> and the extra
precision matters.
Source: lib/var/encoding.x:190
Var.is_integer
int Var.is_integer(Var v)
Reports whether v belongs to the integer runtime family.
True for every signed and unsigned integer family from <u8> through
<ullong>, including the scope-owned wide boxes. Symbols are a kind of
their own and answer 0 here, even though Var.integer returns a Symbol’s
numeric value.
Source: lib/var/encoding.x:198
Var.is_nil
meta native int Var.is_nil(Var v)
Reports whether v is the typed empty List.
The empty List is a native null pointer carrying the <list> tag.
Var.is_null answers 0 and Var.tag answers <list>. Every %() and
every exhausted List.cdr yields this one value, so an identity test on
the bits is a valid emptiness test.
Source: lib/var/encoding.x:258
Var.is_null
meta native int Var.is_null(Var v)
Reports whether v is the all-zero Null value.
Null is a value: the null pointer and the external nil. It is legal
collection data, iterating a List can return it, and it is false in a
condition. Its tag decodes as <p48>, so there is no dedicated null
family for Var.is to match.
Write Null as (Var) { .u64 = 0 }. An unresolved C NULL macro also
converts to this value when its x2c target is Var.
Source: lib/var/encoding.x:245
Var.is_object
meta native int Var.is_object(Var v)
Reports whether v holds a registered boxed object.
True for the builtin classes such as String, List, Array, Map,
File, and Iter, and for any tag registered with
Var.register_object_tag. A pointer to a handle, such as <string*>, is
<reference> instead and answers 0 here.
Source: lib/var/encoding.x:212
Var.is_pointer
meta native int Var.is_pointer(Var v)
Reports whether v holds a native pointer.
Source: lib/var/encoding.x:201
Var.is_reference
meta native int Var.is_reference(Var v)
Reports whether v holds a pointer to a boxed handle.
Source: lib/var/encoding.x:204
Var.is_void
int Var.is_void(Var v)
Reports whether v is the absence sentinel void.
An API returns void to say there is nothing here. It is excluded from
every collection and iterator value domain: it cannot be pushed into an
Array or stored in a Map. Equality and identity still inspect it. Two
sentinels compare equal and identical, while one sentinel and one
ordinary value compare unequal. Truthiness, hashing, ordering, conversion,
and iteration on void raise to a matching catch or terminate.
Null is the all-zero Var: legal collection data and false in a
condition. A void result may mean missing, exhausted, or invalid;
each API documents its meaning.
Var raw = (Var) { .u64 = 0 };
printf("null: void=%d null=%d\n", raw is void, raw.is_null());
printf("void: void=%d null=%d\n", void is void, void.is_null());
This is the test that accepts a void argument.
Source: lib/var/encoding.x:234
Var.new
Var Var.new(Symbol tag, ...)
Constructs a Var with tag from its tag-directed variadic payload.
The tag chooses how the argument is read, so pass exactly the C type the
tag names: an int for <i32>, an unsigned long for <u48>, a
double for <f64>, a long double for <ldouble>, a pointer for any
pointer, reference, or object family, and a Symbol’s numeric value for
<symbol>. <void> consumes no payload. Variadic arguments are not
converted for you. Assignment, Var boxed = 42;, is the usual way to box
a value. Use this constructor when the tag is computed at run time.
Immediate values are stored inline. Wide numeric tags allocate a box in the
active Scope. Pointer, reference, and object tags borrow the address and
encode only its low 48 bits; they do not take ownership, and the address
must satisfy the alignment implied by the tag. A declared custom tag is
accepted too and requires an 8-byte-aligned pointer. Once the direct
custom rows are taken, a custom object boxes through a process-lifetime
cell, one per class and address, so boxing one object twice gives
identical bits.
Raises: <bad-target> when tag is neither known nor registered,
<conv-range> when a scalar does not fit the tag’s payload width,
<bad-arg> when an <array> or <map> pointer is null, <alloc-fail>
when a wide box cannot be allocated, and <bad-enc> when a box address
cannot be represented or a pointer does not satisfy its tag’s alignment.
Source: lib/var/construction.x:28
Var.null
meta native Var Var.null(void)
Returns Null, the all-zero Var that stands for external nil.
Generated call adapters return it for a void target.
Source: lib/var/encoding.x:250
Var.tag_bottom
meta native unsigned long Var.tag_bottom(Symbol tag)
Returns the bottom encoding field of built-in tag.
Source: lib/var/encoding.x:70
Var.tag_top
meta native unsigned long Var.tag_top(Symbol tag)
Returns the top encoding field of built-in tag.
Source: lib/var/encoding.x:62
Advanced and interop API
| Function | Summary |
|---|---|
Var.box_long | Boxes a long into a scope-owned <long> value. |
Var.box_long_double | Boxes a long double into a scope-owned <ldouble> value. |
Var.box_long_long | Boxes a native signed long-long value without losing precision. |
Var.box_ulong | Boxes an unsigned long into a scope-owned <ulong> value. |
Var.box_ulong_long | Boxes a native unsigned long-long value without losing precision. |
Var.encoding_valid | Reports whether value has a valid structural Var encoding. |
Var.floating | Returns v’s payload as a double when its tag is floating, or 0.0. |
Var.integer | Returns v’s payload as a long when its tag is integral, or 0. |
Var.integer_compare | Orders the integer payloads of a and b, returning -1, 0, or 1. |
Var.integer_floating_compare | Orders an integer-kinded integer against a floating floating. |
Var.kind | Returns the Symbol naming the coarse category of v’s payload. |
Var.known_tag | Reports whether tag has a built-in encoding or declared custom class. |
Var.long_double_value | Returns the payload of an <ldouble> box, or 0.0 if v has another tag. |
Var.long_long_value | Returns an <llong> box’s signed payload, or 0 for another tag. |
Var.long_value | Returns the payload of a <long> box, or 0 if v has a different tag. |
Var.parse | Parses str as source text of kind kind and returns the boxed value. |
Var.pointer | Returns the raw address stored in v, or NULL if it holds no address. |
Var.register_object_tag | Declares custom boxed-object tag and returns 0. |
Var.tag | Returns the Symbol naming the exact family of v’s payload. |
Var.ulong_long_value | Returns a <ullong> box’s unsigned payload, or 0 for another tag. |
Var.ulong_value | Returns the payload of a <ulong> box, or 0 if v has a different tag. |
Var.wide_compare | Orders two wide boxes carrying the same tag, returning -1, 0, or 1. |
Var.wide_equal | Reports content equality for supported wide scalar boxes. |
Var.wide_hash | Returns a supported wide scalar box’s content hash, or 0 otherwise. |
Var
Var.box_long
Var Var.box_long(long value)
Boxes a long into a scope-owned <long> value.
A Var is eight bytes, and the tag consumes some of them. The five widest
native families, long, unsigned long, long long, unsigned long long, and long double, cannot be stored inline. Boxing one allocates a
small immutable box in the active scope, and the result lives for that
scope’s lifetime like any other scope allocation.
Two boxes of the same number are equal and identical: == compares the
values, and === compares the type and the value bits. Var.same
compares the 64 Var bits, and therefore the box addresses.
Var five = Var.box_long(5L);
Var also = Var.box_long(5L);
printf("equal=%d identical=%d same=%d tag=%s\n", five == also,
five === also, five.same(also), five.tag().str());
Raises: <alloc-fail> when the box cannot be allocated and <bad-enc>
when its address cannot be represented in a Var. Before Error
initialization, allocation failure uses the raw fatal floor.
Source: lib/var/numbers.x:66
Var.box_long_double
Var Var.box_long_double(long double value)
Boxes a long double into a scope-owned <ldouble> value.
This is the only family that keeps a full long double payload. The tag
names that C family; it does not promise a bit width. Var.floating
narrows the value to double; Var.long_double_value preserves the
extra precision.
Raises: <alloc-fail> when the box cannot be allocated and <bad-enc>
when its address cannot be represented in a Var. Before Error
initialization, allocation failure uses the raw fatal floor.
Source: lib/var/numbers.x:119
Var.box_long_long
Var Var.box_long_long(long long value)
Boxes a native signed long-long value without losing precision.
Raises: <alloc-fail> when the box cannot be allocated and <bad-enc>
when its address cannot be represented in a Var. Before Error
initialization, allocation failure uses the raw fatal floor.
Source: lib/var/numbers.x:93
Var.box_ulong
Var Var.box_ulong(unsigned long value)
Boxes an unsigned long into a scope-owned <ulong> value.
<ulong> is a distinct family from <long>. A box made here is never
Var.equal or identical to one made by Var.box_long, even when both
hold the same bit pattern, because Var.wide_equal requires matching
tags. == converts the two as C does. Read it back with
Var.ulong_value, the one reader that returns the payload unsigned.
Raises: <alloc-fail> when the box cannot be allocated and <bad-enc>
when its address cannot be represented in a Var. Before Error
initialization, allocation failure uses the raw fatal floor.
Source: lib/var/numbers.x:82
Var.box_ulong_long
Var Var.box_ulong_long(unsigned long long value)
Boxes a native unsigned long-long value without losing precision.
Raises: <alloc-fail> when the box cannot be allocated and <bad-enc>
when its address cannot be represented in a Var. Before Error
initialization, allocation failure uses the raw fatal floor.
Source: lib/var/numbers.x:104
Var.encoding_valid
int Var.encoding_valid(Var value)
Reports whether value has a valid structural Var encoding.
An address-bearing encoding must still refer to live storage of the right
type; wide encodings in particular require a readable Scope-owned box.
Source: lib/var/encoding.x:264
Var.floating
meta native double Var.floating(Var v)
Returns v’s payload as a double when its tag is floating, or 0.0.
Handles <f32>, <f64>, and <ldouble>, and reconstructs NaN,
+Inf, and -Inf from their discrete tags. An <ldouble> payload is
narrowed to double; call Var.long_double_value to keep the full
precision.
Like the other raw payload readers this one is silent. An integer, a
String, or void reads as 0.0, and nothing distinguishes that from a
stored zero. When the tag is not already known, convert with
Var.convert in lib/varconvert.x, which raises a conversion failure;
the scalar-named readers such as Var.double do this for you.
An unhandled tag yields 0.0.
Source: lib/var/numbers.x:180
Var.integer
meta native long Var.integer(Var v)
Returns v’s payload as a long when its tag is integral, or 0.
This reads the payload; it does not convert. It decodes every integer
family, from <u8> through <ullong>, including the scope-owned boxes,
and returns 0 for a tag it does not handle. A double reads as 0, and so
does a String; nothing reports the mismatch. A <ullong> or <llong>
payload is truncated to long, and a <ulong> above LONG_MAX comes back
negative. Var.ulong_value preserves the unsigned payload. A
Symbol reads as its numeric Symbol value.
When the tag might not be what you expect, convert instead of reading.
Var.convert in lib/varconvert.x raises a conversion failure.
Assigning a Var to an int or a long, and the scalar-named readers
such as Var.int, go through Var.convert too.
Var text = "ada";
Var small = (unsigned char) 44;
printf("small=%ld text=%ld\n", small.integer(), text.integer());
An unhandled tag yields 0.
Source: lib/var/numbers.x:224
Var.integer_compare
int Var.integer_compare(Var a, Var b)
Orders the integer payloads of a and b, returning -1, 0, or 1.
Each value is decomposed into a sign and an unsigned magnitude first, so
the whole integer range orders correctly, including a <ullong> above
LONG_MAX against a negative <long>. Subtracting in a fixed-width
integer type could overflow.
Both arguments are assumed to be integer-kinded. Another value is decoded
by Var.integer, which reads it as 0. Confirm with Var.is_integer when
the kinds are not known.
Source: lib/var/ordering.x:19
Var.integer_floating_compare
int Var.integer_floating_compare(Var integer, Var floating)
Orders an integer-kinded integer against a floating floating.
Returns -1, 0, or 1 for less, equal, and greater. The integer is never
converted to floating point, so a large <ullong> and a nearby double
order by their true values. A floating value with a fractional part is
never equal to an integer.
+Inf is greater than every integer and -Inf is less than every
integer. NaN is not ordered and reports -1. Test the tag for <nan>
first if that distinction matters.
Source: lib/var/ordering.x:60
Var.kind
meta native Symbol Var.kind(Var v)
Returns the Symbol naming the coarse category of v’s payload.
The categories are <integer>, <floating>, <symbol>, <object>,
<pointer>, <reference>, and <void>, and every tag belongs to exactly
one. Use kind when a group of families is treated alike. All twelve
integer widths answer <integer>, and every builtin class handle such as
String, List, Map, and File answers <object>.
<pointer> means a raw C pointer such as <u8*>, while <reference>
means a pointer to an object handle such as <string*>. NaN and the
infinities are <floating>. Only void is <void>.
Source: lib/var/encoding.x:178
Var.known_tag
int Var.known_tag(Symbol tag)
Reports whether tag has a built-in encoding or declared custom class.
Source: lib/var/var.x:62
Var.long_double_value
meta native long double Var.long_double_value(Var v)
Returns the payload of an <ldouble> box, or 0.0 if v has another tag.
This is the only reader that preserves a long double. Every other
floating tag, <f64> included, yields 0.0 here instead of being widened.
Var.floating is the general floating reader.
A tag mismatch yields 0.0.
Source: lib/var/numbers.x:306
Var.long_long_value
meta native long long Var.long_long_value(Var v)
Returns an <llong> box’s signed payload, or 0 for another tag.
Source: lib/var/numbers.x:292
Var.long_value
meta native long Var.long_value(Var v)
Returns the payload of a <long> box, or 0 if v has a different tag.
The test is on the tag, so a <ulong>, <llong>, or <i32> value
reads as 0 with no complaint. Var.integer accepts any integer family;
use this one when the tag is known and the payload must survive intact.
A tag mismatch yields 0.
Source: lib/var/numbers.x:276
Var.parse
meta native Var Var.parse(String str, Symbol kind)
Parses str as source text of kind kind and returns the boxed value.
The kinds understood are <int>, <float>, <double>, <string>,
<symbol>, and <char>. For <string>, matching %"..." or "..."
delimiters are removed; unquoted input is also accepted, and either form
is unescaped. <char> expects 'a' complete with its quotes and produces
an <i32>. Both <float> and <double> produce an <f64>; there is no
path here to <f32>.
Integer and floating kinds require the whole input to parse, apart from
surrounding whitespace. Malformed input, trailing text, a value outside
the native reader’s range, or an <int> outside int range returns
void, so a parsed numeric zero remains distinguishable from failure.
<symbol> accepts the leading atom or <...> Symbol literal and ignores
trailing text; no recognized leading Symbol produces the zero Symbol. A
kind this function does not handle returns void, and a bad character
literal gives <i32> -1.
Var count = Var.parse("42", <int>);
Var broken = Var.parse("abc", <int>);
Var refused = Var.parse("3", <u8>);
printf("%s=%s %s=%s refused=%d\n", count.tag().str(), count,
broken.tag().str(), broken, refused is void);
Raises: <alloc-fail> while constructing String or quoted-Symbol
output.
Source: lib/var/construction.x:205
Var.pointer
void *Var.pointer(Var v)
Returns the raw address stored in v, or NULL if it holds no address.
Every pointer, reference, and object family shares one decoder: the
payload is masked free of the subtype bits its family reserves, so the
result is the stored low-48-bit address for a <u8*>, a <string>
handle, and a registered custom object. The returned pointer is borrowed;
this operation does not retain it or change its lifetime. A value that is
not address-shaped, such as an integer, a double, a Symbol, a wide box,
or void, reads as NULL, and nothing distinguishes that from a stored
null pointer.
Nothing here proves that an accepted address is live or came from the
right constructor; that remains the typed API’s precondition. This raw
decoder also accepts some reserved pointer-shaped bit patterns. Validate
external bits with Var.encoding_valid, then confirm the family with
Var.tag or Var.is before trusting the result.
Source: lib/var/classes.x:181
Var.register_object_tag
int Var.register_object_tag(Symbol tag)
Declares custom boxed-object tag and returns 0.
Declaring spends no Var row; the first box of a value assigns one.
Declaring a tag again returns 0; NULL or a built-in tag returns -1 without
changing the registry. Declaration must finish before the first successful
Thread.start; afterward it raises <bad-state>. Native registry-mutex
failure aborts.
Source: lib/var/classes.x:207
Var.tag
meta native Symbol Var.tag(Var v)
Returns the Symbol naming the exact family of v’s payload.
The tag names one family: <i32>, <string>, <f64>, <symbol>, or a
registered custom object tag. Built-in families have one row in the
encoding table in this file. Use Var.kind for a group of
families and Var.is to test one family.
Raw Null, the all-zero Var written (Var) { .u64 = 0 }, is a native
null pointer. It decodes as <p48>; there is no dedicated null family.
Test it with Var.is_null. An encoding matching no reserved row decodes
as <f64>, since the shifted double range covers everything left over.
Var raw = (Var) { .u64 = 0 };
printf("%s %s\n", raw.tag().str(), void.tag().str());
Source: lib/var/encoding.x:151
Var.ulong_long_value
meta native unsigned long long Var.ulong_long_value(Var v)
Returns a <ullong> box’s unsigned payload, or 0 for another tag.
Source: lib/var/numbers.x:296
Var.ulong_value
meta native unsigned long Var.ulong_value(Var v)
Returns the payload of a <ulong> box, or 0 if v has a different tag.
Prefer this to Var.integer for a <ulong>: the general reader casts the
payload to long, which reinterprets anything above LONG_MAX as
negative, while this reader returns the unsigned value. A tag that is
not <ulong> yields 0 silently, so test with Var.is when the tag is in
doubt.
A tag mismatch yields 0.
Source: lib/var/numbers.x:288
Var.wide_compare
int Var.wide_compare(Var a, Var b)
Orders two wide boxes carrying the same tag, returning -1, 0, or 1.
Integer families delegate to Var.integer_compare. An <ldouble> pair
compares as long double and falls back to a byte comparison when neither
operand is less than the other, so distinct NaN representations still
order deterministically.
0 means equal, and it is also the answer for mismatched tags and for an
argument that is not a wide box. Check the tags first, or use
Var.compare, the runtime’s full ordering.
Source: lib/var/numbers.x:377
Var.wide_equal
int Var.wide_equal(Var a, Var b)
Reports content equality for supported wide scalar boxes.
Boxed <long>, <ulong>, <llong>, <ullong>, and <ldouble> values
are separate allocations, so bit identity says nothing about their
contents. This is the payload comparison that Var.equal and === use
for those tags. An <ldouble> pair is compared byte for byte, so two NaNs
sharing one representation compare equal here.
A 0 result means “not equal as wide boxes”. It also covers an argument
that is not a wide box and a pair whose tags differ. For a general
equality test use Var.equal, which covers every family, or ==, which
compares two numbers as C does.
Source: lib/var/numbers.x:348
Var.wide_hash
unsigned Var.wide_hash(Var v)
Returns a supported wide scalar box’s content hash, or 0 otherwise.
Source: lib/var/numbers.x:316
Runtime-internal callables
These callables connect runtime translation units. They are documented for source readers but are not supported as user API.
| Function | Summary |
|---|---|
Var.clone_wide | Clones the wide numeric value into a new box in the active Scope. |
Var.custom_descriptor_index | Returns a boxed custom object’s row, or -1 for another value. |
Var.move_wide_to | Moves a wide numeric box into the destination Scope held by scope. |
Var.wide_owner | Returns the Scope owning a live wide numeric box, or NULL otherwise. |
Var
Var.clone_wide
meta native Var Var.clone_wide(Var value)
Clones the wide numeric value into a new box in the active Scope.
The clone is == and === to value but has its own box, so Var.same
tells the two apart. Returns void when value is not wide.
Raises: <alloc-fail> when the clone cannot be allocated, or <bad-enc>
if its address cannot be represented in a Var.
Source: lib/var/numbers.x:131
Var.custom_descriptor_index
int Var.custom_descriptor_index(Var value)
Returns a boxed custom object’s row, or -1 for another value.
Rows below 30 belong to one class each; row 30 holds every overflow heap
class and row 31 every overflow record.
Source: lib/var/encoding.x:283
Var.move_wide_to
Self Var.move_wide_to(Self value, Scope *scope)
Moves a wide numeric box into the destination Scope held by scope.
The box is not copied and value keeps its identity. If the destination
slot is NULL, a new Scope is created there. Returns value unchanged for
another family.
For a wide value, raises <bad-arg> when scope is NULL, or
<alloc-fail> when a new destination Scope cannot be allocated.
Ownership is unchanged on failure.
Source: lib/var/numbers.x:155
Var.wide_owner
Scope Var.wide_owner(Var v)
Returns the Scope owning a live wide numeric box, or NULL otherwise.
Source: lib/var/numbers.x:162
Public types
| Type | Kind | Summary |
|---|---|---|
TagId | enum | Names the built-in Var tags in var-tags.x ledger order, which is the order of x2c_var_taginfo; lib/var-ledger.x checks the two agree. |
VarDecodeGroup | struct | Resolves one encoding top: the selector is the middle field when by_middle is set and the bottom field under mask otherwise, and ids maps it to a TagId, or _invalid_ where no tag has it. |
VarTagInfo | struct | Describes one built-in Var tag’s kind and encoding fields. |
TagId
typedef enum TagId { _invalid_ = -1, _u8_, _i8_, _u16_, _i16_, _u32_, _i32_, _f32_, _u48_, _i48_, _p48_, _f64_, _long_, _ulong_, _llong_, _ullong_, _ldouble_, _u8_p_, _i8_p_, _u16_p_, _i16_p_, _u32_p_, _i32_p_, _f32_p_, _ulong_p_, _long_p_, _f64_p_, _ullong_p_, _llong_p_, _ldouble_p_, _p48_p_, _u8_pp_, _i8_pp_, _u16_pp_, _i16_pp_, _u32_pp_, _i32_pp_, _f32_pp_, _ulong_pp_, _long_pp_, _f64_pp_, _ullong_pp_, _llong_pp_, _ldouble_pp_, _array_, _block_, _buffer_, _bytes_, _context_, _error_, _file_, _func_, _iter_, _lambda_, _list_, _logger_, _map_, _mutex_, _pipe_, _proc_, _regexp_, _rope_, _scope_, _slice_, _socket_, _stream_, _string_, _symbol_, _tensor_, _thread_, _token_, _var_, _array_p_, _block_p_, _buffer_p_, _bytes_p_, _context_p_, _error_p_, _file_p_, _func_p_, _iter_p_, _lambda_p_, _list_p_, _logger_p_, _map_p_, _mutex_p_, _pipe_p_, _proc_p_, _regexp_p_, _rope_p_, _scope_p_, _slice_p_, _socket_p_, _stream_p_, _string_p_, _symbol_p_, _tensor_p_, _thread_p_, _token_p_, _var_p_, _nan_, _neginf_, _posinf_, _void_, _tag_count_ } TagId
Names the built-in Var tags in var-tags.x ledger order, which
is the order of x2c_var_taginfo; lib/var-ledger.x checks the two
agree.
Source: lib/var/var.x:28
VarDecodeGroup
typedef struct VarDecodeGroup { unsigned char mask, by_middle; signed char ids[8]; } VarDecodeGroup
Resolves one encoding top: the selector is the middle field when
by_middle is set and the bottom field under mask otherwise, and
ids maps it to a TagId, or _invalid_ where no tag has it.
Source: lib/var/var.x:56
VarTagInfo
typedef struct VarTagInfo { Symbol tag, kind; unsigned long top, middle, bottom; } VarTagInfo
Describes one built-in Var tag’s kind and encoding fields.
Source: lib/var/var.x:48
Design notes
Var owns the one-word encoding of dynamic values. Doubles keep their IEEE
754 bits, and the special-value ranges carry tagged payloads, native
pointers, Symbols, and boxes for wide scalars and custom classes. A
Var preserves its runtime kind, and void is excluded from
value-bearing protocols.
Tests and examples
make verify (unittest/test-var.x) and make examples (type-conversion-matrix).