Reduct  v4.0.5-1-g4851deb
A functional and immutable language.
Loading...
Searching...
No Matches
Atoms

Detailed Description

Atoms represent all strings within a Reduct expression, as such it also represents anything that a string can be, including numbers and natives.

Interning

Some atoms, primarily atoms loaded during initial parsing, are "interned", meaning they are stored in a global map to ensure that only one instance of a given string exists at any time. This improves memory usage but primarily it allows us to cache if an atom represents a number or a native function, avoiding repeated parsing or lookups during execution.

See also
Wikipedia String interning

Small and Large Strings

For small strings, of a length less than REDUCT_ATOM_SMALL_MAX, the string data is stored directly within the atom structure.

For larger strings, the data is allocated from a dedicated atom stack, with the atom referencing this stack to prevent the garbage collector from collecting it.

Substrings and Superstrings

The stack system also allows multiple atoms to share the same buffer within a stack.

For example, if we wish to create an atom containing a substring of a large atom, we can simply point to the middle of the existing buffer and reference the same stack.

Or, if we wish to create an atom that uses another atom as a prefix, and that other atom happens to be at the end of its stack, we can simply extend the allocation in place and return a new atom pointing to the same buffer.

Data Structures

struct  reduct_atom_t
 Atom structure. More...
 
struct  reduct_atom_global_t
 Global atom-related environment structure. More...
 

Macros

#define REDUCT_ATOM_MAP_INITIAL   64
 The initial size of the atom map.
 
#define REDUCT_ATOM_MAP_GROWTH   2
 The growth factor of the atom map.
 
#define REDUCT_ATOM_SMALL_MAX   16
 The maximum length of a small atom.
 
#define REDUCT_ATOM_TOMBSTONE   ((reduct_atom_t*)(uintptr_t)1)
 Tombstone value for the atom map.
 
#define REDUCT_ATOM_INDEX_NONE   ((uint32_t)-1)
 The value of an unindexed atom.
 
#define REDUCT_ATOM_FLAG_NONE   0
 No flags.
 
#define REDUCT_ATOM_FLAG_NUMBER   (1 << 0)
 Atom is known to be number shaped.
 
#define REDUCT_ATOM_FLAG_INTRINSIC   (1 << 1)
 Atom is known to represent an intrinsic.
 
#define REDUCT_ATOM_FLAG_NATIVE   (1 << 2)
 Atom is known to represent a native function.
 
#define REDUCT_ATOM_FLAG_NUMBER_CHECKED   (1 << 3)
 Atom has been checked for number shaping.
 
#define REDUCT_ATOM_FLAG_NATIVE_CHECKED   (1 << 4)
 Atom has been checked for a native function.
 
#define REDUCT_ATOM_FLAG_LARGE   (1 << 5)
 Atom has an allocated buffer within a stack.
 
#define REDUCT_ATOM_FLAG_SCHEMA   (1 << 6)
 Atom is a schema field.
 
#define REDUCT_ATOM_FLAG_QUOTED   (1 << 7)
 Atom is quoted.
 
#define REDUCT_FNV_PRIME   16777619U
 FNV-1a 32-bit prime.
 
#define REDUCT_FNV_OFFSET   2166136261U
 FNV-1a 32-bit offset basis.
 

Typedefs

typedef uint8_t reduct_atom_flags_t
 

Enumerations

enum  reduct_atom_lookup_flags_t { REDUCT_ATOM_LOOKUP_NONE = 0 , REDUCT_ATOM_LOOKUP_QUOTED = 1 << 0 }
 Atom lookup flags. More...
 

Functions

REDUCT_API void reduct_atom_global_init (reduct_atom_global_t *global)
 Initialize a global atom state.
 
REDUCT_API void reduct_atom_global_deinit (reduct_atom_global_t *global)
 Deinitialize a global atom state.
 
REDUCT_API bool reduct_atom_is_equal (reduct_atom_t *atom, const char *str, size_t len)
 Check if an atom is equal to a string.
 
