number extensions
From Wiki
m |
|||
Line 77: | Line 77: | ||
This is enforced by design. Technically labeling could be variable but we don't want to give them computational power or have labeling result in unexpected side effects. In theory label look up is a relative expensive operation compared to evaluating a numerical expression. However that was not a motivating factor in this decision. And furthermore there is all but no possibility to reverse this decision. | This is enforced by design. Technically labeling could be variable but we don't want to give them computational power or have labeling result in unexpected side effects. In theory label look up is a relative expensive operation compared to evaluating a numerical expression. However that was not a motivating factor in this decision. And furthermore there is all but no possibility to reverse this decision. | ||
− | When a label is applied to an index it | + | When a label is applied to an index it <u>cannot</u> be removed. Multiple indices can share the same label, and each index can have multiple labels. This is not so much by design as it is simply an annoyance to remove labels. Doing so would require a linear search up and down the collated listing of labels just to find out if an index is already before applying each label. So be careful with labels. |
Last but not least. Labels are matched starting at the current index. This is mainly so labeled function parameters are able to share the same labels. In other words c[1][groceries] begins looking for the index labeled groceries starting with 1. If c[0] happens to be labeled groceries it will be ignored. The first index labeled groceries counting up from 1 is found. | Last but not least. Labels are matched starting at the current index. This is mainly so labeled function parameters are able to share the same labels. In other words c[1][groceries] begins looking for the index labeled groceries starting with 1. If c[0] happens to be labeled groceries it will be ignored. The first index labeled groceries counting up from 1 is found. | ||
</onlyinclude> | </onlyinclude> |
Revision as of 07:24, 27 May 2013
! |
Transcluded by Sword of Moonlight Extension Library / list of extensions. |
This section is available since 1.1.2.1.
Extensions in this section take the form of "numbers" capital N (or Numbers) that can appear inside of the calculator like formulas accepted by #number extensions. Be wary that a few odd number-like extensions exist that are not in fact #numbers because an additional qualification (as of 1.1.2.1) for numbers is the extension must be able to be continuously reevaluated. If it cannot it is best to think of it as a strict numerical code or something else altogether.
Numbers make the Ex.ini file programmable, and on the surface numbers can appear more powerful than Sword of Moonlight's native event system. For sure numbers are a more complete system, however the event system represents a true digital computer; whereas the easiest way to think about "numbers" is to picture a cheap old fashioned pocket calculator.
- Extension assignment
When assigning an expression to a Number in the #Number (or this) section there are between one-and-three parts to the left of the equal (=) sign and either an expression or a label to the right. When assigning to a regular number extension in any other section the expression part is the same except that the expression cannot refer to the number being assigned to (as a number is not a Number)
The three parts to the left of the equal sign take the form of name_0_label. Where name is how the Number appears in expressions. And _0 is a zero-based positive integer owing to the fact that each Number is truly an indexed collection of expressions or functions (expressions with parameters) where each index defaults to NaN or "not-a-number". If _0 is absent then index 0 is assumed and _label cannot be present as it would run into name resulting in a different name altogether. An optional label begins after the underscore (_) in _label. Or in other words Sword of Moonlight's "counters" labels and all are able to be represented by a single so-called Number.
Names and labels are allowed to contain up to 30 Unicode characters. Names should be made up of letters and underscores (_) only. Letters are not limited to ASCII (ie. basic English) and symbols will probably work too, but you should not use symbols as they are reserved for future use. Anything goes inside labels except for cases where inclusion of square brackets ([]) and equal signs (=) would be interpreted as the end of the label. Brackets can appear in equal number inside of a label as long as the constellation begins with an opening bracket. Spacing characters are trimmed from the left and right of the label, and any spacing within the label is converted into a single ASCII space character.
For readability it is recommended that _label not include spaces. However there is an alternative way to assign labels where only the underscore (_) of _label appears and the label itself is written to the right of the equal (=) sign. This approach can further aid readability by keeping the equal signs lined up one line after the next.
Each index is accessed with a square bracket ([]) notation. For example c[1] for the second index of c. Or if c[1] is labeled, c[c[1]'s label], though you must be careful with [ and ] inside of labels so that they always appear in nested pairs so not to be confused with the end of the label. Labels can even be combined with computed offsets like so: c[groceries][+1].
Functions hold default parameters and labels in the indices just above them. So f[1] is the fist default parameter of f (refer to the system number _ below for input parameters access within a function)
- Mathematical symbols
In addition to the familiar plus (+) minus (-) multiplication (*) and division (/) operators (using standard infix association) there are exponent (^) for squared, cubed, etc. and complex square and Nth root by way of fractional "powers" and grouping parentheses (()) following algebraic order of operations and absolute value (||) vertical bars.
Numbers can be prefixed by minus (-) to be made negative or plus (+) to note as positive. Note that + can actually be useful inside of square brackets ([]) to distinguish between numbers and labels. Also care must be taken to ensure that numbers are not interpreted as a series of individual expressions. To do so operators must be surrounded by spaces on both sides or appear directly in front of a number or appear between numbers without any extra space (commas and semicolons can be added to note the continuation of series)
Functions make use of z = f(x,y) notation, read f of x and y yields z, where f is the name of the Number and x and y are parameters of its function.
- Branching symbols
So-called if-then-else (if not otherwise) functionality is achieved by the ternary, or 3 part, x?y:z pattern where x is the predicate, and y is number chosen if x is nonzero, and z is the number chosen if x is zero (refer to _E below for the definition of zero)
- Built in functions
Logical functions include and(...,n) nand(...,n) or(...,n) nor(...,n) xor(x,y) xnor(x,y) and not(x[,y]) where the second parameter of not is optional. If present y is subtracted from x. These functions always yield zero (0) or one (1) "true or false" numbers.
Inequality functions include neg(x[,y]) where y like above is optional and subtracted from x. If x is less than zero (0) neg is one (1) or else zero. In other words neg is one if x is negative. If not zero. Neg is not-equal-nor-greater. Be wary that complex numbers are never negative according to neg.
Identity functions include nan([x]) and inf([x]) where both are one (1) if x is NaN, or not-a-number, or infinity (∞) respectively. Zero (0) alternatively. The parameter x is optional. If omitted the parentheses should be omitted also. Instead of one and zero the functions yield the literal numbers NaN (not really a number but a value nonetheless) and infinity.
Utility functions include int(x) discarding the fractional part of a number, and mod(x,y) yielding the remainder of x divided by y, and min(x,y) and max(x,y).
Complex functions include x(x) and y(x) and iy(x) where x yields the "real" part of a number, y the "imaginary" part of a number as a "real number", or a number that is not complex, and iy the "imaginary" part of a number as a complex number, or a "purely imaginary" number.
Supplemental functions include pow(x,y) abs(x) and if(x,y,z) where pow is equivalent to x^y and abs is equivalent to |x| and if is equivalent to x?y:z.
Additional functions include exp(x) and log(x[,y]) where y is base-e (2.71828) if omitted. And all of the standard trigonometric functions, sin(x) cos(x) and so forth (a complete list is forthcoming.)
- Built in numbers
The numbers pc and npc hold stats for the player character and non player character respectively. Note that these may change (and not always be available) in any given context. And c holds the values of the game's event "counters". Bear in mind that number expressions cannot change these values but the values themselves are subject to change.
The number r generates random positive integers between 0 and one less than the integer ID accessed. So that r[2] can be 0 or 1. r[0] or simply r makes use of the widest range possible.
- System numbers
_ always refers to the parameters of a function. _[0] holds the number itself. Note that technically all numbers are functions of themselves. _[1] holds the first parameter, _[2] the second, and so on. Note that _[0] or simply _ is off limits outside of the #Number section (at least until it is decided otherwise.)
_E, or Epsilon, is a fractional number so small to only be meaningful as rounding error. If the absolute value of a number is less than _E then it is considered to be zero (0) when comparing for equality.
_WALK, _DASH, _TURN refer to the player character speeds as defined by the game's Sys.dat file.
- Shorthand notation
Inside of expressions the number c[2] can be written 2c. However c[intro] and c[1+2] won't work. One becomes introc (another number altogether) and 1+2c, or c[2]+1 (unless that was what you wanted.)
When numbers are not "glued" together by one of the basic mathematical or branching symbols they are treated as numbers in a series. When assigning a series to a number the second number in the series is assigned to the number just above it and so on so that n_0 = 1 2 assigns 1 to n_0 and 2 to n_1 (note that n_0 = 1 -2 is a series while 1 - 2 and 1-2 are not.)
- Labeling caveats
When a label is used to index into a number it must be possible to convert the label into a constant index. In other words a label is no more than a "human readable" alternative to numerical indices. So c[1024r][groceries] will not work, since 1024r being a random number cannot be part of a constant index.
This is enforced by design. Technically labeling could be variable but we don't want to give them computational power or have labeling result in unexpected side effects. In theory label look up is a relative expensive operation compared to evaluating a numerical expression. However that was not a motivating factor in this decision. And furthermore there is all but no possibility to reverse this decision.
When a label is applied to an index it cannot be removed. Multiple indices can share the same label, and each index can have multiple labels. This is not so much by design as it is simply an annoyance to remove labels. Doing so would require a linear search up and down the collated listing of labels just to find out if an index is already before applying each label. So be careful with labels.
Last but not least. Labels are matched starting at the current index. This is mainly so labeled function parameters are able to share the same labels. In other words c[1][groceries] begins looking for the index labeled groceries starting with 1. If c[0] happens to be labeled groceries it will be ignored. The first index labeled groceries counting up from 1 is found.