The CM language is statically typed, which means all variables and expressions in CM must have a type that is known at compile time. This type is used to detect errors and improve run-time performance.
There are two main categories of types in CM: value types and reference types. Value types can be allocated on the stack and are passed by value to functions when used as arguments or return values, which means they are copied. Reference types, on the other hand, are allocated and freed by the garbage collector and are passed by reference between functions, which means only a pointer to the data is passed instead of a copy.
Value Types
Reference Types
Primitive Types
Primitive types are indivisible value types that are built into the language.
Numeric Types
CM supports a wide range of numeric types with different sizes to accommodate many needs.
For every numeric type, there are two constants that contain the minimal and maximal values possible for that type. These constants are named minType and maxType, where Type is the name of the type with its first letter capitalized.
For instance, the minInt and maxInt constants contain the bounds of the int type.
Integral Types
Operations on integral types that lead to under- or overflow cause the number to wrap around. For instance, the addition of byte values is addition modulo 256.
int
Values of type int are 32-bit signed integers.
range: -2147483648..2147483647
Integer literals can be specified in hexadecimal form (base 16) by prefixing the number with 0x.
nat
Values of type nat are 32-bit unsigned integers.
range: 0..4294967295
Integer literals can be specified in hexadecimal form (base 16) by prefixing the number with 0x.
nat64
Values of type nat are 64-bit unsigned integers.
range: 0..9223372036854775807
Integer literals can be specified in hexadecimal form (base 16) by prefixing the number with 0x.
byte
Values of type byte are 8-bit unsigned integers.
range: 0..255
int8
Values of type int8 are 8-bit signed integers.
range: -128..127
int16
Values of type int16 are 16-bit signed integers.
range: -32768..32767
word
Values of type word are 16-bit unsigned integers.
range: 0..65535
int64
Values of type nat are 64-bit signed integers.
Literals of type int64 are written with i64 appended at the end of the number.
range: -9223372036854775808..9223372036854775807
Floating-Point Types
double
Values of type double contain double-precision 64-bit floating-point values.
range: -1.79769e+308..1.79769e+308
float
Values of type float contain single-precision 32-bit floating-point values.
range: -3.40282e+038..3.40282e+038
Character Types
char
Values of type char are wide characters (16 bits) representing UTF-16 code units.
cchar
Values of type cchar are 8-bit characters used for compatibility with C.
Boolean Types
bool
The bool type represents truth values and can be either true or false.
Enumerations
Enum defines sets of named integer constants.
enum-definition: enum id using-declopt enumPropsopt { enumEntry1 ; enumEntry2 ; .. enumEntryn ; } using-decl: using type enum-props: : enum-prop-list enum-prop-list: enum-prop-list, enum-prop enum-prop enum-prop: field access unsafe bitset allow capitalized enumEntry: id id = expr
using specifies which integral type should be used to hold values of the enumeration. Legal types are: int8, byte, int16, word, char, int, and nat.
All enum definitions must contain a zero-valued entry unless the unsafe property is used. The zeroth entry is the default value given to unassigned variables of this type.
If the field access property is present, the enum entries will define fields of the enum type instead of top-level names. This can reduce the risk for name collisions. If the season enum below had used the field access property, it would have introduced a constant named season.summer instead of simply summer, for instance. To use field access should be the normal case.
Enum types should begin with lower-case letters. Using a leading upper-case letter will render a warning in the compilation buffer unless the allow capitalized property was used.
Examples:
private enum season : field access { winter; spring; summer; fall; }
public enum liOpenGLMode using byte : field access { liOpenGLNone = 0; liOpenGLLowDetail = 1; liOpenGLMediumDetail = 2; liOpenGLHighDetail = 3; }
Enum type test
You can use the in operator to check enum collections. When the right-hand side is the name of an enumeration type, the expression is true if the left-hand side matches the integer value of an entry in the enumeration, and false otherwise.
{ pln(#season.fall in season); pln(#3 in season); pln(#4 in season); }
Output:
season.fall in season=true 3 in season=true 4 in season=false
Compound Values
Compound values are similar to objects in that they have fields and methods, but different in that they are passed by value and can be allocated on the stack. They also cannot be inherited/overwritten as a class/object can.
Example:
public value rangeI { public int from; public int to; public constructor(int from, int to) { this.from = from; this.to = to; } final public bool operator==(rangeI a) { return from == a.from and to == a.to; } final public int span() { return to - from; } }
Classes
Class definitions introduce new reference types called classes and define their members, which may be fields, constructors, finalizers, and methods. The instances of class types are called objects.
See more: Classes and Objects
Strings
String types in CM are for the most part analogous to their representation in C/C++: null-terminated character arrays.
String literals are formed by enclosing sequences of character literals in pairs of quotation marks. Special characters may need to be escaped with backslashes.
The corresponding type of the characters that comprise a string and the size of each character is defined by the string type.
str
Comprised of char
s, which are UTF16-encoded 2-byte characters. This corresponds to wchars ("wide characters") in some C implementations.
cstr
Comprised of cchar
s, which are 1-byte characters analogous to char in ANSI C and require a codepage to interpret if outside the standard lower set of ASCII.
str8
The str8 type defines null-terminated character sequences encoded with the UTF-8 character encoding. UTF-8 is a variable-length format. Each character is 1-4 cchar
s.
in operator for strings
The in operator can be used for testing if a character is contained in a string.
{ str stringEx = "Foobar"; pln(#"Foo" in stringEx); pln(#"foo" in stringEx); pln(#"bear" in stringEx); pln(#'o' in stringEx); }
Output:
"Foo" in stringEx=true "foo" in stringEx=false "bear" in stringEx=false 'o' in stringEx=true
Symbols
Symbols are immutable strings which can be compared for equality in constant time by comparing the pointers.
A symbol literal can be created by prefixing either an id or literal string with a '#'. Currently (9.5), putting parenthesis around symbol literals that are not otherwise in parenthesis (e.g., when being used in an 'if', or passed to a function/method, etc.) is recommended to preserve automatic tabbing levels in Emacs, since otherwise C-Mode will believe them to indicate a start of a preprocessor directive/macro.
symbol sym = (#abc123); symbol pkg = (#"symbol.with.chars.not.allowed.for.an.id"); if (sym == #abc) ...
To get the string component of a symbol, cast it to a str
instead of using toS(). This is because toS() functions/methods are providing identifying information, primarily for debugging, and thus for symbols includes the '#' in order to differentiate it from a string.
Collections
Refer more here.
Reference Datatypes
Values of reference types contain pointers to data instead of the actual data. All reference types are class types, so the data pointed to by a value of a reference type is always an instance of a class. Thus the terms object and reference can be used interchangably for values of reference types in this sense.
Comments
0 comments
Please sign in to leave a comment.