Orb Programming Language

Attributes

Attributes can be placed on a node to add extra information. There are two types of attributes.

: is used to attach a type attribute to a node. We’ve used these in sym instructions and function arguments.

    sym x:i32;

:: is used to attach non-type attributes to a node. For example, we’ve seen ::noDrop on function arguments and ::preprocess on macro arguments.

There can be multiple non-type attributes attached to a single node. Each has a name and a value. If the value is not specified, it will implicitly be set to true.

# single attribute with no value provided
a::attr0

# single attribute with a value provided
a::((attr0 val0))

# multiple attributes with no values provided
a::(attr0 attr1)

# multiple attributes, some have values provided
a::(attr0 (attr1 val1) (attr2 val2))

The attr?? and attrOf special forms are used for attribute inspection. attr?? checks whether a node has an attribute with a given name. attrOf fetches the value of that attribute from the node.

The name of type attribute is type. Note that a node’s type attribute is a different concept from the type of that node.

fnc main () () {
    eval (sym (x 0::((myAttr 10))));

    attr?? x myAttr; # true
    attrOf x myAttr; # 10

    attr?? x fakeAttr; # false

    attr?? 0:i32 type; # true
    attrOf 0:i32 type; # i32
};

Data types can have attributes attached to their type. This is useful for additional type inspection.

import "std/io.orb";

data Foo {
    x:i32
}::((xTy i32));

fnc main () () {
    eval (sym foo:Foo);

    eval (if (attr?? (typeOf foo) xTy) {
        message (attrOf (typeOf foo) xTy); # prints i32
    });
};

Attributes are useful in conjunction with macro arguments, as they preserve their attributes during the invocation.

import "base.orb";

mac myFoo (a) {
    if (&& (attr?? a selection) (== (attrOf a selection) diffBehaviour)) {
        # ...
    };

    # ...
};