Why C-?
------------
The following features from the standard  are not supported:
   Directives: #error, #import(has a different purpose in Flat C-), #include_next, #line, #pragma, #warning.
   No hash digraph ( <: <% etc). No inline, volatile, Complex, Generic, auto, register, restrict.
   Probably, I've forgotten to mention something.

Why Flat?
---------
The compiler has a built-in FASM engine for code generation, without macros and other features of FASM,
and uses flat memory model.

=============================================================
Flat C- produces 64-bit executables for Windows platform only.
=============================================================

Flat C- directives.
-------------------
#import "dllname" - imports function names from the DLL library for use in linking executable code.
#include "filename" - opens file for compilation. The file name and path must be specified.
      The search function is not implemented.
      Examples: #include "kernel.h-" open file in current directory;
      "..\\xxx\\file.c" open file in subdirectory "xxx" of current directory.
#list - listing the compiled program.
#debug, #dbgall - create file with debugging information for the x64dbg debugger.
      The name of the file looks like: <program>.exe.dd64.
      #debug - only global labels (variables and functions wil be included in .dd64.
      #deball - global labels, local labels and source lines, as comments.
#gui - produce executables for gui. By default, console programs are created.
#resource "file.res" - the specified resource file is used when compiling.

Main features of Flat C-.
----------------------
1. Built-in assembler with FASM syntax. You can freely use assembler code anywhere inside the functions.
   For example:
         void OutByte(char b){
            xchg [outptr],rdi; mov al,[b]; stosb; xchg [outptr],rdi;
            if(f_list){
               push rcx rdx rsi;
               sprintf(&info,"%2x ",b);
               fprint(outputfp,&info);
               add dword[LstStrLen],3; pop rsi rdx rcx;
            }
            mov al,[b];
         }
   All supported instructions are listed in file mnem.txt.
   In assembler you can use all registers freely, except rax,rcx,eax,ecx,ax,cx and byte registers
   al,ah,cl,ch, which are used in expression processing.
   You can use registers in expression. For example: a+=edx; will be compiled as the following code:
      push rdx
      movsxd rax, dword[a]
      pop rcx
      add rax, rcx
      mov [a], eax

2. Conditional statement - 'docase'.
    Used for multiple coditional branching. Statements 'continue' and 'break' can be used inside.
       docase{
       >  some statements here
             case(cond1){
             some statements here;
             .................       >Ŀ
             }                            
             case(cond2){                 
                some statements here;     
                break; >>
                some statements here;     
             }                            
             ......                       
             case(condN){                 
                some statements here;     
       < continue;                 
                some statements here; >>
              }                            
             default:                      
                some statements here; >>
       }                                   
       .... <

3. Aliasing - used to replace local variables or function parameters or pointers with registers in
   expressions. :: - operation symbol (var::rdi or *ptr::rbx).
   For example, for a function
      typedef struct {
         int a;
         char c;
      } ZZZ;
      void func(ZZZ *z){
         z->a+=4;
      }
   such code can be compiled:
         ; t.c(13):    z->a+=4;
         ; push  4
         ; mov   rax , [ rbp + 16 ]
         ; movsxd rax , [ rax ]
         ; pop   rcx
         ; add   rax , rcx
         ; push  rax
         ; mov   rax , [ rbp + 16 ]
         ; pop   rcx
         ; mov   [ rax ] , ecx
   When assigning an alias to a parameter z,
      void func(ZZZ *z::r11){
         z->a+=4;
      }
   the code will be different:
         ; t.c(13):    z->a+=4;
         ; push  4
         ; movsxd rax , [ r11 ]
         ; pop   rcx
         ; add   rax , rcx
         ; push  rax
         ; pop   rcx
         ; mov   [ r11 ] , ecx
   If function has aliased parameters or variables, code for saving and initializing the registers,
   used in that function, will be placed into the function's prolog.
   Those registers will be restored in the end of the function.
   The following code will be in the beginning of the function: push r11; mov r11,qword[rbp+16],
   and the following code will be at the function's end: pop r11 for above example.

4. Key 'on' may be used for the 'switch' operator, as well as 'case':
   switch(bl){
      case 'a' ... 'z': return 1;
      on '0' ... '9': return 0;
   }

5. Calling convention 'fastcall' is realized for functions. Parameters for this function are passed via registers
   rcx,rdx,r8,R9 for integers or xmm0..xmm3 for floating type values. For example:
     int fastcall main (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
   function prolog will be:
      main:
         ; push  rbp
         ; mov   rbp , rsp
         ; mov   qword [ rbp + 16 ] , rcx
         ; mov   qword [ rbp + 24 ] , rdx
         ; mov   qword [ rbp + 32 ] , r8
         ; mov   qword [ rbp + 40 ] , r9

6. Flat C- when compiled, unused functions are not included in the final executable. Thus, for example,
   the function a2() will not be included, since there are no calls to it:
         #list
         void main(int p){
            a1(p+2);
         }
         int a2(int p2){
            p2++;
         }
         int a1(int p1){
            return p1-=10;
         }
         main:
         00401000: 55                                    ; push  rbp
         00401001: 48 89 E5                              ; mov   rbp , rsp
                 ;; t.c(13):    a1(p+2);
         00401004: 6A 02                                 ; push  2
         00401006: 48 63 45 10                           ; movsxd        rax , [ rbp + 16 ]
         0040100A: 59                                    ; pop   rcx
         0040100B: 48 01 C8                              ; add   rax , rcx
         0040100E: 50                                    ; push  rax
         0040100F: E8 00000000                           ; call  a1
         00401014: 48 83 C4 08                           ; add   rsp , 8
         @L0:
         00401018: 5D                                    ; pop   rbp
         00401019: C3                                    ; ret
         a1:
         0040101A: 55                                    ; push  rbp
         0040101B: 48 89 E5                              ; mov   rbp , rsp
         0040101E: 6A 0A                                 ; push  10
         00401020: 48 63 45 10                           ; movsxd        rax , [ rbp + 16 ]
         00401024: 59                                    ; pop   rcx
         00401025: 48 29 C8                              ; sub   rax , rcx
         00401028: 89 45 10                              ; mov   [ rbp + 16 ] , eax
         @L1:
         0040102B: 5D                                    ; pop   rbp
         0040102C: C3                                    ; ret
   The same  is applicable to global variables.

7. Flat C- is self-hosting.
