2.5. Types in "steve"

2.5.1. The int type

An int is a whole number, identical to the int type in C.

2.5.1.1. int operators

ints can be operated on using the following mathematical operators, which operate just like their C counterparts: +, -, *, /, % and ^ (power). Divisions or mods by zero are treated as errors and will stop the execution of the simulation. The absolute value of an integer is given by | integer expression |.

2.5.1.2. Conversions to Other Types

ints can be converted to floats automatically in expressions or during assignments, but cannot be converted to any other type.

2.5.2. The float type

A real number, also known as "double", identical to the double type in C. Internally, floats are represented by 8-byte doubles.

2.5.2.1. float Operators

All of the operators used for ints—including %—can also be applied to floats.

2.5.2.2. Conversions to Other Types

floats can be converted to (and from) ints automatically in expressions or assignments. floats cannot be converted to any other type.

2.5.3. The object Type

An object is an instance of a steve class.

2.5.3.1. object Operators

objects cannot used in mathematical expressions as some of the other types can. Instead, objects are mainly used for one type of expression: method calling. Method calling is outlined in the section Method Calls (Section 2.6.7).

2.5.3.2. Conversion to Other Types

Objects cannot be explicitly converted to other types. They do, however, have meaning as "boolean" (true or false) expressions in control structures (Section 2.7). If used in the context of a boolean expression (like an if statement, Section 2.7.1), the expression is true only if the variable refers to an active object. This means that an object variable which has not yet been associated with an instance in the simulation is false.

2.5.4. The vector Type

A vector is used to represent a point or vector in 3D space. A vector is expressed as three floating point numbers, such as (1.0, 2.0, 5.0).

2.5.4.1. vector Operators

Vectors may be added (+) to and subtracted (-) from other vectors, which yields another vector. Vectors may be multiplied (*) or divided (/) by ints or floats, which also results in other vectors. The length of the vector is given using the following construct: | vector expression |.

Some examples of using vectors follow:
v = (1, 2, 3).  # sets the vector to a constant vector.

v = v * 4.      # multiplies the vector by 4

v = v / |v|.    # normalizes the vector by dividing it by it's own 
				# length such that the new length is 1.

2.5.4.2. Conversions to Other Types

Vectors cannot be converted to any other types. They do, however, have meaning as "boolean" (true or false) expressions in control structures (Section 2.7). If used in the context of a boolean expression (like an if statement, Section 2.7.1), the vector will be true if it's length is greater than 0, and false if its length is equal to 0. This is to say that only the vector (0, 0, 0) is false in a boolean context.

2.5.5. matrix

A matrix in steve refers to a 3x3 matrix which describes a transformation in 3D space. Using transformation matrices is somewhat advanced and they are not generally used in most simulations. Still, they may be useful when dealing with physical simulation.

Matrices may be written in steve as three comma-separated vectors, enclosed in braces ('[' and ']'), as in this example:
# the matrix m will be initialized to:
#
# [ 1 2 3 ]
# [ 4 5 6 ]
# [ 7 8 9 ]

m = [ (1, 2, 3), (4, 5, 6), (7, 8, 9) ].

2.5.5.1. matrix Operators

Matrices may be multiplied (*), divided (/), added (+) to and subtracted (-) from other matrices. The results of these operations are other matrices.

Matrices may be multiplied (*) or divided (/) by scalars (ints and doubles). The result of these operations are other matrices.

Matrices may be used to transform vectors by multiplying the matrix times the vector (*). The result of this operation is a vector.

2.5.5.2. Conversions to Other Types

Matrices cannot be converted to any other types. They do, however, have meaning as "boolean" (true or false) expressions in control structures (Section 2.7). If used in the context of a boolean expression (like an if statement, Section 2.7.1), the expression will be true if there are any non-zero values in the matrix. This means that a matrix of all zeros will be false, while all other matrices are true.

2.5.6. The list Type

The list datatype allows you to keep a list of other variables. lists can contain any datatype, including other lists. lists can even contain multiple datatypes simultaneously.

lists are formed using the syntax { item1, item2, ... }.

Some simple examples of constructing lists are shown below:
myList = { 1, 2, 3.0 }.                 # a list of numbers (both int and float)
myList = { "a", "b", "c" }.             # a list of strings
myList = { "a", 30, new Mobile }.       # a list of mixed types
myList = { 1, "a", { "dog", "cow" } }.  # a list with a nested list

2.5.6.1. list Operators

The following operations can be used with list expressions:

  • push expression onto list: appends expression onto the end of list

  • pop list: removes the last element of list and returns it

  • prepend expression onto list: prepends expression onto the start of list

  • unprepend list: removes the first element of list and returns it

  • list{ expression }: returns the element of the list at offset expression. The expression index is zero based, as in C, such that 0 refers to the first element, 1 to the second, and so forth. If the offset expression is less than zero, or greater than the length of the list minus one (because the access is zero based), an error is triggered and the simulation is stopped.

  • list{ expression } = value: sets an element of the list at offset expression to value. The offset index is again zero based. If the offset expression is less than zero or greater than the size of the list an error is triggered and the simulation is stopped. If the offset expression is equal to the size of the list, the list is extended by one element; the operation has the same effect as pushing a value on to the end.

  • sort list with method-name: sorts list using the method specified with method-name. method-name must be a method which takes two list elements (the keywords are unimportant) and compares them, returning a negative number if the first list element belongs before the second in the sorted list, a positive number if the second belongs before the first, and 0 if the two entries are equal. In most cases, this confusing sounding method returns a certain value associated with one argument minus the same value in the other.

    Unlike the perl sort operator, sort operates on the list it is given and does not return a copy of it. This means that the original list is modified during the sort operation.

  • copylist list: copies the entire list. Normally, assigning a list to a variable will not copy the list but instead will yield two variables pointing to the same list.

  • | list |: gives the length of a list. Lists are automatically converted to integers when use in mathematical expressions, but this construct can be used too force the conversion.

