FANDOM


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 !

IntroductionEdit

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

SyntaxEdit

Character setEdit

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

KeywordsEdit

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.

CommentsEdit

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 typesEdit

BooleanEdit

Can take two values : TRUE or FALSE

StringEdit

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 stringEdit

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-']

IntegerEdit

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

Associated regular expression:

 [0-9][0-9]*

FloatEdit

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]+)?

VectorEdit

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.

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.