REDUCT_API reduct_atom_treduct_atom_new (struct reduct *reduct, size_t len)
 Create an atom with a reserved size.
 
REDUCT_API reduct_atom_treduct_atom_new_string (struct reduct *reduct, const char *str)
 Create an atom from a null-terminated string.
 
REDUCT_API reduct_atom_treduct_atom_new_number (struct reduct *reduct, double value)
 Create an atom from a number value.
 
REDUCT_API reduct_atom_treduct_atom_new_native (struct reduct *reduct, reduct_native_fn native)
 Create an atom for a anonymous native function.
 
REDUCT_API bool reduct_atom_intern (struct reduct *reduct, reduct_atom_t *atom)
 Intern an existing atom into the Reduct structure.
 
REDUCT_API reduct_atom_treduct_atom_lookup (struct reduct *reduct, const char *str, size_t len, reduct_atom_lookup_flags_t flags)
 Lookup an interned atom in the Reduct structure.
 
REDUCT_API reduct_atom_lookup_flags_t reduct_atom_get_lookup_flags (reduct_atom_t *atom)
 Retrieve the lookup flags required to lookup this specific atom.
 
static REDUCT_ALWAYS_INLINE reduct_atom_treduct_atom_ensure_interned (struct reduct *reduct, reduct_atom_t *atom)
 Ensure an atom is interned.
 
REDUCT_API void reduct_atom_check_number (reduct_atom_t *atom)
 Cache if an atom is a number.
 
REDUCT_API void reduct_atom_check_native (struct reduct *reduct, reduct_atom_t *atom)
 Cache if an atom is a native function.
 
REDUCT_API void reduct_atom_retain (struct reduct *reduct, reduct_atom_t *atom)
 Retain an atom, preventing it from being collected by the garbage collector.
 
REDUCT_API void reduct_atom_release (struct reduct *reduct, reduct_atom_t *atom)
 Release an atom, potentially allowing the garbage collector to collect it.
 
static REDUCT_ALWAYS_INLINE bool reduct_atom_is_intrinsic (struct reduct *reduct, reduct_atom_t *atom)
 Check if an atom is an intrinsic.
 
static bool reduct_atom_is_native (struct reduct *reduct, reduct_atom_t *atom)
 Check if an atom is a native function.
 
static REDUCT_ALWAYS_INLINE bool reduct_atom_is_number (reduct_atom_t *atom)
 Check if an atom is number-shaped.
 
static REDUCT_ALWAYS_INLINE double reduct_atom_get_number (reduct_atom_t *atom)
 Get the number value of an atom.
 
REDUCT_API reduct_atom_treduct_atom_substr (struct reduct *reduct, reduct_atom_t *atom, size_t start, size_t len)
 Create a substring of an existing atom.
 
REDUCT_API reduct_atom_treduct_atom_superstr (struct reduct *reduct, reduct_atom_t *atom, size_t len)
 Create a superstring of an existing atom.
 
static REDUCT_ALWAYS_INLINE reduct_atom_treduct_atom_new_copy (struct reduct *reduct, const char *data, size_t len)
 Create a new atom by copying data directly into it.
 
REDUCT_API int64_t reduct_atom_as_int (struct reduct *reduct, reduct_atom_t *atom)
 Retrieve an integer value from an atom, regardless of if it is quoted or not.
 
REDUCT_API double reduct_atom_as_number (struct reduct *reduct, reduct_atom_t *atom)
 Retrieve a number value from an atom, regardless of if it is quoted or not.
 

Macro Definition Documentation

◆ REDUCT_ATOM_MAP_INITIAL

#define REDUCT_ATOM_MAP_INITIAL   64

The initial size of the atom map.

Definition at line 55 of file atom.h.

◆ REDUCT_ATOM_MAP_GROWTH

#define REDUCT_ATOM_MAP_GROWTH   2

The growth factor of the atom map.

