Act of War Wiki
Advertisement
autosize
"What? Those tapes are classified!"
This section of the Act of War wiki is archived, containing information from defunct fansites and wikis.
Do NOT edit any information in the archives unless it is fixing up spelling mistakes.

The NDF language reference manual[]

Warning As you will notice in the following text, the NDF language is a real programming language.
As such, a reference manual is required to explain the syntax and semantics of its features.
This manual can be read start to end but the best is to refer to it to obtain a piece of information on a specific trait of the language.
Enjoy your reading !

Introduction[]

NDF language allows to create objects of a given native class.
You can then set the value of the object properties as required.


Syntax[]

Character set[]

NDF files should be encoded using the ISO-8859-1 encoding, also know as latin-1.


Keywords[]

In alphabetic order :
const, else, end, GROUPE_SEMANTIQUE, if, map, nil, object (obsolet), prototype (obsolet), RGB, RGBA, StringList, template, then, VECTOR, with,

NDF is not case sensitive, MAP, MaP and map are, for example, the same keyword.


Comments[]

One line comments start with '//'

// This is a one line comment 
 

Multi-line comments start with '{' and end with '}'

 
{
 This is a
 multi-line comment
}

Base types[]

Boolean[]

Can take two values : TRUE or FALSE


String[]

They can define the printable 8 bit ASCII chars

There are three syntaxic forms to define string :

  • By using simple quotes
 
'I say : "This is a string"'
  • By using double quotes
 
"This is a string, isn'it ?"
  • By using three double quotes
 
"""
This is a multi-line string
It spans several lines
"""

Extended string[]

Extended string allows to define Unicode strings, that is to say roughly 16 bits encoded chars.
In order to use classic 8 bits editors to input these strings (NotePad, UltraEdit, ...), they are encoded using UTF7 encoding.

WideString['+eLpbmg-']

Integer[]

Integer values are defined using decimal base.
Integer are coded in 32 bits and are signed.
Integer can contain values between -2^16-1 and +2^16-1

Associared regular expression:

 [0-9][0-9]*

Float[]

Float number are coded on 10 bytes.
They are signed.
They can take positive or negative values between 3.6 x 10^–4951 and 1.1 x 10^4932
It contains between 19 and 20 significative digits. The scientific notation can also be used.

 
3.1415954
5.6E+5  // is the same as 5.6 x 10^5 = 5 600 000

Associated regular expression :

 [0-9]+(\.[0-9]+)?([eE](\+|\-)?[0-9]+)?

Vector[]

A vector is a point in a 3D space.

 
VECTOR[1.23, 4.56, 5.67]

RGB color[]

RGBA color[]

It's a vector in a 4D space : Red, Green, Blue, Transparency.
Values are non signed 8 bits values, between 0 and 255.

D3DRGBA[255, 0, 0, 127]

List[]

List can contain 0 to an infinite number of elements, each element is separated from the others by a comma.

 
// a empty list
[]
 
// a list of integers
[1, 2, 3]
 
// a list of any types
[1, TRUE, 'Hello', 1.234]

String List[]

String list is a special kind of list that can only contain 8 bits string.

 
// This is a String list with 3 strings
StringList['one', 'two', 'three']
 
// A empty String list
StringList[]

Map[]

A map allow to specify an association between a string, the key, and a value of any type.

 
map [
    ('one', 1),
    ('two', 2.3),
    ('three', TRUE)
    ]

Note: in order to have case insensitive maps, the key are converted to upper case.
This is very important when a Map is used to pass parameters to a block of Python code.


Symbol[]

A symbol is a label used as argument to a template and that has a semantic only when used in the context of the template.
A label start with a letter or '<' or '.' or '$' or '~' and is follow by 0 or an infinite number of letters or digits or '/' or '.' or '<' or '>' or '$' or '~' and can optionally end with '?'.

Associated regular expression:

 [a-z_A-Z\<\.\$~][a-z_A-Z0-9\/\.\<\>\$~]*(\?)?

See below for the definition of a template.


Reference[]

A reference is a label corresponding to the name of an object.
A reference can be empty, and is then equal to nil


Absolute[]

  • Relative to the root namespace

In this case, the reference starts with '$'.

  $/TypeWarrior/TypeWarrior_US_Marine

Relative[]

  • The first matched
 TypeWarrior_US_Marine
  • Relative to the current loading namespace

In thid case, the reference starts with '~'

 ~/TypeWarrior_US_Marine
  • Relative to the current namespace

In this case, the reference starts with '.'

 ./TypeWarrior_US_Marine

Optionally[]

