Unit Lexify;
{* S Compiler, ver 1.00.
   Copyright (C) 1994, Henri LESOURD.

   This software is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This compiler is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  *}

{ $DEFINE PTIT}

{$DEFINE MEMREAD}

Interface

Uses
    Symbolize;
Type
    ProcWord=Procedure(W : Word);
Var
   CallBackCR : ProcWord;

Const
    { Les noms }
      KeyPackage=0;KeyInclude=1;KeyUses=2;KeyInterface=3;KeyImplementation=4;
      KeyConst=5;KeyType=6;KeyVar=7;KeyStatic=8;
      KeyFar=44;{*LAST*}KeyDef=9;KeySub=10;
      KeyEnter=11;KeyLeave=12;
      KeyRecord=13;KeyIs=14;
      KeyIf=15;KeyThen=16;KeyBegin=17;KeyElse=18;KeyEnd=19;
      KeyAlways=20;KeyAwhile=21;KeyWhile=22;KeyWend=23;KeyDo=24;
      KeyFor=25;KeyTo=26;KeyDownTo=27;KeyToInf=28;KeyDowntoSup=29;
        KeyStep=30;KeyNext=31;
      KeyCase=32;KeyOf=33;KeyWhen=34;
      KeyLabel=35;KeyGoto=36;
      KeyInLine=37;
      KeyDeuxPoints=38;KeyCarriage=39;KeyPVirg=40;
      KeyPFerm=41;KeyCRFerm=42;
      KeyEOF=43;

      OpPoint=0;OpFlechePoint=1;
      OpPouvr=2;OpCrouvr=3;
      OpAdr=4;
      OpMoins=5;OpPlus=6;
      OpFleche=7;OpFlecheFleche=8;
      OpMul=9;OpDiv=10;OpMod=11;
      OpAdd=12;OpSub=13;
      OpEq=14;OpNeq=15;OpInf=16;OpInfEq=17;OpSup=18;OpSupEq=19;
      OpNot=20;OpAnd=21;OpOr=22;
      OpPointPoint=23;
      OpOf=24;
      OpAs=25;OpIs=26;
      OpLogNot=27;OpLogAnd=28;OpLogOr=29;OpLogXor=30;
      OpLeftShift=31;OpRightShift=32;
      OpLogAndLet=33;OpLogOrLet=34;OpLogXorLet=35;
      OpLeftShiftLet=36;OpRightShiftLet=37;
      OpModLet=38;
      OpLet=39;OpAddLet=40;OpSubLet=41;OpMulLet=42;OpDivLet=43;
      OpVirg=44;OpPVirg=45;
      OpNiv0=$3fff;

      PredExitDef=0;PredExitSub=1;
      PredExitWhile=2;PredExitFor=3;PredExitCase=4;
      PredLabel=5;PredRegister=6;
      PredBoolean=7;PredChar=8;
      PredByte=9;PredShortInt=10;
      PredWord=11;PredInt=12;
      PredLongWord=13;PredLongInt=14;
      PredArray=15;
      PredPointer=16;PredReference=17;
      PredSize=18;
      PredAX=19;PredBX=20;PredCX=21;PredDX=22;
      PredSP=23;PredBP=24;PredSI=25;PredDI=26;
      PredCS=27;PredDS=28;PredSS=29;PredES=30;
      PredResult=31;
      ValTVRef=32;
      ValTVPtr=33;
      ValTVArray=34;
      ValTVRecord=35;
      ValTVSub=36;
      ValTVDef=37;
    { Valeurs destin‚es uniquement … ˆtre pok‚es ds les .PAK }
      ValTVType=38;
      ValTVConst=39;
    { * }
      PredHigh=40;
      PredLow=41;
    { SELF }
      PredSelf=42;
    { USER }
      PredUserSymb=$3FFF;

      ConstChar=0;
      ConstString=1;
      ConstNum=2;
      BasedDec=2;BasedBin=6;BasedOct=$A;BasedHex=$E;
      Length8=0;Length16=$10;Length32=$20;

Var
   { Les Predefinis }
     SymbExitDef,SymbExitSub,
     SymbExitWhile,SymbExitFor,SymbExitCase,
     SymbLabel,SymbRegister,
     SymbBoolean,{SymbChar, }
     SymbByte,SymbWord,SymbLongWord,
     SymbShortInt,SymbInt,SymbLongInt,
     SymbArray,
     SymbPointer,SymbReference,
     SymbSize,
     SymbAX,SymbBX,SymbCX,SymbDX,
     SymbSP,SymbBP,SymbSI,SymbDI,
     SymbCS,SymbDS,SymbSS,SymbES,
     SymbResult,
     SymbHigh,SymbLow,
     SymbUnnamed
   :
     Symb;

Type
    { Les noeuds generaux }
      BoxPtr=^Box;
      Box=Record
            Nature : Word;
            Gauche,Droite : BoxPtr;
          End;

      LiNodePtr=^LiNode;
      LiNode=Record
               Nature : Word;
               Gauche,Droite : BoxPtr;
               NbCR : Word;
             End;

    { Les noeuds constants }
      CharBoxPtr=^CharBox;
      CharBox=Record
                Nature : Word;
                Value : Char;
              End;
      StringBoxPtr=^StringBox;
      StringBox=Record
                Nature : Word;
                Value : Word;
              End;
      ByteBoxPtr=^ByteBox;
      ByteBox=Record
                Nature : Word;
                Value : Byte;
              End;
      WordBoxPtr=^WordBox;
      WordBox=Record
                Nature : Word;
                Value : Word;
              End;
      LongBoxPtr=^LongBox;
      LongBox=Record
                Nature : Word;
                Value : LongInt;
              End;

    { Les valeurs des types }
      TVRefPtr=^TVRef;
      TVRef=Record
              Nature : Word;
              Size : Word;
              Next : TVRefPtr;
            End;
      TVPtrPtr=^TVPtr;
      TVPtr=Record
              Nature : Word;
              Size : Word;
              Next : TVPtrPtr;
            End;
      TVArrayPtr=^TVArray;
      TVArray=Record
                Nature : Word;
                Size : Word;
                Next : TVArrayPtr;
                NbElems : Word;
                FirstInd : Integer;
              End;
      TVRecElemPtr=^TVRecElem;
      TVRecElem=Record
                  Name : SymbPtr;
                  SType : SymbPtr;
                  Next : TVRecElemPtr;
                End;
      TVRecordPtr=^TVRecord;
      TVRecord=Record
                 Nature : Word;
                 Size : Word;
                 First : TVRecElemPtr;
               End;

    { Le noeud cons }
      ConsPtr=^Cons;
      Cons=Record
             Car : SymbPtr;
             Cdr : ConsPtr;
           End;
