Structures

Structures are value types in XXML that are allocated on the stack rather than the heap, providing efficient, lightweight data containers with automatic RAII cleanup.

Overview

Structures provide an alternative to classes when you need high-performance, stack-allocated data containers. They're ideal for small, short-lived data aggregates.

FeatureDescription
Stack AllocationMemory allocated with alloca, not malloc
Value SemanticsProperties store values directly (not pointers)
RAII CleanupAutomatic destructor call when leaving scope
No InheritanceStructures cannot extend other types
Template SupportFull template parameter support

Basic Syntax

xxml
[ Structure <StructureName>
    [ Public <>
        Property <field1> Types Integer^;
        Property <field2> Types String^;

        Constructor Parameters (Parameter <f1> Types Integer%, Parameter <f2> Types String%) -> {
            Set field1 = f1;
            Set field2 = f2;
        }

        Destructor Parameters () -> {
            // Cleanup code (optional)
        }

        Method <someMethod> Returns Integer^ Parameters () -> {
            Return field1;
        }
    ]
]

Structure vs Class

Understanding when to use structures versus classes is key to writing efficient XXML code.

FeatureClassStructure
StorageHeap (malloc)Stack (alloca)
InheritanceSupportedNot supported
PropertiesStore pointersStore values directly
Default PassingBy referenceBy value (copy)

Memory Model Comparison

Class (Heap Allocation):

text
Variable: [ptr] ──────> Heap: [vtable_ptr][field1_ptr][field2_ptr]...
                               │            │
                               v            v
                          [vtable]    [field value]

Structure (Stack Allocation):

text
Stack Frame: [field1_value][field2_value]...
              └──── embedded directly ────┘

Example: Vec2 Structure

vec2.xxml
[ Structure <Vec2>
    [ Public <>
        Property <x> Types Double^;
        Property <y> Types Double^;

        Constructor Parameters (
            Parameter <px> Types Double%,
            Parameter <py> Types Double%
        ) -> {
            Set x = px;
            Set y = py;
        }

        Method <length> Returns Double^ Parameters () -> {
            Return x.multiply(x).add(y.multiply(y)).sqrt();
        }
    ]
]

[ Entrypoint
    {
        // v is allocated on the stack, not the heap
        Instantiate Vec2 As <v> = Vec2::Constructor(
            Double::Constructor(3.0),
            Double::Constructor(4.0)
        );

        // v.length() returns 5.0
        Run Console::printLine(v.length().toString());

        // v is automatically cleaned up when the entrypoint exits
        Exit(0);
    }
]

Note

Structures are allocated on the stack using LLVM's alloca instruction, providing no heap overhead, automatic cleanup when the function returns, and better cache locality.

Template Structures

Structures support template parameters just like classes:

xxml
[ Structure <Pair> <T Constrains None, U Constrains None>
    [ Public <>
        Property <first> Types T^;
        Property <second> Types U^;

        Constructor Parameters (Parameter <f> Types T%, Parameter <s> Types U%) -> {
            Set first = f;
            Set second = s;
        }
    ]
]

// Usage
Instantiate Pair<Integer, String> As <p> = Pair<Integer, String>::Constructor(
    Integer::Constructor(42),
    String::Constructor("hello")
);

When to Use Structures

Good Use Cases

  • Small, short-lived data aggregates
  • Performance-critical code (avoid heap allocation overhead)
  • Simple data containers without inheritance needs
  • Interop with C/C++ value types
xxml
// Good: Small coordinate pair
[ Structure <Point>
    [ Public <>
        Property <x> Types Integer^;
        Property <y> Types Integer^;
    ]
]

// Good: RGB color value
[ Structure <Color>
    [ Public <>
        Property <r> Types Integer^;
        Property <g> Types Integer^;
        Property <b> Types Integer^;
    ]
]

When to Use Class Instead

  • When inheritance is needed
  • For large data structures
  • When polymorphism or virtual methods are required
xxml
// Use Class: Needs inheritance
[ Class <Shape> Final Extends None
    [ Public <>
        Method <area> Returns Double^ Parameters () -> { ... }
    ]
]

// Use Class: Large data structure
[ Class <LargeBuffer> Final Extends None
    [ Private <>
        Property <data> Types Array<Integer>^;  // Large array
    ]
]

Warning

Keep structures small (under 64 bytes recommended). Large structures may cause stack overflow; use classes for large objects.

Limitations

  • No Inheritance: Structures cannot use Extends
  • No Polymorphism: No virtual methods or dynamic dispatch
  • Stack Size: Large structures may cause stack overflow
  • No Final Modifier: Structures are implicitly final

Next Steps

Learn about Classes for heap-allocated objects with inheritance, or explore Generics for template programming.