A reference that ends with '?' is said to be optionally.
This means that if the reference cannot be resolved to an object, it will be set to 'nil without raising any errors.
This naming scheme is compatible with the others kind of naming :

 TypeWarrior_US_Marine?
 $/TypeWarrior/TypeWarrior_US_Marine?
 ~/TypeWarrior_US_Marine?
 ./TypeWarrior_US_Marine?

Byte packet[]

Named base types[]

Boolean, integer, float, string, list and map objects can be named using a light syntax

 
MyInteger is 5
MyFloat is 3.14
MyString is 'Hello'
MyList is [1, 2, 3]
MyMap is MAP[('Key', 777)]

Expression[]

Arithmetic operations[]

Classic operations are supported :

  • Addition with the '+' sign
  • Soustraction with the '-' sign
  • Multiplication with the '*' sign
  • Division with the 'div' sign
  • Modulo with the 'mod' sign
 
(((10 + 5) * (15 - 5)) div 10) mod 5

List element and sub list[]

This feature is also called 'slicing' and allow to extract an element or a sub list from a given list.
This also works with StringList and string.
This also works with Map to get an element with its key.

MyaList[:n] is the sub list that contains the first n elements from MyList
MyList[-n:] is the sub list that contains the last n elements from MyList
MyList[:] is a copy of MyList
MyList[n:n] is an empty, it is the same as []

Operations can be done using this notation :

 
(MyList[0] + MyList[1]) * (MyList[2] + MyList[3])
MyStringList[0]
MyFilenameUsing_8_3_naming[-3:] // to get the 3 letters extension for example
MyDico['MyKey']

Structures[]

Constant[]

A constant block start with const and ends with end.
Every constant is defined using the following syntax : ConstantName = Value

A constant block can be used only in the file that defines it

 
const
   NB_ELEMENT = 5
   PATH = 'data\avi'
   USE_DEBUG = True
   SIZE_X = 100
   SHIFT = 150
   WIDTH = SHIFT + NB_ELEMENT * SIZE_X
end

Semantic group[]

A semantic group allows, like a constant block, to define constants. But a semantic group can be used, when defined, everywhere.
It is defined using a block starting with GROUPE_SEMANTIQUE and ending with end

A semantic group :

  • is named
  • contains fields defined using the following syntax : FieldName = Value
  • allow to use value using the following syntax : SemanticGroupName.FieldName
 
GROUPE_SEMANTIQUE ParamTypeWarriorMarine_US
  UnitName = 'US Marine'
  HP = 500
end

Object[]

An object is an instance of a native class.


Object description[]

An object is described by

  • its nama
  • its class
  • the list of values associated to its properties
 
MyObject is TTruc
(
 ValueInteger = 666
)

Namming[]

Object naming allows objects to be used by others and documents its usage.


anonymous[]

Naming can be anonymous, in this case the object has no name and can't be referenced.

 
TTruc
(
 ValueString = "I'm an anonymous object, you can't reference me"
)

anonymous without created namespace[]

An object, either anonymouds or not, does create a namespace using its name :

  • Here, the absolute name of object HisObject is $/MyObject/YourObject/HisObject
 
MyObject is TTruc
(
 AutreTruc = YourObject is TTruc
             (
               AutreTruc = HisObject is TTruc()
             )
)


  • Here, the absolute name of object HisObject is $/MyObject//HisObject
 
MyObjet is TTruc
(
 AutreTruc = TTruc
             (
               AutreTruc = HisObject is TTruc()
             )
)


  • In this last case, the absolute name of object HisObject is $/MyObject/HisObject
 
MyObject is TTruc
(
 AutreTruc = _ is TTruc
             (
               AutreTruc = HisObject is TTruc()
             )
)

This kind of naming is used in a template to create new objects at the root namespace.


comment naming[]

Comment naming allows to give name to object to document them but without allowing them to be referenced.
The name start with '~' and ends with '~'

 
~MyObjectUsedWhenBlaBlaBla~ is TTruc()

regular[]

Its the main case, object is named using a label.

 
MyObject_Main_Case is TTruc()

Prototype[]

A prototype is an object that can be used a reference for the creation of a new object.
Every named object can be used as a prototype.

 
MyObjectUsedAsPrototype is TTruc
(
 ValueString = 'I will be used as a prototype'
 ValueInteger = 222
)
 
MyObjectUsingThePrototype is MyObjectUsedAsPrototype
(
 ValueString = "It's me"
)

MyObjectUsingThePrototype has the same property values than MyObjectUsedAsPrototype, except the ones explicitly overriden.
For example, the ValueString property value is different.

Template[]

A template allows to create one or several objects given a list of arguments.
A template looks like what is called a macro in others languages but with some nice bonus.

Template description[]

A template is defined with :

  • a keyword template
  • a list of arguments with optionnaly a default value
  • a class or a template or a prototype
 
