next up previous contents index
Next: 2.2 Syntax Up: 2. Onyx Language Reference Previous: 2. Onyx Language Reference   Contents   Index


2.1 Objects

An Onyx object has three aspects: type, attribute, and value.

Objects fall into two categories according to type: simple and composite. A simple object takes up no memory of its own; it uses space within a stack, array, or dictionary. A composite object requires space of its own in addition to the space taken up in stacks, arrays, or dictionaries to refer to the composite object. See Table 2.1 for object type classifications.


Table 2.1: Simple and composite types
Simple Composite
boolean array
fino condition
integer dict
mark file
name hook
null mutex
operator regex
pmark regsub
real stack
  string
  thread


There can be multiple references that refer to the same memory backing composite objects. In most cases, composite objects that refer to the same memory are indistinguishable, but for arrays and strings, composite objects may only be able to access a subset of the total memory backing them. This behavior is described in detail later.

All objects have a literal, executable, or evaluatable attribute associated with them. Composite objects each have their own attribute, even for composite objects that share the same backing memory. Objects are ``interpreted'' when they are encountered directly by the interpreter. Objects can also be ``evaluated''. One of two actions is taken when an object is interpreted or evaluated:

Table 2.2 enumerates under what circumstances object interpretation results in execution. Table 2.3 enumerates under what circumstances object evaluation results in execution. Note that executable arrays are the only objects that behave differently when interpreted versus evaluated.

In practice, attributes are only useful for types that can be executed. Attributes are not considered in equality test operations.


Table 2.2: Interpretation of objects by type and attribute
Type Attribute
  literal executable evaluatable
array data data code
boolean data data data
condition data data data
dict data data data
file data code code
fino data data data
hook data code code
integer data data data
mark data data data
mutex data data data
name data code code
null data code code
operator data code code
pmark data data data
real data data data
regex data data data
regsub data data data
stack data data data
string data code code
thread data data data



Table 2.3: Evaluation of objects by type and attribute
Type Attribute
  literal executable evaluatable
array data code code
boolean data data data
condition data data data
dict data data data
file data code code
fino data data data
hook data code code
integer data data data
mark data data data
mutex data data data
name data code code
null data code code
operator data code code
pmark data data data
real data data data
regex data data data
regsub data data data
stack data data data
string data code code
thread data data data


array:
An array is an ordered sequence of objects of any type. The sequence of objects contained in an array is indexed starting at 0. References to existing arrays may be constructed such that a contiguous subsequence is visible. The following code creates such an array:

[0 1 2 3 4]
1 3 getinterval

After the code executes, the array left on the operand stack looks like:

[1 2 3]

Executable arrays are in effect procedures. When an array is executed, its elements are sequentially interpreted.

boolean:
A boolean can have two values: true or false.

condition:
A condition is used for thread synchronization. The standard operations on a condition are to wait and to signal.

dict:
A dict (short for dictionary) is a collection of key/value pairs. Other names for dictionaries include ``associative array'' and ``hash''. A key can be of any type, though in most cases, keys are of type name. A value can also be of any type.

file:
A file is a handle to an ordered sequence of bytes with a current position. Read and write permissions are set when a file object is created.

When an executable file is executed, it is used as a source of Onyx code. Data are sequentially read from the file and interpreted until the end of the file is reached.

fino:
A fino (first in, never out) is used as a stack marker when constructing stacks.

hook:
The hook type is not used by the core Onyx language. It can be used by applications that extend the interpreter as a container object. Hooks can be executed, but the results are application dependent.

Each hook has a tag associated with it that can used by C extension code as a form of type checking. By default, the tag is a null object. In most cases, an application that extends the interpreter using hook objects will set hook tags to be name objects.

integer:
An integer is a signed integer in the range $-2^{63}$ to $2^{63} - 1$.

mark:
A mark is used as a stack marker for various stack operations.

mutex:
A mutex is a mutual exclusion lock. Mutexes cannot be acquired recursively, and the application must take care to unlock mutexes before allowing them to be garbage collected (whether during normal program execution or at program termination).

name:
A name is a key that uniquely identifies a sequence of characters. Two name objects that correspond to the same sequence of characters can be compared for equality with the same approximate cost as comparing two integers for equality. Names are typically used as keys in dictionaries.

When an executable name is executed, the topmost value in the dictionary stack associated with the name is evaluated.

null:
A null has no significance other than its existence. When an executable null is executed, it does nothing. Executable nulls can be useful as place holders that can later be replaced with useful code, or for replacing obsolete code so that the code is no longer executed.

operator:
An operator is an operation that is built in to the interpreter. Operators can be executed.

pmark:
A pmark is used as a stack marker when creating procedures in deferred execution mode (i.e. procedures that use the {} syntax). The application will only encounter pmarks in error conditions, and there is never a reason for an application to explicitly create a pmark.

real:
A real is a double precision (64 bit) floating point number.

regex:
A regex encapsulates a regular expression and associated flags, which can be used to find substring matches within an input string.

regsub:
A regsub encapsulates a regular expression, substitution template, and associated flags, which can be used to do substring substitutions matches and create an output string from input string.

stack:
A stack provides LIFO (last in, first out) access to objects that it contains, as well as some more advanced access methods. An application can create, then manipulate stacks in much the same way that the operand stack can be manipulated.

string:
A string is an ordered sequence of 8 bit characters. The bytes contained in an string are indexed starting at 0. References to existing strings may be constructed such that a contiguous subsequence is visible. The following code creates such a string:

`abcde'
1 3 getinterval

After the code executes, the string left on the operand stack looks like:

`bcd'

When an executable string is executed, its contents are used as a source of Onyx code.

thread:
A thread object serves as a handle for operations such as detaching and joining.


next up previous contents index
Next: 2.2 Syntax Up: 2. Onyx Language Reference Previous: 2. Onyx Language Reference   Contents   Index
Jason Evans 2003-01-31