| | 1 | #charset "us-ascii" |
| | 2 | |
| | 3 | /* |
| | 4 | * Copyright (c) 1999, 2006 Michael J. Roberts |
| | 5 | * |
| | 6 | * This file is part of TADS 3 |
| | 7 | * |
| | 8 | * This header defines the tads-gen intrinsic function set. This function |
| | 9 | * set provides some miscellaneous functions, including data conversions, |
| | 10 | * object iteration, regular expressions, and state persistence operations. |
| | 11 | */ |
| | 12 | |
| | 13 | /* |
| | 14 | * TADS basic data manipulation intrinsic function set |
| | 15 | */ |
| | 16 | |
| | 17 | #ifndef TADSGEN_H |
| | 18 | #define TADSGEN_H |
| | 19 | |
| | 20 | /* |
| | 21 | * The tads-gen function set |
| | 22 | */ |
| | 23 | intrinsic 'tads-gen/030006' |
| | 24 | { |
| | 25 | /* |
| | 26 | * Get the type of the given value. This returns a TypeXxx value. |
| | 27 | */ |
| | 28 | dataType(val); |
| | 29 | |
| | 30 | /* |
| | 31 | * Get the given parameter to the current function. 'idx' is 1 for the |
| | 32 | * first argument in left-to-right order, 2 for the second, and so on. |
| | 33 | */ |
| | 34 | getArg(idx); |
| | 35 | |
| | 36 | /* |
| | 37 | * Get the first object in memory. If 'cls' is provided, we return the |
| | 38 | * first object of the given class; otherwise we return the first |
| | 39 | * object of any kind. 'flags' is an optional bitwise combination of |
| | 40 | * ObjXxx values, specifying whether classes, instances, or both are |
| | 41 | * desired. If this isn't specified, ObjAll is assumed. This is used |
| | 42 | * in conjunction with nextObj() to iterate over all objects in memory, |
| | 43 | * or all objects of a given class. |
| | 44 | */ |
| | 45 | firstObj(cls?, flags?); |
| | 46 | |
| | 47 | /* |
| | 48 | * Get the next object in memory after the given object, optionally of |
| | 49 | * the given class and optionally limiting to instances, classes, or |
| | 50 | * both. This is used to continue an iteration started with |
| | 51 | * firstObj(). |
| | 52 | */ |
| | 53 | nextObj(obj, cls?, flags?); |
| | 54 | |
| | 55 | /* |
| | 56 | * Seed the random-number generator. This uses unpredictable |
| | 57 | * information from the external operating system environment (which |
| | 58 | * might be something like the current time of day, but the exact |
| | 59 | * information used varies by system) to seed the rand() generator with |
| | 60 | * a new starting position. Since rand() is a pseudo-random number |
| | 61 | * generator, its sequence is deterministic - each time it's started |
| | 62 | * with a given seed value, the identical sequence will result. This |
| | 63 | * function helps produce apparent randomness by effectively |
| | 64 | * randomizing the starting point of the sequence. |
| | 65 | * |
| | 66 | * Note that if randomize() is never called, the system will use a |
| | 67 | * fixed initial seed, so rand() will return the same sequence each |
| | 68 | * time the program is run. This is intentional, because it makes the |
| | 69 | * program's behavior exactly repeatable, even if the program calls |
| | 70 | * rand() to select random numbers. This type of repeatable, |
| | 71 | * deterministic behavior is especially useful for testing purposes, |
| | 72 | * since it allows you to run the program through a fixed set of input |
| | 73 | * and compare the results against a fixed set of output, knowing the |
| | 74 | * the random number sequence will be the same on each run. Typically, |
| | 75 | * what you'd want to do is check at start-up to see if you're in |
| | 76 | * "testing" mode (however you wish to define that), and call |
| | 77 | * randomize() only if you're not in testing mode. This will create |
| | 78 | * apparently random behavior on normal runs, but produce repeatable |
| | 79 | * behavior during testing. |
| | 80 | */ |
| | 81 | randomize(); |
| | 82 | |
| | 83 | /* |
| | 84 | * Select a random number or a random value. |
| | 85 | * |
| | 86 | * If only one argument is supplied, and this argument is an integer |
| | 87 | * value, the function returns an integer from 0 to one less than the |
| | 88 | * argument value. For example, rand(10) returns a number from 0 to 9 |
| | 89 | * inclusive. |
| | 90 | * |
| | 91 | * If one argument is supplied, and the argument is a list, the |
| | 92 | * function randomly selects one of the values from the list and |
| | 93 | * returns it. |
| | 94 | * |
| | 95 | * If more than one argument is supplied, the function randomly selects |
| | 96 | * one of the arguments and returns it. (Note that since this is an |
| | 97 | * ordinary function call, all of the arguments are evaluated, |
| | 98 | * triggering any side effects of those evaluations.) |
| | 99 | * |
| | 100 | * In all cases, the random number selection is uniformly distributed, |
| | 101 | * meaning that each possible return value has equal probability. |
| | 102 | */ |
| | 103 | rand(x, ...); |
| | 104 | |
| | 105 | /* |
| | 106 | * Convert the given value to a string representation. 'val' can be an |
| | 107 | * integer, in which case it's converted to a string representation in |
| | 108 | * the numeric base given by 'radix' (which can be any value from 2 to |
| | 109 | * 36), or base 10 (decimal) if 'radix' is omitted; nil or true, in |
| | 110 | * which case the string 'nil' or 'true' is returned; a string, which |
| | 111 | * is returned unchanged; or a BigNumber, in which case the value is |
| | 112 | * converted to a string representation in decimal. (Note that in the |
| | 113 | * case of BigNumber, you might prefer to use BigNumber.formatString(), |
| | 114 | * as that gives you much more control over the formatting.) |
| | 115 | */ |
| | 116 | toString(val, radix?); |
| | 117 | |
| | 118 | /* |
| | 119 | * Convert the given value to an integer. If 'val' is a string, the |
| | 120 | * function parses the value as an integer value in the numeric base |
| | 121 | * given by 'radix' (which can be one of 2, 8, 10, or 16), or base 10 |
| | 122 | * (decimal) if 'radix' is omitted. If 'val' is the string 'true' or |
| | 123 | * 'nil', the function returns true or nil, respectively. If 'val' is |
| | 124 | * a BigNumber value, the value is rounded to the nearest integer; an |
| | 125 | * exception ("numeric overflow") is thrown if the number is out of |
| | 126 | * range for a 32-bit integer. |
| | 127 | */ |
| | 128 | toInteger(val, radix?); |
| | 129 | |
| | 130 | /* |
| | 131 | * Get the current local time. |
| | 132 | * |
| | 133 | * If timeType is GetTimeDateAndTime (or is omitted), this returns the |
| | 134 | * calendar date and wall-clock time, as a list: [year, month, |
| | 135 | * dayOfMonth, dayOfWeek, dayOfYear, hour, minute, second, timer]. |
| | 136 | * Year is the year AD (for example, 2006); month is the current month, |
| | 137 | * from 1 (January) to 12 (December); dayOfMonth is the calendar day of |
| | 138 | * the month, from 1 to 31; dayOfWeek is the day of the week, from 1 |
| | 139 | * (Sunday) to 7 (Saturday); dayOfYear is the current day of the year, |
| | 140 | * from 1 (January 1) to 366 (December 31 in a leap year); hour is the |
| | 141 | * hour on a 24-hour clock, ranging from 0 (midnight) to 23 (11pm); |
| | 142 | * minute is the minute of the hour, from 0 to 59; second is the second |
| | 143 | * of the minute, from 0 to 59; and timer is the number of seconds |
| | 144 | * elapsed since the "epoch," defined arbitrarily as midnight, January |
| | 145 | * 1, 1970. |
| | 146 | * |
| | 147 | * If timeType is GetTimeTicks, this return the number of milliseconds |
| | 148 | * since an arbitrary starting time. The first call to get this |
| | 149 | * information sets the starting time, so it will return zero; |
| | 150 | * subsequent calls will return the amount of time elapsed from that |
| | 151 | * starting time. Note that because a signed 32-bit integer can only |
| | 152 | * hold values up to about 2 billion, the maximum elapsed time that |
| | 153 | * this value can represent is about 24.8 days; so, if your program |
| | 154 | * runs continuously for more than this, the timer value will roll |
| | 155 | * around to zero at each 24.8 day multiple. So, it's possible for |
| | 156 | * this function to return a smaller value than on a previous |
| | 157 | * invocation, if the two invocations straddle a 24.8-day boundary. |
| | 158 | */ |
| | 159 | getTime(timeType?); |
| | 160 | |
| | 161 | /* |
| | 162 | * Match a string to a regular expression pattern. 'pat' can be either |
| | 163 | * a string giving the regular expression, or can be a RexPattern |
| | 164 | * object. 'str' is the string to match, and 'index' is the starting |
| | 165 | * character index (the first character is at index 1) at which to |
| | 166 | * start matching. Returns the length in characters of the match, or |
| | 167 | * nil if the string doesn't match the pattern. (Note that a return |
| | 168 | * value of zero doesn't indicate failure - rather, it indicates a |
| | 169 | * successful match of the pattern to zero characters. This is |
| | 170 | * possible for a pattern with a zero-or-more closure, such as 'x*' or |
| | 171 | * 'x?'.) |
| | 172 | */ |
| | 173 | rexMatch(pat, str, index?); |
| | 174 | |
| | 175 | /* |
| | 176 | * Search the given string for the given regular expression pattern. |
| | 177 | * 'pat' is a string giving the regular expression, or a RexPattern |
| | 178 | * object. 'str' is the string to search, and 'index' is the optional |
| | 179 | * starting index (the first character is at index 1). If the pattern |
| | 180 | * cannot be found, returns nil. If the pattern is found, the return |
| | 181 | * value is a list: [index, length, string], where index is the |
| | 182 | * starting character index of the match, length is the length in |
| | 183 | * characters of the match, and string is the text of the match. |
| | 184 | */ |
| | 185 | rexSearch(pat, str, index?); |
| | 186 | |
| | 187 | /* |
| | 188 | * Get the given regular expression group. This can be called after a |
| | 189 | * successful rexMatch() or rexSearch() call to retrieve information on |
| | 190 | * the substring that matched the given "group" within the regular |
| | 191 | * expression. A group is a parenthesized sub-pattern within the |
| | 192 | * regular expression; groups are numbered left to right by the open |
| | 193 | * parenthesis, starting at group 1. If there is no such group in the |
| | 194 | * last regular expression searched or matched, or the group wasn't |
| | 195 | * part of the match (for example, because it was part of an |
| | 196 | * alternation that wasn't matched), the return value is nil. If the |
| | 197 | * group is valid and was part of the match, the return value is a |
| | 198 | * list: [index, length, string], where index is the character index |
| | 199 | * within the matched or searched string of the start of the group |
| | 200 | * match, length is the character length of the group match, and string |
| | 201 | * is the text of the group match. |
| | 202 | */ |
| | 203 | rexGroup(groupNum); |
| | 204 | |
| | 205 | /* |
| | 206 | * Search for the given regular expression pattern (which can be given |
| | 207 | * as a regular expression string or as a RexPattern object) within the |
| | 208 | * given string, and replace one or more occurrences of the pattern |
| | 209 | * with the given replacement text. If 'flags' includes ReplaceAll, |
| | 210 | * all occurrences of the pattern are replaced; otherwise only the |
| | 211 | * first occurrence is replaced. 'index', if provided, is the starting |
| | 212 | * character index of the search; instances of the pattern before this |
| | 213 | * index will be ignored. Returns the result string with all of the |
| | 214 | * desired replacements. When an instance of the pattern is found and |
| | 215 | * then replaced, the replacement string is not rescanned for further |
| | 216 | * occurrences of the text, so there's no danger of infinite recursion; |
| | 217 | * instead, scanning proceeds from the next character after the |
| | 218 | * replacement text. |
| | 219 | * |
| | 220 | * The replacement text can use "%n" sequences to substitute group |
| | 221 | * matches from the input into the output. %1 is replaced by the match |
| | 222 | * to the first group, %2 the second, and so on. %* is replaced by the |
| | 223 | * entire matched input. (Because of the special meaning of "%", you |
| | 224 | * must use "%%" to include a percent sign in the replacement text.) |
| | 225 | */ |
| | 226 | rexReplace(pat, str, replacement, flags, index?); |
| | 227 | |
| | 228 | /* |
| | 229 | * Create an UNDO savepoint. This adds a marker to the VM's internal |
| | 230 | * UNDO log, establishing a point in time for a future UNDO operation. |
| | 231 | */ |
| | 232 | savepoint(); |
| | 233 | |
| | 234 | /* |
| | 235 | * UNDO to the most recent savepoint. This uses the VM's internal UNDO |
| | 236 | * log to undo all changes to persistent objects, up to the most recent |
| | 237 | * savepoint. Returns true if the operation succeeded, nil if not. A |
| | 238 | * nil return means that there's no further UNDO information recorded, |
| | 239 | * which could be because the program has already undone everything |
| | 240 | * back to the start of the session, or because the UNDO log was |
| | 241 | * truncated due to memory size such that no savepoints are recorded. |
| | 242 | * (The system automatically limits the UNDO log's total memory |
| | 243 | * consumption, according to local system parameters. This function |
| | 244 | * requires at least one savepoint to be present, because otherwise it |
| | 245 | * could create an inconsistent state.) |
| | 246 | */ |
| | 247 | undo(); |
| | 248 | |
| | 249 | /* |
| | 250 | * Save the current system state into the given file. This uses the |
| | 251 | * VM's internal state-save mechanism to store the current state of all |
| | 252 | * persistent objects in the given file. Any existing file is |
| | 253 | * overwritten. |
| | 254 | */ |
| | 255 | saveGame(filename); |
| | 256 | |
| | 257 | /* |
| | 258 | * Restore a previously saved state file. This loads the states of all |
| | 259 | * persistent objects stored in the given file. The file must have |
| | 260 | * been saved by the current version of the current running program; if |
| | 261 | * not, an exception is thrown. |
| | 262 | */ |
| | 263 | restoreGame(filename); |
| | 264 | |
| | 265 | /* |
| | 266 | * Restart the program from the beginning. This resets all persistent |
| | 267 | * objects to their initial state, as they were when the program was |
| | 268 | * first started. |
| | 269 | */ |
| | 270 | restartGame(); |
| | 271 | |
| | 272 | /* |
| | 273 | * Get the maximum of the given arguments. The values must be |
| | 274 | * comparable with the ordinary "<" and ">" operators. Note that |
| | 275 | * because this is an ordinary function call, all of the arguments are |
| | 276 | * evaluated (which means any side effects of these evaluations will be |
| | 277 | * triggered). |
| | 278 | */ |
| | 279 | max(val1, ...); |
| | 280 | |
| | 281 | /* |
| | 282 | * Get the minimum of the given arguments. The values must be |
| | 283 | * comparable with the ordinary "<" and ">" operators. Note that |
| | 284 | * because this is an ordinary function call, all of the arguments are |
| | 285 | * evaluated (which means any side effects of these evaluations will be |
| | 286 | * triggered). |
| | 287 | */ |
| | 288 | min(val1, ...); |
| | 289 | |
| | 290 | /* |
| | 291 | * Create a string by repeating the given value the given number of |
| | 292 | * times. If the repeat count isn't specified, the default is 1. |
| | 293 | * 'val' can be a string, in which case the string is simply repeated |
| | 294 | * the given number of times; an integer, in which case the given |
| | 295 | * Unicode character is repeated; or a list of integers, in which case |
| | 296 | * the given Unicode characters are repeated, in the order of the list. |
| | 297 | * The list format can be used to create a string from a list of |
| | 298 | * Unicode characters that you've been manipulating as a character |
| | 299 | * array, which is sometimes a more convenient or efficient way to do |
| | 300 | * certain types of string handling than using the actual string type. |
| | 301 | */ |
| | 302 | makeString(val, repeatCount?); |
| | 303 | |
| | 304 | /* |
| | 305 | * Get a description of the parameters to the given function. 'func' |
| | 306 | * is a function pointer. This function returns a list: [minArgs, |
| | 307 | * optionalArgs, isVarargs], where minArgs is the minimum number of |
| | 308 | * arguments required by the function, optionalArgs is the additional |
| | 309 | * number of arguments that can be optionally provided to the function, |
| | 310 | * and isVarargs is true if the function takes any number of additional |
| | 311 | * ("varying") arguments, nil if not. |
| | 312 | */ |
| | 313 | getFuncParams(func); |
| | 314 | } |
| | 315 | |
| | 316 | /* |
| | 317 | * flags for firstObj() and nextObj() |
| | 318 | */ |
| | 319 | #define ObjInstances 0x0001 |
| | 320 | #define ObjClasses 0x0002 |
| | 321 | #define ObjAll (ObjInstances | ObjClasses) |
| | 322 | |
| | 323 | /* |
| | 324 | * rexReplace() flags |
| | 325 | */ |
| | 326 | #define ReplaceOnce 0x0000 |
| | 327 | #define ReplaceAll 0x0001 |
| | 328 | |
| | 329 | /* |
| | 330 | * getTime() flags |
| | 331 | */ |
| | 332 | #define GetTimeDateAndTime 1 |
| | 333 | #define GetTimeTicks 2 |
| | 334 | |
| | 335 | |
| | 336 | #endif /* TADSGEN_H */ |
| | 337 | |