Definition at line 56 of file atom.h.

◆ REDUCT_ATOM_SMALL_MAX

#define REDUCT_ATOM_SMALL_MAX   16

The maximum length of a small atom.

Definition at line 57 of file atom.h.

◆ REDUCT_ATOM_TOMBSTONE

#define REDUCT_ATOM_TOMBSTONE   ((reduct_atom_t*)(uintptr_t)1)

Tombstone value for the atom map.

Definition at line 59 of file atom.h.

◆ REDUCT_ATOM_INDEX_NONE

#define REDUCT_ATOM_INDEX_NONE   ((uint32_t)-1)

The value of an unindexed atom.

Definition at line 61 of file atom.h.

◆ REDUCT_ATOM_FLAG_NONE

#define REDUCT_ATOM_FLAG_NONE   0

No flags.

Definition at line 73 of file atom.h.

◆ REDUCT_ATOM_FLAG_NUMBER

#define REDUCT_ATOM_FLAG_NUMBER   (1 << 0)

Atom is known to be number shaped.

Definition at line 74 of file atom.h.

◆ REDUCT_ATOM_FLAG_INTRINSIC

#define REDUCT_ATOM_FLAG_INTRINSIC   (1 << 1)

Atom is known to represent an intrinsic.

Definition at line 75 of file atom.h.

◆ REDUCT_ATOM_FLAG_NATIVE

#define REDUCT_ATOM_FLAG_NATIVE   (1 << 2)

Atom is known to represent a native function.

Definition at line 76 of file atom.h.

◆ REDUCT_ATOM_FLAG_NUMBER_CHECKED

#define REDUCT_ATOM_FLAG_NUMBER_CHECKED   (1 << 3)

Atom has been checked for number shaping.

Definition at line 77 of file atom.h.

◆ REDUCT_ATOM_FLAG_NATIVE_CHECKED

#define REDUCT_ATOM_FLAG_NATIVE_CHECKED   (1 << 4)

Atom has been checked for a native function.

Definition at line 78 of file atom.h.

◆ REDUCT_ATOM_FLAG_LARGE

#define REDUCT_ATOM_FLAG_LARGE   (1 << 5)

Atom has an allocated buffer within a stack.

Definition at line 79 of file atom.h.

◆ REDUCT_ATOM_FLAG_SCHEMA

#define REDUCT_ATOM_FLAG_SCHEMA   (1 << 6)

Atom is a schema field.

Definition at line 80 of file atom.h.

◆ REDUCT_ATOM_FLAG_QUOTED

#define REDUCT_ATOM_FLAG_QUOTED   (1 << 7)

Atom is quoted.

Definition at line 81 of file atom.h.

◆ REDUCT_FNV_PRIME

#define REDUCT_FNV_PRIME   16777619U

FNV-1a 32-bit prime.

Definition at line 121 of file atom.h.

◆ REDUCT_FNV_OFFSET

#define REDUCT_FNV_OFFSET   2166136261U

FNV-1a 32-bit offset basis.

Definition at line 122 of file atom.h.

Typedef Documentation

◆ reduct_atom_flags_t

typedef uint8_t reduct_atom_flags_t

Definition at line 72 of file atom.h.

Enumeration Type Documentation

◆ reduct_atom_lookup_flags_t

Atom lookup flags.

Enumerator
REDUCT_ATOM_LOOKUP_NONE 

No flags.

REDUCT_ATOM_LOOKUP_QUOTED 

Atom should be explicitly quoted.

Definition at line 66 of file atom.h.

Function Documentation

◆ reduct_atom_global_init()

REDUCT_API void reduct_atom_global_init ( reduct_atom_global_t global)

Initialize a global atom state.

Parameters
globalPointer to the global atom state to initialize.

◆ reduct_atom_global_deinit()

REDUCT_API void reduct_atom_global_deinit ( reduct_atom_global_t global)

Deinitialize a global atom state.

