/*******************************************************************************/
//
// D languge syntax highlighting examples for the KDE Kate source code editor.
//
// Simon J Mackenzie : mailto:project.d@smackoz.fastmail.fm
//
// VERSION: 0.02, August 18, 2003.
//
/*******************************************************************************/
//
// NOTE: This code is guaranteed to unsuccessfully compile!!!
//
/*******************************************************************************/
//
// What's New for KATE Syntax Highlighting, VERSION: 0.02.
//
// - D Version 0.69 language additions now supported.
// - Floats now supported.
// - Embedded underscores in integer and float literals are now supported.
//

   dchar aDchar;                          // Added dchar keyword for UCS-32 characters.
   char[] freda = 'a character literal';  // ' ' strings are now character literals, not strings.
   char[] fredb = r"wysiwyg";             // wysiwyg strings are now r"string", not 'string'.
   char[] fredc = `wysiwyg`;              // `string` (backquotes) are also wysiwyg strings.
   char[] fredd = x"oa AA BF";            // Added x"0a AA BF" style hex strings.

   char[] frede = x"0A";                  // same as "\x0A
   char[] fredf = x"00 FBCD 32FD A";      // same as "\x00\xFB\xCD\x32\xFD\x0A"

// The following are all equivalent:
   char[] fredg = "ab" "c";
   char[] fredh = r"ab" r"c";
   char[] fredi = r"a" "bc";
   char[] fredj = "a" ~ "b" ~ "c";
   char[] fredk = \x61"bc";               // Should \0x61 be \x61 ???

//
// Embedded underscores in integer and float literals are supported.
//
// Floats:
   0x1.FFFFFFFFFFFFFp1023; // double.max
   0x1p-52i;               // double.epsilon
   1.175494351e-38F;       // float.min
   6.3i;                   // idouble 6.3
   6.3fi;                  // ifloat 6.3
   6.3LI;                  // ireal 6.3
   0__._3_e+3_45_f;
   1__.6;
      ._6_e-3_4__li;
   3__._4;
   45_____e-2;
   45_____e2;
   45_.___e2;
      .45_e2;
   0x1.___p34;
   0x1____p-2;
   0x1a2p2;
   0x1a2p+2;
   0x1a2p-2;
   0x1A2.3B4p0;
   0x1a2.3b4P2;


// Array ranges now highlight correctly if both range values use the same base. i.e. oct..oct, int..int etc:
   char [23 .. 498_555ul]     // integers
   int  [0 ..2_3]
   char [0b01 .. 0B0101_1111] // binary
   char [0213 ..047_555]      // octal
   int  [0x1_.. 0x2_3]        // hexadecimal

//
/*******************************************************************************/

module kate;      // name of this source code module

import string,   /* block comments */
      c.stdlib; /+ block comments +/

//
// D Comments
//

   /* Characters */
   // Characters EndOfLine
   /+ Characters +/


/*


   Block comments can be collasped.


*/


/+


   Block comments can be collasped.


+/

{


   // Braces can be collasped.


}

//
// D Character Literals
//

   char[] fred1 = 'hello';
   char[] fred2 = 'c:\root\foo.exe';
   char[] fred3 = 'ab\n';

//
// D String Literals
//

   char[] fred4 = "hello";
   char[] fred5 = "c:\\root\\foo.exe";
   char[] fred6 = "ab\n";               // string is 3 characters, 'a', 'b', and a linefeed
   char[] fred7 = "ab
";                                      // string is 3 characters, 'a', 'b', and a linefeed

//
// Escape strings start with a \ and form an escape character sequence.  Adjacent escape strings are concatenated:
//

   \n          // the linefeed character
   \t          // the tab character
   \"          // the double quote character
   \0712       // octal
   \x1A        // hex
   \u1234      // wchar character
   \U00101234  // dchar character
   \r\n        // carriage return, line feed

   char[] fred = "hello " ~ "world" ~ \U01234321 \n ~ \n\t\r\n\0234567\x1caA ~ \"\"\r\n\t;

/+
   Integer Literals


   IntegerLiteral:
            Integer
            Integer IntegerSuffix

   Integer:
            Decimal
            Binary
            Octal
            Hexadecimal

   IntegerSuffix:
   l
   L
   u
   U
   lu
   Lu
   lU
   LU
   ul
   uL
   Ul
   UL
+/

// Decimal:
   long alonga  = 2066l;
   long alongb  = 2066L;
   uint auinta  = 2066u;
   uint auintb  = 2066U;
   ulong ulonga = 2066lu;
   ulong ulongb = 2066Lu;
   ulong ulongc = 2066lU;
   ulong ulongd = 2066LU;
   ulong ulonge = 2066ul;
   ulong ulongf = 2066uL;
   ulong ulongg = 2066Ul;
   ulong ulongh = 2_066_UL;

   int anInta =       0_;   // 0
   int anIntb =       1_;   // NonZeroDigit
   int anIntc =  12_345_;   // NonZeroDigit Decimal

