Changes since 03/30/2000
- Slightly changed the InitObject mechanism. The class
formerly known as InitObject is now called
PreinitObject, and a new class InitObject has been
added. The new InitObject does the same thing that
PreinitObject does, but does it at regular program start-up
rather than pre-initialization. This change makes the
pre-initialization and regular initialization mechanisms work the
same way. In addition, to make this mechanism more generic, both
InitObject and PreinitObject now descend from a
base class called ModuleExecObject; this class should be
usable as the base class for other types of modular execution
objects, such as perhaps a post-restore initializer sequence, a
command parsing initializer sequence, and so on. Refer to the
library pre-initialization documentation for
details.
- Added the -r option to the interpreter, allowing games to
be restored directly from the command. The saved state files now include
information on the image file that created them, so if you're restoring
a game, you don't have to specify the image file; this particular feature
also allows double-clicking on a saved state from the desktop to start
the interpreter, load the image file, and restore the saved state.
- The GrammarProd intrinsic class's parseTokens() method now
includes truncated matches to dictionary words (according to the
dictionary's truncation length setting) in its structural analysis.
The method also includes truncated matches (again, using the dictionary
setting) for literal tokens in the grammar. If you don't want to allow
truncated matches, simply change the dictionary's truncation length
setting to zero.
Changes since 03/26/2000
- Added a new library pre-initialization
mechanism based on "initialization objects" rather than a simple
preinit() method. This new mechanism should be especially useful for
library developers, since new initialization objects can be plugged in
without touching any library or user code
- It is now possible to extend
intrinsic classes with user-defined methods.
Changes since 03/21/2000
- The method-based API to certain functions that were formerly
implemented as intrinsics is now official. The trailing underscores
on the interim method names have been removed, and the corresponding
functions have been removed from the intrinsic function sets.
- getSuperclassList() is now Object.getSuperclassList()
- isClass() is now Object.isClass()
- propDefined() is now Object.propDefined()
- propType() is now Object.propType()
- length() is now List.length() and String.length()
- sublist() is now List.sublist()
- intersect() is now List.intersect()
- car() and cdr() are now List.car() and List.cdr()
- substr() is now String.substr()
- toUpper() is now String.toUpper()
- toLower() is now String.toLower()
- find() is now List.find() and String.find()
- toUnicode() is now String.toUnicode()
This change will, of course, necessitate recompiling all code, and will
require changing code that calls any of the functions that have been
migrated to methods. The sample code included in the distribution has
been updated to reflect the changes, and the documentation has also been
updated.
- Renamed the getSize() method in the Array class to
length(), for consistency with List and String.
- Added the 'is in' and 'not in' operators. See
the "is in" and "not in" expressions
section.
- The debugger now has "program arguments" settings. You can
access these settings via a dialog, which you can open using the
"Program Arguments" item on the "Debug" menu. You can use the
program arguments to control script file reading, output logging,
and the argument string that is passed to your program's "_main()"
entrypoint procedure.
- Added several new regular expression features: <Case> and
<NoCase>, <Alpha>, <Upper>, <Lower>, <Digit>,
<AlphaNum>, <Space>, <Punct>. Refer to the new
regular expressions section of the documentation
for details.
- Enhanced the regular expression parser to detect and remove
cycles in compiled patterns. It is possible (pretty easy,
actually) to introduce "infinite loops" into a pattern; the easiest
way to do this is to put a zero-or-more closure inside another closure,
as in "(.*)+" (this has an infinite loop because the expression in
parentheses can match zero characters, and that match can be repeated any
number of times), but much more complex and subtle types of cycles are
possible and can be inadvertantly constructed. Eliminating the
infinitely repeating zero-length matches obviously doesn't change the
meaning of the expression, since one repetition of a zero-length match is
as good as a million, so the regular expression matcher simply detects
and removes these loops and then carries on as normal.
- Updated StartI3.t and StartA3.t (the starter games in the Workbench
kit) to work with _main.t, so you don't have to compile them with -nodef.
(This also has the benefit of making the files a whole lot simpler.)
Also updated them to use method calls rather than intrinsic function
calls where appropriate.
- Updated the sample files to use the standard _main.t startup and
new property functions.
Changes since 03/12/2000
- Added default display methods, which
allow string display to be routed through a method of the active
"self" object in effect each time a string is displayed and each time
an expression embedded in a string via the << >> syntax
is displayed. This powerful new feature allows for per-object output
filtering, and allows for "stateful" filtering (in that the filtering
function is a method of the object that initiated the filtering, and
can therefore look at properties of "self" to perform its work).
- Added the "short form" anonymous
function syntax, which is much
more compact than the long form, but can only be used to define
functions that consist solely of a single expression.
- Added the subset() and applyAll() methods to
the array and list
intrinsic classes.
- Added documentation for the List intrinsic
class.
- Added the -cs interpreter option, which allows the user
to specify a character set to use for the display and keyboard.
Refer to the new interpreter section in
the documentation.
- As mentioned above, there is a new section
on the interpreter in the documentation.
- The TADS 3 HTML interpreter and debugger for Windows now use a
separate registry key for storing their preference settings. In
addition, the TADS 3 debugger's global preferences file is now
called HTMLTDB3.TDC. These changes should allow TADS 2 and TADS 3
installations to co-exist independently on a single system, without
affecting one another's stored configuration settings.
- Anonymous function objects are now represented by their own
intrinsic class. This is a mostly internal change, but does have
the benefit of enabling the debugger to display the type of an
anonymous function object (before, the debugger only knew that they
were objects).
- Made some internal changes to the way anonymous function context
objects are implemented to make them more efficient. (In particular,
context objects are now arrays, not TADS objects; array index lookup
is faster than TADS object property lookup.)
- Moved the code to Visual C++ 6 (which involved no changes, not
surprisingly, although the new C++ compiler caught a few dubious
constructs and generated helpful warnings, all of which have been
cleaned up).