Parameters
globalPointer to the global atom state to deinitialize.

◆ reduct_atom_is_equal()

REDUCT_API bool reduct_atom_is_equal ( reduct_atom_t atom,
const char *  str,
size_t  len 
)

Check if an atom is equal to a string.

Parameters
atomPointer to the atom.
strThe string to compare.
lenThe length of the string.
Returns
true if the atom is equal to the string, false otherwise.

◆ reduct_atom_new()

REDUCT_API reduct_atom_t * reduct_atom_new ( struct reduct *  reduct,
size_t  len 
)

Create an atom with a reserved size.

Parameters
reductPointer to the Reduct structure.
dataThe raw buffer to create the atom from.
lenThe length of the buffer.
Returns
A pointer to the atom.
Here is the caller graph for this function:

◆ reduct_atom_new_string()

REDUCT_API reduct_atom_t * reduct_atom_new_string ( struct reduct *  reduct,
const char *  str 
)

Create an atom from a null-terminated string.

Parameters
reductPointer to the Reduct structure.
strThe null-terminated string.
Returns
A pointer to the atom.

◆ reduct_atom_new_number()

REDUCT_API reduct_atom_t * reduct_atom_new_number ( struct reduct *  reduct,
double  value 
)

Create an atom from a number value.

Parameters
reductPointer to the Reduct structure.
valueThe number value.
Returns
A pointer to the atom.

◆ reduct_atom_new_native()

REDUCT_API reduct_atom_t * reduct_atom_new_native ( struct reduct *  reduct,
reduct_native_fn  native 
)

Create an atom for a anonymous native function.

Parameters
reductPointer to the Reduct structure.
nativeThe native function pointer.
Returns
A pointer to the atom.

◆ reduct_atom_intern()

REDUCT_API bool reduct_atom_intern ( struct reduct *  reduct,
reduct_atom_t atom 
)

Intern an existing atom into the Reduct structure.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom to intern.
Returns
true if the atom is already interned or it was successfully added, false if an identical atom is already interned.
Here is the caller graph for this function:

◆ reduct_atom_lookup()

REDUCT_API reduct_atom_t * reduct_atom_lookup ( struct reduct *  reduct,
const char *  str,
size_t  len,
reduct_atom_lookup_flags_t  flags 
)

Lookup an interned atom in the Reduct structure.

Will create and intern a new atom if it does not exist.

Parameters
reductPointer to the Reduct structure.
strThe string to lookup.
lenThe length of the string.
flagsLookup flags to alter the interning behavior.
Returns
A pointer to the atom.
Here is the caller graph for this function:

◆ reduct_atom_get_lookup_flags()

REDUCT_API reduct_atom_lookup_flags_t reduct_atom_get_lookup_flags ( reduct_atom_t atom)

Retrieve the lookup flags required to lookup this specific atom.

Really just used to check if an atom is quoted or not.

Parameters
atomThe atom to check.
Returns
The lookup flags.
Here is the caller graph for this function:

◆ reduct_atom_ensure_interned()

static REDUCT_ALWAYS_INLINE reduct_atom_t * reduct_atom_ensure_interned ( struct reduct *  reduct,
reduct_atom_t atom 
)
inlinestatic

Ensure an atom is interned.

If the atom is already interned, it returns the existing atom. If an identical atom is already interned, the already interned atom is returned. Otherwise, it interns the atom and returns it.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom to ensure is interned.
Returns
A pointer to the interned atom.

Definition at line 244 of file atom.h.

Here is the call graph for this function:

◆ reduct_atom_check_number()

REDUCT_API void reduct_atom_check_number ( reduct_atom_t atom)

Cache if an atom is a number.

Parameters
atomPointer to the atom.
Here is the caller graph for this function:

◆ reduct_atom_check_native()

REDUCT_API void reduct_atom_check_native ( struct reduct *  reduct,
reduct_atom_t atom 
)

Cache if an atom is a native function.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.
Here is the caller graph for this function:

◆ reduct_atom_retain()

REDUCT_API void reduct_atom_retain ( struct reduct *  reduct,
reduct_atom_t atom 
)

Retain an atom, preventing it from being collected by the garbage collector.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.

◆ reduct_atom_release()

REDUCT_API void reduct_atom_release ( struct reduct *  reduct,
reduct_atom_t atom 
)

Release an atom, potentially allowing the garbage collector to collect it.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.

◆ reduct_atom_is_intrinsic()

static REDUCT_ALWAYS_INLINE bool reduct_atom_is_intrinsic ( struct reduct *  reduct,
reduct_atom_t atom 
)
inlinestatic

Check if an atom is an intrinsic.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.
Returns
true if the atom is an intrinsic, false otherwise.

Definition at line 298 of file atom.h.

Here is the call graph for this function:

◆ reduct_atom_is_native()

static bool reduct_atom_is_native ( struct reduct *  reduct,
reduct_atom_t atom 
)
inlinestatic

Check if an atom is a native function.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.
Returns
true if the atom is a native function, false otherwise.

Definition at line 314 of file atom.h.

Here is the call graph for this function:

◆ reduct_atom_is_number()

static REDUCT_ALWAYS_INLINE bool reduct_atom_is_number ( reduct_atom_t atom)
inlinestatic

Check if an atom is number-shaped.

Parameters
atomPointer to the atom.
Returns
true if the atom is a number, false otherwise.

Definition at line 329 of file atom.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reduct_atom_get_number()

static REDUCT_ALWAYS_INLINE double reduct_atom_get_number ( reduct_atom_t atom)
inlinestatic

Get the number value of an atom.

Parameters
atomPointer to the atom.
Returns
The number value.

Definition at line 344 of file atom.h.

Here is the call graph for this function:

◆ reduct_atom_substr()

REDUCT_API reduct_atom_t * reduct_atom_substr ( struct reduct *  reduct,
reduct_atom_t atom,
size_t  start,
size_t  len 
)

Create a substring of an existing atom.

Parameters
reductPointer to the Reduct structure.
atomPointer to the source atom.
startThe starting index.
lenThe length of the substring.
Returns
A pointer to the new atom.

◆ reduct_atom_superstr()

REDUCT_API reduct_atom_t * reduct_atom_superstr ( struct reduct *  reduct,
reduct_atom_t atom,
size_t  len 
)

Create a superstring of an existing atom.

If the atom is at the end of its stack and there is enough capacity, it will extend the existing allocation. Otherwise, it will allocate a new atom and copy the existing data.

Parameters
reductPointer to the Reduct structure.
atomPointer to the source atom.
lenThe new total length.
Returns
A pointer to the new atom.

◆ reduct_atom_new_copy()

static REDUCT_ALWAYS_INLINE reduct_atom_t * reduct_atom_new_copy ( struct reduct *  reduct,
const char *  data,
size_t  len 
)
inlinestatic

Create a new atom by copying data directly into it.

The atom is NOT interned and its hash is set to 0, avoiding the overhead of hash computation and map lookup.

Parameters
reductPointer to the Reduct structure.
dataThe data to copy.
lenThe length of the data.
Returns
A pointer to the new atom.

Definition at line 385 of file atom.h.

Here is the call graph for this function:

◆ reduct_atom_as_int()

REDUCT_API int64_t reduct_atom_as_int ( struct reduct *  reduct,
reduct_atom_t atom 
)

Retrieve an integer value from an atom, regardless of if it is quoted or not.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.
Returns
The integer value.
Here is the caller graph for this function:

◆ reduct_atom_as_number()

REDUCT_API double reduct_atom_as_number ( struct reduct *  reduct,
reduct_atom_t atom 
)

Retrieve a number value from an atom, regardless of if it is quoted or not.

Parameters
reductPointer to the Reduct structure.
atomPointer to the atom.
Returns
The number value.
Here is the caller graph for this function: