-
Notifications
You must be signed in to change notification settings - Fork 1
Literal
A literal is a value written directly in a calculation rule: a number such as 42, 2.5 or 1000f, or a string such as 'Amsterdam'. Literals are one of the three kinds of expression elements, next to operator and function applications and references to other tree items. Every numeric literal has a value type, which the notation determines: an unadorned integer is a uint32, an unadorned real is a float64, and a suffix selects any other type or a values unit.
- An integer literal is a sequence of decimal digits:
0,42,1000000. Its value type is uint32. - A real literal contains a decimal point or an exponent:
2.5,.5,5.,1e3,15e-1,2E2. Its value type is float64. A number without a point or exponent is never a real:1000is a uint32,1000.0and1e3are float64. - A hexadecimal literal is a percent sign followed by hexadecimal digits, in either case:
%FFand%ffare 255. Its value type is uint32 like a decimal integer, and a suffix applies in the same way. A suffix that starts with a letter that is also a hexadecimal digit (b,c,d,f) is read as more digits:%1Fbis 507, not the uint8 value 31; writeuint8(%1F)or31binstead.
The digits are read as an unsigned number. There is no negative literal: -1 is the negation operator applied to the literal 1, and negation of an unsigned value results in the signed type of the same width, so -1 is an int32, -1b an int8 and -1.5 a float64.
An integer literal must fit the uint32 range. Up to 4294967295 is accepted, but note that 4294967295 is the null value of uint32, so uint64(4294967295) is null. From 4294967296 on the parser reports Cannot convert 4294967296 to UInt32, consider adding the suffix u64 or i64, and with that suffix the full 64 bits range is available (since the GeoDMS 9.0 series; before, such a literal was rejected whatever its suffix).
A suffix is written directly after the digits, without a space, and gives the literal another value type. It is shorthand for the conversion function of that type: 1000f is float32(1000), and because it is a conversion, 2.7u is uint32(2.7), which is 2.
Since GeoDMS 20.21.0 the suffixes in the table below are case sensitive and are written in lower case: 4.5f is a float32, 4.5F is not. Up to 20.20.0 they were case insensitive, and the letters d, f, u, i, w, s, b and c were registered as names in the same case-folded namespace as every item name, so a configuration that named a unit W, a container C or a function type parameter D reported a case mix-up against the suffix letter on every run. A suffix is now recognised as text and is not a name at all; those item names are free. An upper-case suffix is read the way any other name after a number is, as a values unit (see below), and fails as an unknown identifier when no such unit exists: 60D used to be 60d, write 60d.
| value type | suffix | also | example |
|---|---|---|---|
| uint8 | b |
u8 |
200b |
| uint16 | w |
u16 |
1000w |
| uint32 | u |
u32 |
42u, the same as 42
|
| uint64 | u64 |
4294967296u64 |
|
| int8 | c |
i8 |
-100c |
| int16 | s |
i16 |
7s |
| int32 | i |
i32 |
42i |
| int64 | i64 |
-5000000000i64 |
|
| float32 | f |
2.5f, 1000f
|
|
| float64 | d |
2.5d, the same as 2.5; 42d is 42.0
|
|
| uint2 | u2 |
3u2 |
|
| uint4 | u4 |
15u4 |
The full name of any value type is accepted as a suffix as well: 3float32 is 3f. The one-letter suffixes b, w, u, c, s, i, f and d have been available since GeoDMS 7.105.
Any other name directly after a number is taken as the name of a values unit: 5m means 5[m], that is value(5, m), the value 5 expressed in the unit m (see value). This makes the suffix letters above unavailable as unit suffixes: with a unit named s for seconds, 5s is the int16 value 5, not five seconds; write 5[s]. The bracket form is unambiguous and works for any unit path, as in 10[Units/m]. Since 20.21.0 the upper-case letter is a unit suffix like any other name, so 5W with a unit W for watt is five watt, while 5w is a uint16.
A literal is an expression with a value type, and the item that holds it must agree with that type. parameter<int32> x := 42; is refused with ItemType DataItem is incompatible with the result of the calculation which is of type DataItem, because 42 is a uint32; write 42i. The same holds for parameter<float32> f := 2.5;, where 2.5f is needed.
The operands of an arithmetic operator must have the same value type as well; the GeoDMS never promotes one operand to the type of the other. With length a float32 attribute, Road/length * 2 and Road/length * 2.0 are both refused with mul Error: Cannot find operator for these arguments, and Road/length * 2f is accepted. So the suffix of a literal follows the type of the data it is combined with. Conversion functions such as float32(2) do the same as the suffix, at more length.
-
trueandfalseare constant functions, as arepi()and the typed null valuesnull_b,null_u,null_f, ...; there is no boolean or null literal. - Point values are constructed with functions such as point_xy.
- A whole array of values is not written in an expression; that is what a data block (
attribute<int32> a : [1, 2, 3]) is for.
A string literal is text between single quotes or between double quotes: 'Amsterdam' and "Amsterdam" are the same value. The difference is how the quote character itself is written inside the string:
- in a single quoted string, a single quote is written twice:
'it''s'is it's; - in a double quoted string, a double quote is escaped with a backslash:
"say \"yes\""is say "yes", while a single quote needs nothing:"it's".
In a single quoted string a backslash does not escape the quote: 'it\'s' is a syntax error, since the string ends at the first quote that is not doubled. Which quote style to use often follows from the context: in the original expr = "..." notation the whole expression is a double quoted string, so its string literals are single quoted; see Expression syntax.
Two or more string literals written after each other, with only whitespace in between, form one string: 'Amster' 'dam' is 'Amsterdam', and the styles may be mixed. This joins long texts over several lines without a +.
In both quote styles, a backslash starts an escape code that stands for one character:
| escape | character |
|---|---|
\t |
tab |
\n |
line feed |
\r |
carriage return |
\0 |
the NUL character |
\\ |
a backslash |
\" |
a double quote |
\' |
a single quote (in a double quoted string; in a single quoted string a quote is doubled instead) |
\xHH |
the byte with hexadecimal value HH, e.g. \x41 is A (since GeoDMS 20.0.2) |
A backslash before any other character is dropped and that character is kept: 'a\d+b' is the four characters ad+b. This is what turns a Windows path with single backslashes into nonsense: 'C:\temp\data.csv' reads as C:, a tab, empdata.csv, and "C:\Users\x.pdf" as C:Usersx.pdf. Write the separator as \\ or as /, which the GeoDMS accepts in every file name: 'C:/temp/data.csv'. Since GeoDMS 20.10.0 such a literal is reported in the event log as unknown escape code '\d' in the string ..., with the file, line and column when it occurs in a configuration file; the value is still read with the backslash dropped, as before.
The same rules apply to every quoted string in a configuration, not only in calculation rules: a string in a property value such as url, Descr or StorageName and a string in a data block are read by the same parser. Strings that reach the GeoDMS through data, from a file or a database, are not parsed and contain no escape codes.
- Expression elements
- Value type, with the same suffix table per type
-
Value and the bracket notation
5[m] - Constant functions
- String functions
GeoDMS ©Object Vision BV. Source code distributed under GNU GPL-3. Documentation distributed under CC BY-SA 4.0.