Var
   CurWord : Word;
   CurBox : BoxPtr;
   CurPtr : Pointer;

{ Les fonctions de test }
Function Nature(Idf : Word) : Word;
Function Name(Idf : Word) : Word;
Function IsReg(Idf : Word) : Boolean;
Function NumBase(Idf : Word) : Word;
Function NumLength(Idf : Word) : Word;
Function IsValTV(Idf : Word) : Boolean;
{ Les fonctions New }
Function NewBox(Idf : Word) : BoxPtr;
Function NewLiNode(Idf : Word) : BoxPtr;
{ Fonctions Lexer }
{$IFDEF MEMREAD}
Procedure StartLexify0;
Procedure EndLexify0;
{$ENDIF}
Procedure StartLexify(S : String);
Procedure EndLexify;

Var
   Buf : String;
   EqualIsLet,IsIsOpIs,OfIsOpOf,PVirgIsOpPVirg,EatCR : Boolean;
   NbSpaces,NbCalls : Word;
   NbKeyWordCalls,NbOperatorCalls : Word;
   NbSymbolCalls,NbConstantCalls : Word;

Procedure NextWord;
Procedure InitPredefSymbs;

Implementation

{$IFDEF MEMREAD}
Uses
    Errorify,Editify;
{$ELSE}
Uses
    Errorify;
{$ENDIF}

{ Les fonctions de test }
Function Nature(Idf : Word) : Word;
Begin
  Nature:=Idf And $C000;
End;

Function Name(Idf : Word) : Word;
Begin
  Name:=Idf And $3FFF;
End;

Function IsReg(Idf : Word) : Boolean;
Begin
  If (Idf And $C000)<>Symbol Then IsReg:=False
  Else
    IsReg:=((Idf And $3FFF)>=PredAX) And ((Idf And $3FFF)<=PredDI);
End;

Function NumBase(Idf : Word) : Word;
Begin
  NumBase:=Idf And $F;
End;

Function NumLength(Idf : Word) : Word;
Begin
  NumLength:=Idf And $30;
End;

Function IsValTV(Idf : Word) : Boolean;
Begin
  If (Name(Idf)>=ValTVRef) And
     (Name(Idf)<=ValTVRecord)
  Then
    IsValTV:=True
  Else
    IsValTV:=False;
End;

{ Les fonctions New }
Function NewBox(Idf : Word) : BoxPtr;
Var
   Result : BoxPtr;
Begin
  If Nature(Idf)=KeyWord Then NewBox:=NewLiNode(Idf)
  Else
    Begin
      New(Result);
      Result^.Nature:=Idf;
      Result^.Gauche:=Nil;
      Result^.Droite:=Nil;
      NewBox:=Result;
    End
End;

Function NewLiNode(Idf : Word) : BoxPtr;
Var
   Result : LiNodePtr;
Begin
  New(Result);
  Result^.Nature:=Idf;
  Result^.Gauche:=Nil;
  Result^.Droite:=Nil;
  Result^.NbCR:=NbCR;
  NewLiNode:=@Result^;
End;

Function NewCharBox(N : Word; V : Char) : CharBoxPtr;
Var
   Result : CharBoxPtr;
Begin
  New(Result);
  Result^.Nature:=Constant Or N;
  Result^.Value:=V;
  NewCharBox:=Result;
End;

Function NewStringBox(Var S : String) : StringBoxPtr;
Var
   Result : StringBoxPtr;
Begin
  New(Result);
  Result^.Nature:=Constant Or ConstString;
  Result^.Value:=StoreString(S);
  NewStringBox:=Result;
End;

Function NewByteBox(N : Word; V : Byte) : ByteBoxPtr;
Var
   Result : ByteBoxPtr;
Begin
  New(Result);
  Result^.Nature:=Constant Or N;
  Result^.Value:=V;
  NewByteBox:=Result;
End;

Function NewWordBox(N : Word; V : Word) : WordBoxPtr;
Var
   Result : WordBoxPtr;
Begin
  New(Result);
  Result^.Nature:=Constant Or N;
  Result^.Value:=V;
  NewWordBox:=Result;
End;

Function NewLongBox(N : Word; V : LongInt) : LongBoxPtr;
Var
   Result : LongBoxPtr;
Begin
  New(Result);
  Result^.Nature:=Constant Or N;
  Result^.Value:=V;
  NewLongBox:=Result;
End;

Var
   Cour : Char;
   BPtr : Byte;

Procedure EatSpak; ForWard;
Procedure ReadIdf; ForWard;

{$IFNDEF MEMREAD}
{ ******************************************************
  Fonctions Lexer : lecture directe ds le fichier source
  ****************************************************** }
Type
    SpeedBufType=Array[1..256] Of Char;
Var
   F : Text;
   SpeedBuf : SpeedBufType;

Function NextChar : Char;
Var
   C : Char;
Begin
  Read(F,C);
  NextChar:=C;
End;

Procedure StartLexify(S : String);
Begin
  If Not FileExists(S) Then Error('StartLexify : File Not Found');
  Assign(F,S);Reset(F);

  SetTextBuf(F,SpeedBuf);

  If Eof(F) Then Error('File is Empty')
  Else
    Cour:=NextChar;

  CurWord:=KeyWord Or KeyEOF;
  EqualIsLet:=True;
  PVirgIsOpPVirg:=False;
  OfIsOpOf:=True;
  EatCR:=False;

  NbCR:=0;NbCalls:=0;
  NbKeyWordCalls:=0;NbOperatorCalls:=0;
  NbSymbolCalls:=0;NbConstantCalls:=0;
End;

Type
    LexContext=Record
                 CurWord : Word;
                 EqualIsLet,PVirgIsOpPVirg,OfIsOpOf,EatCR : Boolean;
                 NbCR: Word;
                 F : Text;
                 SpeedBuf : SpeedBufType;
                 Cour : Char;
               End;
    CopyType=Array[1..SizeOf(Text)] Of Byte;