// Binary:
   int aBinarya = 0b0101_0110_UL;   // 0b BinaryDigits
   int aBinaryb = 0B1110_0110_;     // 0B BinaryDigits
   int aBinaryc = 0b0101_0110uL;    // 0b BinaryDigits
   int aBinaryd = 0B1110_0110_;     // 0B BinaryDigits
   int aBinarye = 0b01010110Ul;     // 0b BinaryDigits
   int aBinaryf = 0B11100110;       // 0B BinaryDigits

// Octal:
   int anIntd =  02_337_lu;         // 0 OctalDigits

// Hexadecimal:
   int anInte = 0x12a6_Lu;          // 0x HexDigits
   int anIntf = 0x12a6_LU;          // 0x HexDigits
   int anIntg = 0x12a6UL;           // 0x HexDigits
   int anInth = 0X12a6_;            // 0X HexDigits

/+
   Floating Literals


   FloatLiteral:
            Float
            Float FloatSuffix
            Float ImaginarySuffix
            Float FloatSuffix ImaginarySuffix

   Float:
            DecimalFloat
            HexFloat
            Float _

   FloatSuffix:
            f
            F
            l
            L

   ImaginarySuffix:
            i
            I

   Floats can be in decimal or hexadecimal format, as in standard C.

   Hexadecimal floats are preceded with a 0x and the exponent is a p or P followed by a power of 2.


   Floating literalss can have embedded '_' characters, which are ignored. The embedded '_' are useful for formatting long literals to make them more readable, such as using them as a thousands separator:

         123_456.567_8           // 123456.5678
         1_2_3_4_5_6_._5_6_7_8   // 123456.5678
         1_2_3_4_5_6_._5e-6_     // 123456.5e-6

   Floats can be followed by one f, F, l or L suffix. The f or F suffix means it is a float, and l or L means it is an extended.

   If a floating literal is followed by i or I, then it is an ireal (imaginary) type.
+/

// Examples:
   0x1.FFFFFFFFFFFFFp1023   // double.max
   0x1p-52i                 // double.epsilon
   1.175494351e-38F         // float.min
   6.3i                     // idouble 6.3
   6.3fi                    // ifloat 6.3
   6.3LI                    // ireal 6.3

// It is an error if the literal exceeds the range of the type. It is not an error if the literal is rounded to fit into the significant digits of the type.
// Complex literals are not tokens, but are assembled from real and imaginary expressions in the semantic analysis:

   float sargo = 4.5 + 6.2i // complex number

   float max = 3.2;
   float doe = .3456e-23;
   float rae = 1.23e-23fi;
   float me = .3333e-2li;

// Keyword:
   abstract
   alias
   align
   asm
   assert
   auto

   bit
   body
   break
   byte

   case
   cast
   catch
   cent
   char
   class
   cfloat
   cdouble
   creal
   const
   continue

   dchar
   debug
   default
   delegate
   delete
   deprecated
   do
   double

   else
   enum
   export
   extern int afunction(void);

   false
   final
   finally
   float
   for
   function

   super
   null
   new
   short
   int
   long
   ifloat
   idouble
   ireal
   if
   switch
   synchronized
   return
   goto
   struct
   interface
   import string;
   static
   override
   in
   out
   inout
   private
   protected
   public
   invariant
   real

   this
   throw
   true
   try
   typedef

   ubyte
   ucent
   uint
   ulong
   union
   ushort

   version
   void
   volatile

   wchar
   while
   with


// Pragma
// # line Integer EndOfLine
// #line Integer "Filespec" EndOfLine

   int #line 6 "foo\bar"
   x;                   // this is now line 6 of file foo\bar
   # line  3 "foo/bar" // Pragmas are now working correctly.
   #line 3 "foo/bar"


   if () {
      // some code
   }
   else {
      // dodah
   }

unittest {
   assert(1>2);

   debug = fred;


   debug(fred)
   debug printf("__eh_finddata(address = x%x)\n", address);
   debug printf("_deh_beg = x%x, _deh_end = x%x\n", &_deh_beg, &_deh_end);

}

extern char *strupper(char *str);

extern (C) {
   extern IID IID_IUnknown;
   extern IID IID_IClassFactory;
   extern IID IID_IMarshal;
   extern IID IID_IMallocSpy;
   extern IID IID_IStdMarshalInfo;
   extern IID IID_IExternalConnection;
   extern IID IID_IMultiQI;
   extern IID IID_IEnumUnknown;
   extern IID IID_IBindCtx;

   int afunction(int var1);   // external c call.
}

version = fred;

version (fred)
{

   // Version stuff here

}

version (X86) {
   asm
   {
      db 5,6,0x83;   // insert bytes 0x05, 0x06, and 0x83 into code
      ds 0x123_4;    // insert bytes 0x34, 0x12
      di 0x1234;     // insert bytes 0x34, 0x12, 0x00, 0x00
      dl 0x1234;     // insert bytes 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
      df 1.23_4_;    // insert float 1.234
      dd 1.234;      // insert double 1.234
      de 1.234;      // insert extended 1.234
      db "abc";      // insert bytes 0x61, 0x62, and 0x63
      ds "abc";      // insert bytes 0x61, 0x00, 0x62, 0x00, 0x63, 0x00
   }
}