2.5.6.2. Conversions to Other Types

lists can be converted to ints simply by using them in the context of integers. They can thus also be used as floats. In the event that the context of the expression does not force the list to become an integer, you can force it yourself by using it in a mathematical context:
myInt = (myList + 0).

2.5.7. The string Type

The string type holds a character string. A string is written in code (as in C) as a quoted string. For example, the built-in print operator is capable of printing strings:
print "this is a string".

2.5.7.1. string Operators

There are no string operators, per se, but simple variables can be embedded strings so that the strings are interpreted dynamically, as in Perl. The following, for example, will use the variable "self" in order to build the string which will then be printed:
print "my value is $self.".

2.5.7.2. Conversions to Other Types

strings can be converted to ints and floats, but not to any other types. types.

In the context of an int or a float, the string becomes the appropriate type by taking the numerical component of the string. For more information on this conversion, consult the man pages for the ANSI C atoi() (for ints) or atof() (for doubles) functions.

2.5.8. The hash Type

A hash is a type which works like a dictionary: it allows expressions ("values") to be stored and looked-up using other expressions as the "keys". The following example shows a steve hash being used like a dictionary:
dictionary (hash).

dictionary{ "dog" } = "a four-legged pet".
dictionary{ "fish" } = "a zero-legged pet".

# this will print the definition we stored above.

print "the definition of dog is ", dictionary{ "dog" }.

As shown in this example, we're able to store data using strings as the keys. When data is later retrieved from the hash table using the same key, the value stored previously is returned.

hashes are not limited to using strings as keys. They can use any valid type. The most useful application is a hash table which uses objects as keys. In this way, relationships between objects can be stored in a hash. Consider an object which wants to keep track of neighbors it has encountered previously:
# let's say that this method gets called when a neighbor is seen...
# if the neighbor has already been seen, print a message — otherwise,
# just add it to the hash for next time!

+ to meet with neighbor (object):
	if seenHash{ neighbor }: print "i've seen this neighbor before!"
	else seenHash{ neighbor } = 1.

The example above also shows that the syntax of hashes is the same as the syntax for lists when storing or retrieving data. Unlike lists, however, hashes do not hold ordered data, and none of the other list operators work with hashes.

When using hashes with ints, floats, vectors, matrices and strings, then steve will test the equivalence of the key when looking up or storing the data. This means that two equivalent strings, even if they are stored in different variables, will refer to the same value in the hash. For the other types (objects, pointers, data, lists and hashes themselves), the hash will only return the same value for the same exact variable key. This means that two different lists, even if they contain "equal" data, will access different values in the hash.

2.5.8.1. Conversion to Other Types

hashes cannot be converted to any other types.

2.5.9. The pointer Type

NoteFor developer use only
 

The pointer type is for use by breve and plugin developers only.

pointer variables store C-style pointers to internal data. They are not used for writing simulations in steve and are only used by breve developers and plugin authors.

pointer variables are only useful in the context of interacting with internal C-style function calls: they do not contain methods, variables or any other meaning in the context of most steve code. Like objects, however, pointers can be tested to see if they are NULL (0), but cannot be used in mathematical expressions. That is to say that pointers have a meaning in a boolean context of control structures such as if and while (as well as the logical operators && and ||).

Copying a pointer (assigning it to another variable), as in C, will not copy the data is points to.

2.5.9.1. Conversion to Other Types

pointers cannot be converted to any other types.

2.5.10. The data Type

NoteFor developer use only
 

The data type is for use by breve and plugin developers only.

data variables are similar to pointer variables in that they contain a reference to internal data. Also like pointer variables, they are not to be used in regular simulation code—they are only to be used by breve developers and custom plugins.

The different between data and pointer is that data refers to a linear block of internal data of known size. This means that data variables can be successfully archived, while pointers cannot. The only use for data variables is archiving and dearchiving internal data. For more information on using the data type with plugins, see the section on Archiving Plugin Data With The data Type (Section 11.3).

2.5.11. Arrays of other types

If you wish to create several grouped variables of a certain steve type, you can define an array of variables.

Arrays are not simple types like the others described here, but are instead simply a way to declare multiple variables of a certain type at the same time. That is to say that arrays cannot be passed to methods as arguments and cannot be assigned values as the other variable types are. If you need to pass multiple related values as a method argument, you'll want to use the LIST type, instead of an array.

Arrays of variables are defined by specifying the number of elements in the array, along with the plural version of the type name. Individual elements in the array are then accessed using the syntax arrayName[ arrayIndex ]. Both the array declaration and usage are illustrated below:
+ variables:
	myIntArray (10 ints).

+ to init:
	myIntArray[4] = 300.   # set the fourth element to be 300
	myIntArray[2] = 150.   # set the second element to be 150
	print myIntArray[2].   # print out the second element.

Array variables cannot be converted to other types—however, the elements contained in the arrays function just like any other variables and can be converted accordingly.