// Template definition
Template MyTemplate[TheIntegerValue, TheStringValue = ] is TTruc
(
 ValueInteger = <TheIntegerValue>
 ValueString  = <TheStringValue>
)
 
// Usage
MyObject is MyTemplate
(
 TheIntegerValue = 666
)

Template with template[]

A template can use another template.

 
// template definition
Template MyOtherTemplate[ActorName] is MyTemplate
(
 TheIntegerValue = 555
 TheStringValue  = <ActorName>
)

Included object override[]

A template can also contain objects.

 
Template MyTemplate[TheIntegerValue, TheStringValue = ] is TTruc
(
 ObjetIncluded is TTruc
 (
   ValueInteger = <TheIntegerValue>
   ValueString  = <TheStringValue>
 )
 
 AutreTruc = ObjetIncluded
)

Another template can use the first template and override the included object ObjetIncluded

Template MyOtherTemplate[TheIntegerValue, TheStringValue = ] is MyTemplate
(
 ValeurEntiere = <TheIntegerValue>
 ValeurChaine  = <TheStringValue>
 
 ObjetIncluded is TTruc
 (
   ValueInteger = <TheIntegerValue> + 10
   ValueString  = 'Hello' + <TheStringValue>
 )
)

NDF type[]

base type[]

compound type[]

If Then Else[]

This structure is like the #ifdef #else #endif of C++.
It allows to select only one of the two branches, at loading time, using the value returned by a condition.
The condition is evaluated at loading time and should return a boolean value.

 
MyObject is TTruc
(
 if True then
    ValueInteger = 666
 else
    ValueInteger = 777  // this code is never evaluated !
 end
)

NDF function[]

A NDF function is a called to a native function.
In most of the cases, a call to this kind of function create an object but this is not mandatory.

The syntax is the same than object creation.
Here, Equal is a NDF function.

MyBoolean is TEUGBBoolean
(
 Value = TRUE
)
 
MyObject is TTruc
(
 if Equal(arg1 = MyBoolean arg2 = True) then
    ValueString = 'MyBoolean is TRUE'
 else
    ValueString = 'MyBoolean is FALSE'
 end
)

Available NDF function :

  • Equal, EqualListeNil, EqualNil, Lesser, Greater
  • Round, Floor, Ceil
  • Min, Max
  • ...

Advanced features[]

Transactions[]

Object visibility[]

The object visibility is the way the reference this object.

There are 5 visibility types :

  • default visibility : if the visibility is not explicitly defined
  • private : the object is visible inside the object which contains it
  • package : the object is visible inside the file where it is defined
  • public : the object is visible inside the namespace which contains the file where it is defined (example : $/TypeWarrior)
  • export : the object is visible anywhere

The default visibility is precised for each namespace.

Meta-programming using template[]

Meta-programming is language structure composition to generate new structures.
If the language used in meta-programming is the one generated, the language is said to be meta-circular.

Meta-programming can be done in most of the languages that feature macro ou template like structures.
Meta-programming can hence be done in C++, Lisp, ...

NDF has a macro like structure with the template.

Why use this concept[]

  • it allows to write less code
  • it allows to write code much tied with specifications
  • it allows to pre-generate objects at loading time in order to speed execution time

When use this concept[]

  • when a template has a list of arguments of the same kind, like Arg1, Arg2, ..., ArgN
  • when the code to write repeat itselft
  • when data have to be seperated from their use (see samples)

Samples[]

Get the number of elements in a list

 
Template ListCount [ List ] is TEUGBInteger
(
   if EqualListeVide(<List>) then
      Value = 0
   else
      Value = 1 + ListCount ( List = <List>[1:] )
   end
)

Recursive template is always of the same kind:

  • Case of the empty list or of a null value, in order to avoid infinite recursion
  • Case of N relative to case N-1

Optimisation[]

Recursive template can be optimized by using terminal recursion.

Why optimize
Because a recursive template not written in terminal recursion form :

  • does create a temporary object at every iteration done
  • may potentially eat all the stack (after around 350 recursions)

A template written using the terminal recursion form :

  • don't create temporary object at every recursion done
    • recursion is transformed to a jump at the beginning of the template with arguments updated with new values
  • don't use stack space at all beacause there is no function call stacking
  • does execute faster because function call are now absolute jump

Hence, the number of element in a list can be written as follow, using terminal recursion :

 
Template ListCount [ List, acc = 0 ] is TEUGBInteger
(
   if EqualListeVide(<List>) then
      Value = <acc>
   else
      Value = ListCount(List = <List>[1:]
                        acc  = <acc> + 1)
   end
)

We must use an accumulator, conventionnaly named acc, that is used to store the value return by the template, when the recursion ends.

Advertisement