unit dt2x86;
interface

Uses
  d2type;



  Var
          _token_type:lexType;(* тип лексемы                      *)
          _token:string;       (* внешнее представление лексемы    *)
          _tok:rsvType;       (* внутреннее представление лексемы *)
          _number_tok:word;
          e:integer;

Function Input:pSt;
Procedure InitInput(Path:String);
Procedure DoneInput;

Procedure PutBack;
Procedure Token;

{Function ByteNumber:Byte;
Function WordNumber:Word;}


Implementation

Uses
        dengine;

  Var
        St : pSt;


  Procedure InitInput(Path:String);
  Var
    TempSt:pSt;
  Begin
    TempSt:=New(pSt);
    TempSt^.Name:=New(pString,Init(Path));
    Assign(TempSt^.T,Path);
    {$I-}
    Reset(TempSt^.T);
    If IOResult <> 0 Then ErrorMsg(Input,'can''nt open text');
    TempSt^.Line:=1;
    TempSt^.Column:=0;
    TempSt^.Stream:=False;
    Read(TempSt^.T,TempSt^.Ch);
    TempSt^.Next:=St;
    St:=TempSt
  end;

  Procedure DoneInput;
  Var
    Del : pSt;
  Begin
    If St=Nil Then ErrorMsg(Input,'file not open');
    Del:=St;
    St:=Del^.Next;
    Dispose(Del^.Name,Done);
    Dispose(Del);
  End;

  Function Input:pSt;
  Begin
    Input:=St
  End;

  Function ReadCh:Char;
  Begin
    If Not (Eof(Input^.T) And (CurSub<>Nil)) Then Begin
      ReadCh:=Input^.Ch;
      Read(Input^.T,Input^.Ch);
      If Input^.Ch=#10 Then Begin
        Inc(Input^.Line);
        Input^.Column:=0;
      End;
      Inc(Input^.Column);
    End Else
      ErrorMsg(Input,'unexpected end of file');
  End;

  Function IfUpCase(Ch:Char):Char;
  Begin
    If cseFLG then
      IfUpCase:=UpCase(Ch)
    Else
      IfUpCase:=Ch
  End;


  (* Возвращает лексему обратно во входной поток *)
  Procedure PutBack;
  Begin
    Input^.Stream:=True
  End;

  (* compiler directive *)
  Procedure Directive(D:Char);

    Function Prev(D:Char):Boolean;
    Begin
    End;

    Procedure SetMode(Var Flag:Boolean;M:Char);
    Begin
      Case M Of
      '+':Flag:=True;
      '-':Flag:=False;
      '*':Flag:=Prev(D);
      Else errorMsg(Input,'illegal directive toggle');
      End;
    End;

    Var
      M:Char;
      W:Word;
      E:Integer;

  Begin
    token;
    token;
    If _token_type = _NUMBER then begin
      {$I-}
      val(_token,W,E);
      if E<>0 then errorMsg(Input,'illegal number format');
      case D of
        'R':memSR:=W;
        'A':memSA:=W;
        'S':memSI:=W;
{        'L':memSL:=W;}
        else errorMsg(Input,'unknown directive');
      end;
    end else begin
      if length(_token)>1 then
        {Case D Of
          'M':if _token='straight' then core:=straight else
              if _token='throught' then core:=throught else
              if _token='bootstrap' then core:=bootstrap else    }
              errorMsg(Input,'unknown directive'){;
          Else
            serror(rte_UNKDMODE)
        End  }
      else begin
        M:=_token[1];
        Case D Of
          'I':SetMode(incld,M);
          'D':SetMode(dbgFLG,M);
          'O':SetMode(optFLG,M);
          'J':SetMode(jmpFLG,M);
          'V':SetMode(dnmFLG,M);
          'U':SetMode(uprFLG,M);
          '3':SetMode(ipx386,M);
          'C':Begin
                SetMode(cseFLG,M);
                If cseFLG Then uprFLG:=true;
              End;
         Else errorMsg(Input,'unknown directive');
        End;
      End;
    End;
  End;


 (* Поиск соответствия внутреннего формата для текущей лексемы в
                   таблице лексем. *)
  function look_up(S:String):RsvType;
  begin
    Look_Up:=Search(S);
  end;

  (* Проверка лексемы на зарезервированное слово *)
  Procedure IfRsv;
  Begin
    _tok:=look_up(_token);
    if _tok=_NIL then
      _token_type:=_VARIABLE
    else
     _token_type:=_COMMAND;
  End;

  Type
    tBase = ( Bin, Oct, Deg, Hex);
  Const
  xBase : Array[tBase] Of Char =  ('1','7','9','F');
  fBase : Array[tBase] Of Byte =  (2,8,10,16);
  Var
    Base:tBase;

  Function Cnv(C:Char):Byte;
  Begin
    If (C>='0') And (C<='9')Then Cnv:=Ord(C)-48 Else
    If (C>='A') And (C<='F')Then Cnv:=Ord(C)-55 Else
    ErrorMsg(Input,'illegal number');
  End;


  (* Чтение лексемы. *)
  Procedure Token;
  Begin
    If Input^.Stream Then Input^.Stream:=False Else
    Begin
      _token_type:=_UNKNOWN;
      _tok:=_NIL; (* внутреннее представление лексемы *)
      _token:='';(* внешнее представление лексемы *)
      While Map[Input^.Ch]=Blank Do ReadCh;(*пропуск пробелов*)
      If Map[Input^.Ch]=Finish Then
        _token_type:=_FINISHED
      Else
      If Map[Input^.Ch]=Spec Then Begin
        _token:=ReadCh;
        _token_type:=_DELIMITER;
      End Else
      If Map[Input^.Ch]=Cmt Then Begin
        ReadCh;
        If Input^.Ch='$' Then
          Repeat
            ReadCh;
            Directive(Input^.Ch);
          Until Input^.Ch<>',';
        While ReadCh<>_RR Do;
          token;
      End Else
      If Map[Input^.Ch]=Quote Then Begin
        ReadCh;
        _token_type:=_QUOTE;
        repeat
          if Input^.Ch=#10 then errorMsg(Input,''' expected');
          if Map[Input^.Ch]<>Quote then
            _token:=_token+ReadCh
          else begin
            ReadCh;
            If Map[Input^.Ch]=Quote then
              _token:=_token+ReadCh
            else
              exit;
          end;
        until false;
      End Else
      If Map[Input^.Ch]=Delim Then Begin
        While Map[Input^.Ch]=Delim Do _token:=_token+ReadCh;
        IfRsv;
      End Else
      If Map[Input^.Ch]=Digit Then Begin
          _number_tok:=0;
          _token_type:=_NUMBER;
          Base:=Deg;
          If Input^.CH='0' Then Begin
            ReadCh;
            Case Input^.CH Of
              'h','x': Base:=Hex;
              'd','e': Base:=Deg;
              'o': Base:=Oct;
              'b': Base:=Bin;
            Else
              If Map[Input^.CH]<>Digit Then Exit;
            End;
            If Map[Input^.CH]<>Digit Then ReadCh;
          End;
          While (Map[Input^.CH]=Digit) Or (Map[Input^.CH]=Alpha) Do Begin
            If UpCase(Input^.CH)>xBase[Base] Then ErrorMsg(Input,'invalid numer');
            _number_tok:=_number_tok*fBase[Base]+Cnv(UpCase(ReadCh));
          End;
          Str(_number_tok,_token);
      End Else
      If Map[Input^.Ch]=Alpha Then Begin
        While (Map[Input^.Ch]=Alpha) Or (Map[Input^.Ch]=Digit) Do _token:=_token+IfUpCase(ReadCh);
        IfRsv;
      End Else
        ErrorMsg(Input,'syntax error');
    End;
  End;


  procedure exec_cfg(name:string);

    procedure exec_str(p,s:string);
    begin
      if p='module'
      then
        ModuleDir:=s
      else
      if p='library'
      then
        LibraryDir:=s
      else begin
        Write(#13#10'invalid cfg parameter "',p,'"'#13#10);
        Halt;
      end;
    end;

  var
    T:TEXT;
    P,S:string;
  begin
    assign(T,name);
    {$I-}
    reset(T);
    if not boolean(ioresult) then begin
      while not eof(T) do begin
        readln(T,p);
        readln(T,s);
        exec_str(p,s);
      end;
      close(T);
    end;
  end;

begin
  exec_cfg('d2x86.cfg');
end.