Var
   Imbricated : Boolean;
   LC : LexContext;
   CT1,CT2 : ^CopyType;

Procedure OpenInclude(S : String);
Begin
  If Imbricated Then Error('Lexify : OpenInclude : only 1 nesting level')
  Else
    Imbricated:=True;

{ Enregistrement du contexte }
  LC.CurWord:=CurWord;
  LC.EqualIsLet:=EqualIsLet;
  LC.PVirgIsOpPVirg:=PVirgIsOpPVirg;
  LC.OfIsOpOf:=OfIsOpOf;
  LC.EatCR:=EatCR;
  LC.SpeedBuf:=SpeedBuf;
  LC.Cour:=Cour;
  LC.NbCR:=NbCR;
  CT1:=@LC.F;
  CT2:=@F;
  CT1^:=CT2^;

  StartLexify(S);
  NextWord;
End;

Procedure EnterInclude;
Begin
  EatSpak;
  BPtr:=0;
  ReadIdf;
  OpenInclude(Concat(Buf,'.S'));
End;

Procedure CloseInclude;
Begin
{ Fermeture F }
  Close(F);

{ Restauration du contexte }
  CurWord:=LC.CurWord;
  EqualIsLet:=LC.EqualIsLet;
  PVirgIsOpPVirg:=LC.PVirgIsOpPVirg;
  OfIsOpOf:=LC.OfIsOpOf;
  EatCR:=LC.EatCR;
  SpeedBuf:=LC.SpeedBuf;
  Cour:=LC.Cour;
  NbCR:=LC.NbCR;
  CT2^:=CT1^;

{ Cassos }
  Imbricated:=False;
  EatSpak;
  If Cour<>',' Then NextWord
  Else
    Begin
      Cour:=NextChar;
      EnterInclude;
    End;
End;

Procedure EndLexify;
Begin
  Close(F);
End;
{$ELSE}
{ ********************************************************
  Fonctions Lexer : lecture directe ds le buffer d'‚dition
  ******************************************************** }
Type
    CharBuf=Array[0..$FFFE] Of Char;
    CharBufPtr=^CharBuf;
Var
   Buffer : CharBufPtr;
   BufferPtr,BufferSize : Word;

Function NextChar : Char;
Var
   C : Char;
Begin
  C:=Buffer^[BufferPtr];
  Inc(BufferPtr);
  NextChar:=C;
End;

Procedure StartLexify0;
Begin
  If Buffer=Nil Then
  Begin
    If GetBuffer=Nil Then Error('StartLexify0 : void Buffer')
    Else
      Buffer:=GetBuffer;
  End;
  If Size>$FFF0 Then Error('StartLexify0 : Buffer too big');
  Buffer^[Size]:=Chr(0);
  BufferPtr:=0;
  Cour:=NextChar;

  CurWord:=KeyWord Or KeyEOF;
  EqualIsLet:=True;
  PVirgIsOpPVirg:=False;
  OfIsOpOf:=True;
  EatCR:=False;

  NbCR:=0;NbCalls:=0;
  NbKeyWordCalls:=0;NbOperatorCalls:=0;
  NbSymbolCalls:=0;NbConstantCalls:=0;
End;

Procedure StartLexify(S : String);
Begin
  If Buffer=Nil Then Buffer:=AllocTextBuf(BufferSize);
  LoadText(S);
  StartLexify0;
End;

Procedure OpenInclude(S : String);
Begin
  Error('Lexify : OpenInclude : MEMREAD');
End;

Procedure EnterInclude;
Begin
  Error('Lexify : OpenInclude : MEMREAD');
End;

Procedure CloseInclude;
Begin
  Error('Lexify : CloseInclude : MEMREAD');
End;

Procedure EndLexify0;
Begin
End;

Procedure EndLexify;
Begin
  EndLexify0;
  If Buffer<>Nil Then
  Begin
    FreeMem(Buffer,BufferSize);
    Buffer:=Nil;
  End
  Else
    Error('EndLexify');
End;
{$ENDIF}

