so hopefully not too much breaks). New syntax features:
1. Call-by-name function arguments. You can specify a hash literal in
place of ordered function arguments, and it will become the local
variable namespace for the called function, making functions with many
arguments more readable. Ex:
view_manager.lookat(heading:180, pitch:20, roll:0, x:X0, y:Y0, z:Z0,
time:now, fov:55);
Declared arguments are checked and defaulted as would be expected:
it's an error if you fail to pass a value for an undefaulted argument,
missing default arguments get assigned, and any rest parameter
(e.g. "func(a,b=2,rest...){}") will be assigned with an empty vector.
2. Vector slicing. Vectors (lists) can now be created from others
using an ordered list of indexes and ranges. For example:
var v1 = ["a","b","c","d","e"]
var v2 = v1[3,2]; # == ["d","c"];
var v3 = v1[1:3]; # i.e. range from 1 to 3: ["b","c","d"];
var v4 = v1[1:]; # no value means "to the end": ["b","c","d","e"]
var i = 2;
var v5 = v1[i]; # runtime expressions are fine: ["c"]
var v6 = v1[-2,-1]; # negative indexes are relative to end: ["d","e"]
The range values can be computed at runtime (e.g. i=1; v5=v1[i:]).
Negative indices work the same way the do with the vector functions
(-1 is the last element, -2 is 2nd to last, etc...).
3. Multi-assignment expressions. You can assign more than one
variable (or lvalue) at a time by putting them in a parenthesized
list:
(var a, var b) = (1, 2);
var (a, b) = (1, 2); # Shorthand for (var a, var b)
(var a, v[0], obj.field) = (1,2,3) # Any assignable lvalue works
var color = [1, 1, 0.5];
var (r, g, b) = color; # works with runtime vectors too
FlightGear doesn't use. Also includes a performance fix for the
call() builtin that should help Melchior, who was measuring lower
performance for the props.Node() interface than the getprop/setprop
API.
So toss a runtime error ("floating point error") when any of the math
library functions produce a non-finite value. Note that these are not
the only locations that can do that (simply dividing by zero will
produce an Inf), but it's still proper behavior.
Nasal now supports calls to "subcontexts" and errors can be thrown
across them, leading to complete stack traces when call() is used,
instead of the truncated ones we now see.
Vectors can now be concatenated using the ~ operator that used to work
only for strings.
Better runtime error messages in general due to a fancier
naRuntimeError() implementation
A big data size shrink on 64 bit systems; the size of a naRef dropped
by a factor of two.
"Braceless code blocks" have been added to the parser, so you can
write expressions like "if(a) b();" just like in C. Note that there's
still a parser bug in there that fails when you nest a braced block
within a braceless one.
Character constants that appear in Nasal source code can now be
literal multibyte UTF8 characters (this was always supported for
string literals, but character constants were forced to be a single
byte).
New modules: "bits", "thread", "utf8" and (gulp...) "io". The bits
library might be useful to FlightGear, the utf8 one probably not as
Plib does not support wide character text rendering. The thread
library will work fine for spawning threads to do Nasal stuff, but
obviously contact with the rest of FlightGear must be
hand-synchronized as FlightGear isn't threadsafe. The io library is
no doubt the most useful, as it exposes all the basic stdio.h
facilities; it's also frighteningly dangerous when combined with
networked code...
Fix bug with break/continue inside of a foreach or forindex: Don't pop
the vector/index inside OP_EACH, do it at the end of the loop.
In the process, discovered and fixed a scary corruption issue with
continue; it never really worked right, although simple usage was
likely to get away without crashing. Both the continue's OP_BREAK and
the cleanup code at the end of a loop would pop the "mark" stack,
leading to an underflow. Introduced an OP_CONTINUE which adjusts
stack but doesn't change markTop
Re-inline the PUSH macro. This thing is called all over the place
from the inner loop. If the problem is intra-expression side effects,
then just use another expression in the macro.
Return an empty vector when requesting zero-length subvec, not nil
Have call() return the call stack in the error vector; see docs on
plausible.org/nasal or ask Andy about this feature.
Default closure()'s level argument to zero, not nil
Add an optional "file name" argument to compile()
uninitialized data bug in naHash_cget(). When the hashcode field of
naStr was introduced, I forgot to set it in this function, which
creates a temporary naStr on the stack.
subvec() to mean "the whole vector". Melchior showed a use case
(removal of the first element from a vector) where getting a
zero-length subvector is actually desired. And since I can't come up
with a good reason for why the "feature" was there in the first place,
out it goes...
inspect the string pointers. It also failed to properly sort strings
where one is a prefix of the other. It looks to me like I just never
finished this, and it ended up in CVS because it just happened to
compile...
to pop themselves down while the simulator is paused.
The problem was with the "real time" queue in the event manager,
causing the third argument of Nasal's settimer() (a flag for "sim
time") to be ignored. Inverts the default sense of the argument, as
there are lots of uses of settimer() in the current code, almost none
of which want to use real time.
Note this fix introduces a header file incompatibility in SimGear --
be sure to update.
*appears* to work correctly on all systems to which I have access
(i386 linux/win32, x86_64 linux, powerpc OS X, Sparc Solaris 10), but
not all systems are capable of running fgfs. Beyond that, multiple
threading bugs were fixed, and the naCall() API changed slightly to
support named function arguments.
NOTE: this introduces a change in the external API, and therefore this
change *must* be compiled against current FlightGear code.
patches; my private version has rewritten both of these functions
(ironically fixing these bugs in the process) to handle negative
offsets meaning "from the end".
foreach, except that the variable gets the index instead of the list
element. Should be useful, and took almost no code to implement.
Support for operator/assignment syntax: +=, -=, *=, /= and ~= now do
what you think they should.
Library support for a bind() function (see the docs Andy is still
writing), allowing runtime modifications to function lexical
environments.
that the column math goes wacky when lgalloced is allowed to be
zero.
Augment the find() function to take a starting index.
Fix strc() to use a default index of zero.
Fix parser precedence of TOK_MINUS, so that "a-b-1" means (a-b)-1 and
not a-(b-1).
code generation of constant objects to use real identity and not Nasal
equality, so (e.g.) the constants 1 (number) and "1.0" (string) do not
get turned into the same object in the generated code.
The error properly belongs to the enclosing scope, not the called
(non-)function. This bug was fixed a few months back in my private
tree, but Melchior just discovered that the new Concorde scripts
tickle it. I really need to re-synchronize SimGear with my own Nasal
tree...
a MinGW target:
Link against alut.dll in addition to openal32.dll.
Remove some preprocessor defines from compiler.h that were
confusing the mingw and/or libstdc++ headers (I put the _isnan
one back in the only file it was used).
Hack a broken sleep() call into the OpenAL sample programs so
that they will compile (but not work) in a non-POSIX environment.
Change the header file ordering in sample_openal.hxx to get
around some really weird interactions between MinGW's windows.h
and the gcc iostream header.
popped off the stack in a situation where it could be garbage
collected. I believe this is the source of the spurious "non-object
have no members" bug that has been reported.
uninitialized by naNum(). If it happened to be constructing it on the
stack in a location previously occupied by a real reference, it would
generate a corrupt naRef.