Nasal scripting language: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(Some more cleanup)
 
(12 intermediate revisions by 3 users not shown)
Line 1: Line 1:
:''Please note that a considerable amount of resources has not yet been incorporated here, you can check these out by going to the [[Talk:Nasal scripting language|discussion page]], where we are collecting links to webpages and mailing list discussions/postings related to Nasal.''
{{Nasal Navigation}}
'''Nasal''' is FlightGear's built-in scripting language. Originally written and developed by Andy Ross for a personal project, it was integrated into FlightGear in November 2003, and has been continuously developed, improved, and refined since then. Over time, it has become probably FlightGear's most powerful, and has been used to create a huge variety of systems, ranging from [[wildfire simulation|wildfires]] to [[Control Display Unit]]s.


[[FlightGear]] offers a very powerful functional '''scripting language''' called '''[http://plausible.org/nasal/ Nasal]''', which supports reading and writing of internal [[Property Tree Intro|FlightGear properties]], accessing internal data via extension functions, creating GUI dialogs and much more.  
Within FlightGear, Nasal supports the reading and writing of internal [[Property Tree|properties]], accessing internal data via extension functions, creating GUI dialogs and much, much more. Please see the right navigation bar to get additional information.


{{WIP}}
[[File:Highlight parse.png]]<!--
{{Template:Nasal Navigation}}


== Hello world ==
<syntaxhighlight lang="nasal">
 
# to be saved in $FG_ROOT/Nasal/hello.nas
A simple hello world example in Nasal would be:
print("Hello World!");
 
<syntaxhighlight lang="php">
# hello.nas
print('Hello World!');
</syntaxhighlight>
</syntaxhighlight>