{ Il faut BPtr:=0 AVANT d'appeller }
Procedure EatSpak;
Begin
  While (Cour=' ') Or (Ord(Cour)=9) Or (Ord(Cour)=10) Or (Ord(Cour)=13) Do
  Begin
    If Cour=Chr($0D) Then Inc(NbCR);
    Cour:=NextChar;
  End;
End;

Procedure ReadIdf;
Begin
  Repeat
    Inc(BPtr);
    Buf[BPtr]:=UpCase(Cour);
    Cour:=NextChar;
  Until
    ((Ord(Cour)<Ord('0')) And (Ord(Cour)<>$27) And (Cour<>'$')) Or
    ((Ord(Cour)>Ord('z')) And (Ord(Cour)<$80)) Or
    ((Ord(Cour)>=Ord(':')) And (Ord(Cour)<=Ord('@'))) Or
    ((Ord(Cour)>=Ord('[')) And (Ord(Cour)<=Ord('^'))) Or
    (Cour='`') Or (Cour='ð');

  Buf[0]:=Chr(BPtr);
End;

Procedure CallFunc(O : Word);
Begin
  InLine($FF/$56/<O);
End;

Var
   LexFunc : Array[0..$FF] of Word;

Procedure UnKnown;
Begin
  Error('UnKnown character');
End;

Var
   AlphaFunc : Array[0..Ord('Z')-Ord('A')] of Word;

Procedure Symbole;
Begin
  CurWord:=Symbol Or $3FFF;
  CurPtr:=FindSymb(Buf);
  If CurPtr=Nil Then CurPtr:=NewSymb(Buf);
End;

{ Package }
Procedure AlphaP;
Begin
  If Buf='PACKAGE' Then CurWord:=KeyWord Or KeyPackage
  Else
    Symbole;
End;

{ Uses }
Procedure AlphaU;
Begin
  If Buf='USES' Then CurWord:=KeyWord Or KeyUses
  Else
    Symbole;
End;

{ Interface, Implementation, Include, If, Is, InLine }
Procedure AlphaI;
Begin
  If Buf='INTERFACE' Then CurWord:=KeyWord Or KeyInterface
  Else
  If Buf='IMPLEMENTATION' Then CurWord:=KeyWord Or KeyImplementation
  Else
  If Buf='INCLUDES' Then
    Begin
      CurWord:=KeyWord Or KeyInclude;
      EnterInclude;
    End
  Else
  If Buf='IF' Then CurWord:=KeyWord Or KeyIf
  Else
  If Buf='IS' Then
    If IsIsOpIs
    Then
      Begin
        CurWord:=Operator Or OpIs;
        CurPtr:=NewBox(CurWord);
      End
    Else
      CurWord:=KeyWord Or KeyIs
  Else
  If Buf='INLINE' Then CurWord:=KeyWord Or KeyInLine
  Else
    Symbole;
End;

{ Const, Case }
Procedure AlphaC;
Begin
  If Buf='CONST' Then CurWord:=KeyWord Or KeyConst
  Else
  If Buf='CASE' Then CurWord:=KeyWord Or KeyCase
  Else
    Symbole;
End;

{ Type, Then, To, To<, }
Procedure AlphaT;
Begin
  If Buf='TYPE' Then CurWord:=KeyWord Or KeyType
  Else
  If Buf='THEN' Then CurWord:=KeyWord Or KeyThen
  Else
  If Buf='TO' Then
    If Cour='<' Then
      Begin
        Cour:=NextChar;
        CurWord:=KeyWord Or KeyToInf;
      End
    Else
      CurWord:=KeyWord Or KeyTo
  Else
    Symbole;
End;

{ Def, Do, DownTo, DownTo> }
Procedure AlphaD;
Begin
  If Buf='DEF' Then CurWord:=KeyWord Or KeyDef
  Else
  If Buf='DO' Then CurWord:=KeyWord Or KeyDo
  Else
  If Buf='DOWNTO' Then
    If Cour='>' Then
      Begin
        Cour:=NextChar;
        CurWord:=KeyWord Or KeyDownToSup;
      End
    Else
      CurWord:=KeyWord Or KeyDownTo
  Else
    Symbole;
End;

{ Static, Sub, Step }
Procedure AlphaS;
Begin
  If Buf='SUB' Then CurWord:=KeyWord Or KeySub
  Else
  If Buf='STATIC' Then CurWord:=KeyWord Or KeyStatic
  Else
  If Buf='STEP' Then CurWord:=KeyWord Or KeyStep
  Else
    Symbole;
End;

{ While, Wend, When }
Procedure AlphaW;
Begin
  If Buf='WHILE' Then CurWord:=KeyWord Or KeyWhile
  Else
  If Buf='WEND' Then CurWord:=KeyWord Or KeyWend
  Else
  If Buf='WHEN' Then CurWord:=KeyWord Or KeyWhen
  Else
    Symbole;
End;

{ Enter, Else, End, Exit X }
Procedure AlphaE;
Begin
  If Buf='ENTER' Then CurWord:=KeyWord Or KeyEnter
  Else
  If Buf='ELSE' Then CurWord:=KeyWord Or KeyElse
  Else
  If Buf='END' Then CurWord:=KeyWord Or KeyEnd
  Else
  If Buf='EXIT' Then
    Begin
      NextWord;
      If (Nature(CurWord)<>KeyWord) Then Error('Exit : KeyWord Expected')
      Else
        If (Name(CurWord)=KeyDef) Then
          Begin
            CurWord:=Symbol Or PredExitDef;
            CurPtr:=@SymbExitDef;
          End
        Else
        If (Name(CurWord)=KeySub) Then
          Begin
            CurWord:=Symbol Or PredExitSub;
            CurPtr:=@SymbExitSub;
          End
        Else
        If (Name(CurWord)=KeyWhile) Then
          Begin
            CurWord:=Symbol Or PredExitWhile;
            CurPtr:=@SymbExitWhile;
          End
        Else
        If (Name(CurWord)=KeyFor) Then
          Begin
            CurWord:=Symbol Or PredExitFor;
            CurPtr:=@SymbExitFor;
          End
        Else
        If (Name(CurWord)=KeyCase) Then
          Begin
            CurWord:=Symbol Or PredExitCase;
            CurPtr:=@SymbExitCase;
          End
        Else
          Error('Exit : KeyWord Expected');
    End
  Else
    Symbole;
End;

{ For,Far }
Procedure AlphaF;
Begin
  If Buf='FOR' Then CurWord:=KeyWord Or KeyFor
  Else
  If Buf='FAR' Then CurWord:=KeyWord Or KeyFar
  Else
    Symbole;
End;

{ Next, Not }
Procedure AlphaN;
Begin
  If Buf='NEXT' Then CurWord:=KeyWord Or KeyNext
  Else
  If Buf='NOT' Then Begin
                      CurWord:=Operator Or OpNot;
                      CurPtr:=NewBox(CurWord);
                    End
  Else
    Symbole;
End;

{ Record }
Procedure AlphaR;
Begin
  If Buf='RECORD' Then CurWord:=KeyWord Or KeyRecord
  Else
    Symbole;
End;

{ Always, And, As }
Procedure AlphaA;
Begin
  If Buf='ALWAYS' Then CurWord:=KeyWord Or KeyAlways
  Else
  If Buf='AWHILE' Then CurWord:=KeyWord Or KeyAwhile
  Else
  If Buf='AND' Then
                 Begin
                   CurWord:=Operator Or OpAnd;
                   CurPtr:=NewBox(CurWord);
                 End
  Else
  If Buf='AS' Then
                Begin
                  CurWord:=Operator Or OpAs;
                  CurPtr:=NewBox(CurWord);
                End
  Else
    Symbole;
End;

{ Of, Or }
Procedure AlphaO;
Begin
  If Buf='OR' Then Begin
                     CurWord:=Operator Or OpOr;
                     CurPtr:=NewBox(CurWord);
                   End
  Else
  If Buf='OF' Then
    If OfIsOpOf Then
                  Begin
                    CurWord:=Operator Or OpOf;
                    CurPtr:=NewBox(CurWord);
                  End
    Else
      CurWord:=KeyWord Or KeyOf
  Else
    Symbole;
End;

{ Leave }
Procedure AlphaL;
Begin
  If Buf='LEAVE' Then CurWord:=KeyWord Or KeyLeave
  Else
    Symbole;
End;

{ Var }
Procedure AlphaV;
Begin
  If Buf='VAR' Then CurWord:=KeyWord Or KeyVar
  Else
    Symbole;
End;

{ Begin }
Procedure AlphaB;
Begin
  If Buf='BEGIN' Then CurWord:=KeyWord Or KeyBegin
  Else
    Symbole;
End;

{ Goto }
Procedure AlphaG;
Begin
  If Buf='GOTO' Then CurWord:=KeyWord Or KeyGoto
  Else
    Symbole;
End;

Procedure Alpha;
Begin
  ReadIdf;
  If Buf[1] in ['A'..'Z'] Then CallFunc(AlphaFunc[Ord(Buf[1])-Ord('A')])
  Else
    Symbole;
End;

Function ReadNumber(Base : Byte): LongInt;
Var
   I : Word;
   R : LongInt;
Label
     Boucle1,Boucle2;
Begin
  R:=0;
  If Base>10 Then
    Begin
Boucle1:
      If (Cour>='0') And (Cour<='9') Then
        Begin
          R:=Ord(Cour)-Ord('0')+R*Base;
          Cour:=NextChar;
          Goto Boucle1;
        End
      Else
      If (Cour>='A') And (Cour<=Chr(Base-11+Ord('A'))) Then
        Begin
          R:=Ord(Cour)-Ord('A')+$A+R*Base;
          Cour:=NextChar;
          Goto Boucle1;
        End
      Else
      If (Cour>='a') And (Cour<=Chr(Base-11+Ord('a'))) Then
        Begin
          R:=Ord(Cour)-Ord('a')+$A+R*Base;
          Cour:=NextChar;
          Goto Boucle1;
        End;
    End
  Else
    Begin
Boucle2:
      If (Cour>='0') And (Cour<=Chr(Base-1+Ord('0'))) Then
        Begin
          R:=Ord(Cour)-Ord('0')+R*Base;
          Cour:=NextChar;
          Goto Boucle2;
        End;
    End;

  ReadNumber:=R;
End;

Procedure Number;
Var
   R : LongInt;
Begin
  If Cour='&' Then
    Begin
      Cour:=NextChar;
      Case (Upcase(Cour)) Of
        'B': Begin CurWord:=BasedBin;Cour:=NextChar;R:=ReadNumber(2); End;
        'O': Begin CurWord:=BasedOct;Cour:=NextChar;R:=ReadNumber(8); End;
        'H': Begin CurWord:=BasedHex;Cour:=NextChar;R:=ReadNumber(16); End;
        Else
          Begin
            If Cour='=' Then
              Begin
                Cour:=NextChar;
                CurWord:=Operator Or OpLogAndLet;
              End
            Else
              CurWord:=Operator Or OpLogAnd;

            CurPtr:=NewBox(CurWord);
            Exit;
          End;
      End;
    End
  Else
    Begin
      CurWord:=BasedDec;R:=ReadNumber(10);
    End;

  If R>=0 Then
    If (R<$100) Then CurWord:=CurWord Or Length8
    Else
    If (R<$10000) Then CurWord:=CurWord Or Length16
    Else
      CurWord:=CurWord Or Length32
  Else
    CurWord:=CurWord Or Length32;

  Case (NumLength(CurWord)) Of
    Length8: CurPtr:=NewByteBox(CurWord,Byte(R));
    Length16: CurPtr:=NewWordBox(CurWord,Word(R));
    Length32: CurPtr:=NewLongBox(CurWord,R);
  End;

  CurWord:=Constant Or CurWord;
End;

Procedure Chaine;
Begin
  Repeat
    Cour:=NextChar;
    Inc(BPtr);Buf[BPtr]:=Cour;
  Until (Cour='"') Or (Cour=#$1A) Or (Cour=#$D);
  If (Cour=#$1A) Or (Cour=#$D) Then Error('Unterminated String')
                               Else Cour:=NextChar;
  If BPtr=0 Then Error('String too long');
  Buf[0]:=Chr(BPtr-1);
  CurWord:=Constant Or ConstString;
  CurPtr:=NewStringBox(Buf);
End;

Procedure Character;
Begin
  Cour:=NextChar;
  If (Cour=#$1A) Or (Cour=#$D) Or (Cour=#$A) Then Error('Bad Char Const');
  CurWord:=Constant Or ConstChar;
  CurPtr:=NewCharBox(CurWord,Cour);
  Cour:=NextChar;
  If Cour<>'''' Then Error('Unterminated Char Const') Else Cour:=NextChar;
End;

Procedure Remark;
Begin
  Repeat
    Cour:=NextChar;
    If (Cour=#$D) Then Inc(NbCR);
  Until (Cour='\') Or (Cour=#$1A);
  If Cour=#$1A Then Error('Unterminated comment') Else Cour:=NextChar;
  NextWord;
End;

Procedure Space;
Begin
  Repeat Cour:=NextChar; Until (Cour<>' ') And (Ord(Cour)<>9);
  NextWord;
End;

Procedure Carriage;
Var
   CurWordBis : Word;
Begin
  Cour:=NextChar;
  If Cour<>#$A Then Error('Bad CR Format (0D0A expected)');
  Cour:=NextChar;
  CurWordBis:=KeyWord Or KeyCarriage;
  NbSpaces:=0;
  While (Cour=' ') Do
  Begin
    Inc(NbSpaces);
    Cour:=NextChar;
  End;
  Inc(NbCR);
  CallBackCR(NbCR);
  If EatCR Then NextWord
           Else CurWord:=CurWordBis;
End;

Procedure EndOfFile;
Begin
{$IFDEF MEMREAD}
  CurWord:=KeyWord Or KeyEOF;
{$ELSE}
  If Imbricated Then CloseInclude
  Else
    CurWord:=KeyWord Or KeyEOF;
{$ENDIF}
End;

Procedure Point;
Begin
  Cour:=NextChar;
  If (Cour='.') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpPointPoint;
    End
  Else
    CurWord:=Operator Or OpPoint;

  CurPtr:=NewBox(CurWord);
End;

Procedure Pouvr;
Begin
  CurWord:=Operator Or OpPouvr;
  Cour:=NextChar;
End;

Procedure Pferm;
Begin
  CurWord:=KeyWord Or KeyPferm;
  Cour:=NextChar;
End;

Procedure Crouvr;
Begin
  CurWord:=Operator Or OpCrouvr;
  Cour:=NextChar;
End;

Procedure Crferm;
Begin
  CurWord:=KeyWord Or KeyCrferm;
  Cour:=NextChar;
End;

Procedure Arroba;
Begin
  CurWord:=Operator Or OpAdr;
  Cour:=NextChar;
  CurPtr:=NewBox(CurWord);
End;

Procedure Tilda;
Begin
  Cour:=NextChar;
  If Cour='=' Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpLogXorLet;
    End
  Else
    If (Nature(CurWord)=Constant) Or
       (Nature(CurWord)=Symbol) Or
       (CurWord=(Operator Or OpFleche)) Or
       (CurWord=(KeyWord Or KeyPferm)) Or
       (CurWord=(KeyWord Or KeyCRferm))
    Then
      CurWord:=Operator Or OpLogXor
    Else
      CurWord:=Operator Or OpLogNot;

  CurPtr:=NewBox(CurWord);
End;

Procedure Pipe;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpLogOrLet;
    End
  Else
    CurWord:=Operator Or OpLogOr;

  CurPtr:=NewBox(CurWord);
End;

Procedure Moins;
Begin
  Cour:=NextChar;
  If Cour='=' Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpSubLet;
    End
  Else
    If (Nature(CurWord)=Constant) Or
       (Nature(CurWord)=Symbol) Or
       (CurWord=(Operator Or OpFleche)) Or
       (CurWord=(KeyWord Or KeyPferm)) Or
       (CurWord=(KeyWord Or KeyCRferm))
    Then
      CurWord:=Operator Or OpSub
    Else
      CurWord:=Operator Or OpMoins;

  CurPtr:=NewBox(CurWord);
End;

Procedure Plus;
Begin
  Cour:=NextChar;
  If Cour='=' Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpAddLet;
    End
  Else
    If (Nature(CurWord)=Constant) Or
       (Nature(CurWord)=Symbol) Or
       (CurWord=(Operator Or OpFleche)) Or
       (CurWord=(KeyWord Or KeyPferm)) Or
       (CurWord=(KeyWord Or KeyCRferm))
    Then
      CurWord:=Operator Or OpAdd
    Else
      CurWord:=Operator Or OpPlus;

  CurPtr:=NewBox(CurWord);
End;

Procedure Fleche;
Begin
  Cour:=NextChar;
  If (Cour='~') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpFlecheFleche;
    End
  Else
{ If (Cour='.') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpFlechePoint;
    End
  Else }
    CurWord:=Operator Or OpFleche;

  CurPtr:=NewBox(CurWord);
End;

Procedure Mul;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpMulLet;
    End
  Else
    CurWord:=Operator Or OpMul;

  CurPtr:=NewBox(CurWord);
End;

Procedure Slash;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpDivLet;
    End
  Else
    CurWord:=Operator Or OpDiv;

  CurPtr:=NewBox(CurWord);
End;

Procedure Percent;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpModLet;
    End
  Else
    CurWord:=Operator Or OpMod;

  CurPtr:=NewBox(CurWord);
End;

Procedure Eq;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpEq;
    End
  Else
    If EqualIsLet Then
      CurWord:=Operator Or OpLet
    Else
      CurWord:=Operator Or OpEq;

  CurPtr:=NewBox(CurWord);
End;

Procedure Equal;
Begin
  CurWord:=Operator Or OpEq;
  CurPtr:=NewBox(CurWord);
  Cour:=NextChar;
End;

Procedure DeuxPoints;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpLet;
      CurPtr:=NewBox(CurWord);
    End
  Else
    CurWord:=KeyWord Or KeyDeuxPoints;
End;

Procedure Inf;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpInfEq;
    End
  Else
  If (Cour='>') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpNeq;
    End
  Else
  If (Cour='<') Then
    Begin
      Cour:=NextChar;
      If (Cour='=') Then
        Begin
          Cour:=NextChar;
          CurWord:=Operator Or OpLeftShiftLet;
        End
      Else
        CurWord:=Operator Or OpLeftShift;
    End
  Else
    CurWord:=Operator Or OpInf;

  CurPtr:=NewBox(CurWord);
End;

Procedure Sup;
Begin
  Cour:=NextChar;
  If (Cour='=') Then
    Begin
      Cour:=NextChar;
      CurWord:=Operator Or OpSupEq;
    End
  Else
  If (Cour='>') Then
    Begin
      Cour:=NextChar;
      If (Cour='=') Then
        Begin
          Cour:=NextChar;
          CurWord:=Operator Or OpRightShiftLet;
        End
      Else
        CurWord:=Operator Or OpRightShift;
    End
  Else
    CurWord:=Operator Or OpSup;

  CurPtr:=NewBox(CurWord);
End;

Procedure Virg;
Begin
  CurWord:=Operator Or OpVirg;
  CurPtr:=NewBox(CurWord);
  Cour:=NextChar;
End;

Procedure PVirg;
Begin
  If PVirgIsOpPVirg Then
    Begin
      CurWord:=Operator Or OpPVirg;
      CurPtr:=NewBox(CurWord);
    End
  Else
    CurWord:=KeyWord Or KeyPVirg;

  Cour:=NextChar;
End;

Procedure NextWord;
Begin
  BPtr:=0;
  CallFunc(LexFunc[Ord(Cour)]);
{ Inc(NbCalls);
  If (Nature(CurWord)=KeyWord) Then Inc(NbKeyWordCalls);
  If (Nature(CurWord)=Operator) And (Name(CurWord)<>OpPouvr) Then Inc(NbOperatorCalls);
  If (Nature(CurWord)=Symbol) Then Inc(NbSymbolCalls);
  If (Nature(CurWord)=Constant) Then Inc(NbConstantCalls); }
  CurBox:=CurPtr;
End;

{$F+}
Procedure CRChanged(W : Word);
Begin
End;
{$F-}

Procedure InitPredefSymbs;
Begin
  SymbAX.Nature:=Symbol Or PredAX;
  SymbBX.Nature:=Symbol Or PredBX;
  SymbCX.Nature:=Symbol Or PredCX;
  SymbDX.Nature:=Symbol Or PredDX;
  SymbSP.Nature:=Symbol Or PredSP;
  SymbBP.Nature:=Symbol Or PredBP;
  SymbSI.Nature:=Symbol Or PredSI;
  SymbDI.Nature:=Symbol Or PredDI;
  SymbCS.Nature:=Symbol Or PredCS;
  SymbDS.Nature:=Symbol Or PredDS;
  SymbSS.Nature:=Symbol Or PredSS;
  SymbES.Nature:=Symbol Or PredES;
  SymbAX.Addr.C:=Register;
  SymbBX.Addr.C:=Register;
  SymbCX.Addr.C:=Register;
  SymbDX.Addr.C:=Register;
  SymbSP.Addr.C:=Register;
  SymbBP.Addr.C:=Register;
  SymbSI.Addr.C:=Register;
  SymbDI.Addr.C:=Register;
  SymbCS.Addr.C:=Register;
  SymbDS.Addr.C:=Register;
  SymbSS.Addr.C:=Register;
  SymbES.Addr.C:=Register;
  SymbAX.Addr.Value:=AX;
  SymbBX.Addr.Value:=BX;
  SymbCX.Addr.Value:=CX;
  SymbDX.Addr.Value:=DX;
  SymbSP.Addr.Value:=SP;
  SymbBP.Addr.Value:=BP;
  SymbSI.Addr.Value:=SI;
  SymbDI.Addr.Value:=DI;
  SymbCS.Addr.Value:=rCS;
  SymbDS.Addr.Value:=rDS;
  SymbSS.Addr.Value:=rSS;
  SymbES.Addr.Value:=rES;
{ Plus tard, refoutre @SymbRegister ds le SType }
  SymbAX.Addr.SType:=@SymbWord;
  SymbBX.Addr.SType:=@SymbWord;
  SymbCX.Addr.SType:=@SymbWord;
  SymbDX.Addr.SType:=@SymbWord;
  SymbSP.Addr.SType:=@SymbWord;
  SymbBP.Addr.SType:=@SymbWord;
  SymbSI.Addr.SType:=@SymbWord;
  SymbDI.Addr.SType:=@SymbWord;
  SymbCS.Addr.SType:=@SymbWord;
  SymbDS.Addr.SType:=@SymbWord;
  SymbSS.Addr.SType:=@SymbWord;
  SymbES.Addr.SType:=@SymbWord;
  SymbExitDef.Nature:=Symbol Or PredExitDef;
  SymbExitSub.Nature:=Symbol Or PredExitSub;
  SymbExitWhile.Nature:=Symbol Or PredExitWhile;
  SymbExitFor.Nature:=Symbol Or PredExitFor;
  SymbExitCase.Nature:=Symbol Or PredExitCase;
  SymbLabel.Nature:=Symbol Or PredLabel;
  SymbRegister.Nature:=Symbol Or PredUserSymb;
  SymbRegister.Addr.C:=Null;
  SymbBoolean.Nature:=Symbol Or PredUserSymb;
  SymbBoolean.Addr.C:=Null;
  SymbByte.Nature:=Symbol Or PredByte;
  SymbByte.Addr.C:=CType;
  SymbByte.Addr.Value:=1;
  SymbByte.Addr.SType:=Nil;
  SymbWord.Nature:=Symbol Or PredWord;
  SymbWord.Addr.C:=CType;
  SymbWord.Addr.Value:=2;
  SymbWord.Addr.SType:=Nil;
  SymbLongWord.Nature:=Symbol Or PredLongWord;
  SymbLongWord.Addr.C:=CType;
  SymbLongWord.Addr.Value:=4;
  SymbLongWord.Addr.SType:=Nil;
  SymbShortInt.Nature:=Symbol Or PredShortInt;
  SymbShortInt.Addr.C:=CType;
  SymbShortInt.Addr.Value:=1;
  SymbShortInt.Addr.SType:=Nil;
  SymbInt.Nature:=Symbol Or PredInt;
  SymbInt.Addr.C:=CType;
  SymbInt.Addr.Value:=2;
  SymbInt.Addr.SType:=Nil;
  SymbLongInt.Nature:=Symbol Or PredLongInt;
  SymbLongInt.Addr.C:=CType;
  SymbLongInt.Addr.Value:=4;
  SymbLongInt.Addr.SType:=Nil;
  SymbArray.Nature:=Symbol Or PredArray;
  SymbArray.Addr.C:=CType;
  SymbArray.Addr.Value:=0;
  SymbArray.Addr.SType:=Nil;
  SymbPointer.Nature:=Symbol Or PredPointer;
  SymbPointer.Addr.C:=CType;
  SymbPointer.Addr.Value:=4;
  SymbPointer.Addr.SType:=Nil;
  SymbReference.Nature:=Symbol Or PredReference;
  SymbReference.Addr.C:=CType;
  SymbReference.Addr.Value:=4;
  SymbReference.Addr.SType:=Nil;
  PutSymb(@SymbAX,'AX');
  PutSymb(@SymbBX,'BX');
  PutSymb(@SymbCX,'CX');
  PutSymb(@SymbDX,'DX');
  PutSymb(@SymbSP,'SP');
  PutSymb(@SymbBP,'BP');
  PutSymb(@SymbSI,'SI');
  PutSymb(@SymbDI,'DI');
  PutSymb(@SymbCS,'CS');
  PutSymb(@SymbDS,'DS');
  PutSymb(@SymbSS,'SS');
  PutSymb(@SymbES,'ES');
  PutSymb(@SymbLabel,'LABEL');
  PutSymb(@SymbRegister,'REGISTER');
  PutSymb(@SymbBoolean,'BOOLEAN');
  PutSymb(@SymbShortInt,'SHORTINT');
  PutSymb(@SymbInt,'INT');
  PutSymb(@SymbLongInt,'LONGINT');
  PutSymb(@SymbByte,'BYTE');
  PutSymb(@SymbWord,'WORD');
  PutSymb(@SymbLongWord,'LONGWORD');
  PutSymb(@SymbArray,'ARRAY');
  PutSymb(@SymbPointer,'POINTER');
  PutSymb(@SymbReference,'REFERENCE');
  SymbResult.Addr.C:=Null;
  SymbResult.Addr.SType:=Nil;
  SymbResult.Nature:=Symbol Or PredResult;
  PutSymb(@SymbResult,'RESULT');
  SymbHigh.Addr.C:=Null;
  SymbHigh.Addr.SType:=Nil;
  SymbHigh.Nature:=Symbol Or PredHigh;
  PutSymb(@SymbHigh,'HIGH');
  SymbLow.Addr.C:=Null;
  SymbLow.Addr.SType:=Nil;
  SymbLow.Nature:=Symbol Or PredLow;
  PutSymb(@SymbLow,'LOW');
  SymbSize.Addr.C:=Null;
  SymbSize.Addr.SType:=Nil;
  SymbSize.Nature:=Symbol Or PredSize;
  PutSymb(@SymbSize,'SIZE');
  SymbUnnamed.Addr.C:=Null;
  SymbUnnamed.Addr.SType:=Nil;
  SymbUnnamed.Nature:=Symbol Or PredUserSymb;
  PutSymb(@SymbUnnamed,'UNNAMED');
End;

Var
   I : Integer;

Begin
{ Init LexBurst }
{ Init Tab a UnKnown }
  For I:=0 to $FF Do LexFunc[I]:=Ofs(UnKnown);
{ Caracteres Alpha }
  For I:=Ord('A') to Ord('Z') Do LexFunc[I]:=Ofs(Alpha);
  For I:=Ord('a') to Ord('z') Do LexFunc[I]:=Ofs(Alpha);
  For I:=$80 to $FF Do LexFunc[I]:=Ofs(Alpha);
  LexFunc[Ord('#')]:=Ofs(Alpha);
{ Constantes numeriques }
  For I:=Ord('0') to Ord('9') Do LexFunc[I]:=Ofs(Number);
  LexFunc[Ord('&')]:=Ofs(Number);
{ Constantes char et string }
  LexFunc[Ord('"')]:=Ofs(Chaine);
  LexFunc[Ord('''')]:=Ofs(Character);
{ Remarques }
  LexFunc[Ord('\')]:=Ofs(Remark);
{ Espaces }
  LexFunc[Ord(' ')]:=Ofs(Space);
  LexFunc[9]:=Ofs(Space);
{ Carriage }
  LexFunc[Ord(#$D)]:=Ofs(Carriage);
{ EOF }
  LexFunc[0]:=Ofs(EndOfFile);
  LexFunc[Ord(#$1A)]:=Ofs(EndOfFile);
{ Operateurs }
{ . .. }
  LexFunc[Ord('.')]:=Ofs(Point);
{ ( }
  LexFunc[Ord('(')]:=Ofs(Pouvr);
{ ) }
  LexFunc[Ord(')')]:=Ofs(Pferm);
{ [ }
  LexFunc[Ord('[')]:=Ofs(Crouvr);
{ ] }
  LexFunc[Ord(']')]:=Ofs(Crferm);
{ @ }
  LexFunc[Ord('@')]:=Ofs(Arroba);
{ | ~ }
  LexFunc[Ord('|')]:=Ofs(Pipe);LexFunc[Ord('~')]:=Ofs(Tilda);
{ -1 - -=; +1 + += }
  LexFunc[Ord('-')]:=Ofs(Moins);LexFunc[Ord('+')]:=Ofs(Plus);
{ ^ ^^ ^. }
  LexFunc[Ord('^')]:=Ofs(Fleche);
{ * *=; / /=; % %= }
  LexFunc[Ord('*')]:=Ofs(Mul);LexFunc[Ord('/')]:=Ofs(Slash);
  LexFunc[Ord('%')]:=Ofs(Percent);
{ eq/let }
  LexFunc[Ord('=')]:=Ofs(Eq);
{ ð }
  LexFunc[Ord('ð')]:=Ofs(Equal);
{ : }
  LexFunc[Ord(':')]:=Ofs(DeuxPoints);
{ <> <= <; > >= }
  LexFunc[Ord('<')]:=Ofs(Inf);LexFunc[Ord('>')]:=Ofs(Sup);
{ , ; }
  LexFunc[Ord(',')]:=Ofs(Virg);LexFunc[Ord(';')]:=Ofs(PVirg);

{ Init àBurst }
{ Init Tab a Symbole }
  For I:=0 to Ord('Z')-Ord('A') Do AlphaFunc[I]:=Ofs(Symbole);
  AlphaFunc[Ord('P')-Ord('A')]:=Ofs(AlphaP);
  AlphaFunc[Ord('U')-Ord('A')]:=Ofs(AlphaU);
  AlphaFunc[Ord('I')-Ord('A')]:=Ofs(AlphaI);
  AlphaFunc[Ord('C')-Ord('A')]:=Ofs(AlphaC);
  AlphaFunc[Ord('T')-Ord('A')]:=Ofs(AlphaT);
  AlphaFunc[Ord('D')-Ord('A')]:=Ofs(AlphaD);
  AlphaFunc[Ord('S')-Ord('A')]:=Ofs(AlphaS);
  AlphaFunc[Ord('W')-Ord('A')]:=Ofs(AlphaW);
  AlphaFunc[Ord('E')-Ord('A')]:=Ofs(AlphaE);
  AlphaFunc[Ord('F')-Ord('A')]:=Ofs(AlphaF);
  AlphaFunc[Ord('N')-Ord('A')]:=Ofs(AlphaN);
  AlphaFunc[Ord('R')-Ord('A')]:=Ofs(AlphaR);
  AlphaFunc[Ord('A')-Ord('A')]:=Ofs(AlphaA);
  AlphaFunc[Ord('O')-Ord('A')]:=Ofs(AlphaO);
  AlphaFunc[Ord('L')-Ord('A')]:=Ofs(AlphaL);
  AlphaFunc[Ord('V')-Ord('A')]:=Ofs(AlphaV);
  AlphaFunc[Ord('B')-Ord('A')]:=Ofs(AlphaB);
  AlphaFunc[Ord('G')-Ord('A')]:=Ofs(AlphaG);

{ = ð let, Of ð OpOf }
  EqualIsLet:=True;
  IsIsOpIs:=True;
  OfIsOpOf:=True;
  PVirgIsOpPVirg:=False;
  EatCR:=False;

{ Init Predefinis }
  InitPredefSymbs;

{ Flag Imbricated }
{$IFNDEF MEMREAD}
  Imbricated:=False;
{$ENDIF}

{ Buffer d'‚dition }
{$IFDEF MEMREAD}
  Buffer:=Nil;
{$IFDEF PTIT}
  BufferSize:=10000;
{$ELSE}
  BufferSize:=$FFF0;
{$ENDIF}
  EditErrorHandler:=Error;
{$ENDIF}

{ CallBackCR }
  CallBackCR:=CRChanged;
End.