This will show the "Hello World" string during startup in the console window. The hash sign (#) just introduces comments (i.e. will be ignored by the interpreter).
[[File:Vim-nasal-syntax-highlighting.png]]
 
Note: Script-specific symbols such as global variables (or functions) will be put into a scope (namespace) based on the script's name, scripts embedded via aircraft-set.xml files can separately specify a corresponding module name (see [[Howto: Make an aircraft]] for details).
 
Strings in Nasal can also use double quotes which support escaping:
<syntaxhighlight lang="php">
# hello.nas
print("Hello\nWorld!");
</syntaxhighlight>
 
Double quotes support typical escape sequences:
 
* \n Newline
* \t Horizontal Tab
* \v Vertical Tab
* \b Backspace
* \r Carriage Return
* \f Form feed
* \a Audible Alert (bell)
* \\ Backslash
* \? Question mark
* \' Single quote
* \" Double quote
 
For example, to print a new line, use:
 
print ("\n");
 
To print a quoted string, use:
 
print ("\"quoted string\"");
 
and so on.
 
Single quotes treat everything as literal except for embedded single quotes (including embedded whitespace like newlines).
 
Nasal strings are always arrays of bytes (never characters: see the utf8 library if you want character-based equivalents of substr() et. al.). They can be indexed just like in C (although note that there is no nul termination -- get the length with size()):
 
==Built-in functions==
 
===sort(vector, function)===
Creates a new vector containing the elements in the input vector sorted in ascending order according to the rule given by function, which takes two arguments (elements of the input vector) and should return less than zero, zero, or greater than zero if the first argument is, respectively, less than, equal to, or greater than the second argument. Despite being implemented with ANSI C qsort(), the sort is stable; "equal" elements in the output vector will appear in the same relative order as they do in the input.
 
Because you can define the sort function, sort allows you to create a list of keys sorting a hash by any criterion--by key, value, or (if, for instance the hash values are hashes themselves) any subvalue.
 
vec = [100,24,45];
sortvec = sort (vec, func (a,b) cmp (a,b));
debug.dump (sortvec); #output is [24,45,100]
 
Here is an example of how to output the contents of a hash in sorted order.  Note that the function does not actually sort the hash but returns a list of the hash keys in sorted order.
 
var airport = {
  "LOXZ": "Zeltweg",
  "LOWI": "Innsbruck",
  "LOXL": "Linz Hoersching",    # the last comma is optional
};
var sortedkeys= sort (keys(airport), func (a,b) cmp (airport[a], airport[b]));
foreach (var i; sortedkeys)
  print (i, ": ", airport[i]);
 
The output is:
 
  LOWI: Innsbruck
  LOXL: Linz Hoersching
  LOXZ: Zeltweg 
 
If the hash values are themselves hashes, sorting by any of the subvalues is possible.  For example:
 
var airport = {
    "LOXZ": {city: "Zeltweg", altitude_m: 1300 },
    "LOWI": {city: "Innsbruck", altitude_m: 2312 },
    "LOXL": {city: "Linz Hoersching", altitude_m: 1932 },
};
 
#return a list of the hash keys sorted by altitude_m
var sortedkeys= sort (keys(airport), func (a,b) airport[a].altitude_m - airport[b].altitude_m);
 
foreach (var i; sortedkeys)
  print (i, ": ", airport[i].city, ", ", airport[i].altitude_m);
 
Note that ''sort'' will return errors, and in FG 2.4.0 may even stop working, if the sort function you provide returns errors.  A common cause of this is if your sort vector contains both string and numeric values.  The cmp function will return an error for numeric values, and arithmetic operations you may use to sort numeric values will return errors if performed on a string.  The error in these cases is typically "function/method call on uncallable object".
 
=== Other useful built-in functions ===
 
Other basic built-in Nasal functions such as append, setsize, subvec, typeof, contains, delete, int, num, keys, pop, size, streq, cmp, substr, sprintf, find, split, rand, call, die, bind, math.sin, math.pi, math.exp, math.ln math.e, io.read, io.write, regex.exec, and others of that sort,  are detailed in [http://www.plausible.org/nasal/lib.html this external document].
 
=== Useful functions in the Nasal directory ===
Other functions are available in the Nasal files found in the Nasal directory of a FlightGear install. Simply open those Nasal files in text editor to see what is inside.  Reference those functions by putting the filename in front of the function, method, variable, or object you wish to use.  For instance, to use the method Coord.new() in the file geo.nas, you simply write:
 
geo.Coord.new()
 
=== Distance calculations ===
 
To calculate the distance between two points (in two different ways):
# mylat1, mylong1, mylat2, mylong2 are lat & long in degrees
# myalt1 & myalt2 are altitude in meters
var GeoCoord1 = geo.Coord.new();
GeoCoord1.set_latlon(mylat1, mylong1,myalt1);
var GeoCoord2 = geo.Coord.new();
GeoCoord2.set_latlon(mylat2, mylong2, myalt2);
var directDistance = GeoCoord1.direct_distance_to(GeoCoord2);
var surfaceDistance = GeoCoord1.distance_to(GeoCoord2);
 
The results are distances in meters.
 
* distance_to - returns distance in meters along Earth curvature, ignoring altitudes; useful for map distance
* direct_distance_to - returns distance in meters direct; considers altitude, but cuts through Earth surface
 
=== Other useful geographical functions ===
Other useful geographical functions are found in geo.nas (in the <tt>[[$FG_ROOT]]/Nasal</tt> directory of a FlightGear installation). geo.nas also includes documentation/explanation of the functions available.
 
== Related content ==
{{Forum|30|Nasal}}
* [[:Category:Nasal]]
 
=== External links ===
* http://www.plausible.org/nasal


{{Appendix}}
{{Nasal Efforts}}


[[Category:Nasal]]
-->[[Category:Nasal]]

Latest revision as of 19:17, 28 August 2016

Nasal is FlightGear's built-in scripting language. Originally written and developed by Andy Ross for a personal project, it was integrated into FlightGear in November 2003, and has been continuously developed, improved, and refined since then. Over time, it has become probably FlightGear's most powerful, and has been used to create a huge variety of systems, ranging from wildfires to Control Display Units.

Within FlightGear, Nasal supports the reading and writing of internal properties, accessing internal data via extension functions, creating GUI dialogs and much, much more. Please see the right navigation bar to get additional information.

Highlight parse.png