Скачиваний:
14
Добавлен:
01.05.2014
Размер:
45 Кб
Скачать
☆
(* 
 * uAsm.pas - ¬®¤г«м ЇаҐ®Ўа §®ў ­Ёп ваЁ ¤ ў asm-Є®¤
 * ver. 0.37
 * 21.05.2007 serg
 *)
unit uAsm;
interface
uses uStack, Grams, uTrList, Lex;

procedure triada_to_asm;
procedure print_all_table;
function checkUseTriad: Integer;

procedure tr_begprog;
procedure tr_endprog;
procedure write_AsmProc;
procedure selMemory(countTmpVars: Integer);

procedure tr_defl;
procedure tr_brl;
procedure tr_bf;

procedure tr_RelOp(oper: string);
procedure tr_AddOp(oper: string);
procedure tr_DivOp(oper: string);
procedure tr_mul;
procedure tr_LogOp(oper: string);
procedure tr_not;
procedure tr_neg;
procedure tr_eq;
procedure tr_wrt;
procedure tr_wrts;
procedure tr_wrtm;
procedure tr_rd;

procedure tr_ColRow(oper: string);
procedure tr_subs;
procedure tr_addr;
procedure tr_eqa;

procedure tr_ConDis(oper: string; dest: string);


procedure tr_blbeg;
procedure tr_blend;

implementation

var f_proc:text;
    f_body:text;
    f_var :text;

    gl_curTriadNum: Integer;
    gl_curTriada: tTriadData;

    labelCount: Integer; (* бзҐвзЁЄ ЈҐ­ҐаЁа㥬ле ¬Ґв®Є *)

function isVariable(s: string): boolean;
begin
  isVariable := s[1]='_';
end;
function isConstVariable(s: string): boolean;
begin
  isConstVariable := (s[1]='_') and (s[2]='2');
end;

(*=================================================================*)
(*====== Ћб­®ў­ п Їа®жҐ¤га  - ЇҐаҐў®¤ Ї®в®Є  ваЁ ¤ ў asm-Є®¤ ======*)
procedure triada_to_asm;
var 
   i:integer;
   op: string;
   nextTriada: tTriadData;
begin

  labelCount := 0;

  print_all_table; (* а бЇҐз в Ґ¬ ўбҐ в Ў«Ёжл ў д ©«л *)

  assign(f_var,'var.asm');
  rewrite(f_var);
  assign(f_proc,'proc.asm');
  rewrite(f_proc);
  assign(f_body,'body.asm');
  rewrite(f_body);

  tr_begprog;

  for gl_curTriadNum := 1 to TriadList.top do begin
     getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
     op := gl_curTriada.name;

     if (op = 'DEFL')       then tr_defl
     else if (op = 'BRL')   then tr_BRL
     else if (op = 'BF')    then tr_bf
     else if (op = 'WRT')   then tr_wrt
     else if (op = 'WRTS')  then tr_wrts
     else if (op = 'WRTM')  then tr_wrtm
     else if (op = 'RD')    then tr_rd
     else if (op = 'EQ')    then tr_eq
     else if (op = 'NEG')   then tr_neg
     else if (op = 'NOT')   then tr_not
     else if (op = 'OR')    then tr_LogOp(op)
     else if (op = 'AND')   then tr_LogOp(op)
     else if (op = 'MUL')   then tr_mul
     else if (op = 'DIV')   then tr_DivOp(op)
     else if (op = 'MOD')   then tr_DivOp(op)
     else if (op = 'ADD')   then tr_AddOp(op)
     else if (op = 'SUB')   then tr_AddOp(op)
     else if (op = 'CON')or(op = 'DIS') then
     begin 
       getTriadElemNum(TriadList, gl_curTriadNum+1, nextTriada);
       tr_ConDis(op, nextTriada.op1);
     end
     else if (op = 'LDM')   then begin (*NULL*) end 
     else if (op = 'SUBS')  then tr_subs
     else if (op = 'ADDR')  then tr_addr
     else if (op = 'EQA')   then tr_eqa
     else if (op = 'ROW')   then tr_ColRow(op)
     else if (op = 'COL')   then tr_ColRow(op)
     else if (op = 'BLBEG') then tr_blbeg  (*#*)
     else if (op = 'BLEND') then tr_blend  (*#*)
     else if (op = '>')     then tr_RelOp(op)
     else if (op = '<')     then tr_RelOp(op)
     else if (op = '>=')    then tr_RelOp(op)
     else if (op = '<=')    then tr_RelOp(op)
     else if (op = '=')     then tr_RelOp(op)
     else if (op = '<>')    then tr_RelOp(op)


     else writeln(f_body, '; Err!! ЌҐ а бЇ®§­ ­  ’аЁ ¤  ', gl_curTriada.name);
  end;

  tr_endprog;

  close(f_var);
  close(f_proc);
  close(f_body);
end;

(*==========================================================================
  ======== Џа®ўҐаЄ  Ё ­ бва®©Є  ббл«®Є ваЁ ¤ ¤агЈ ­  ¤агЈ  =================
   ў®§ўа й Ґв Є®«-ў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• ¤«п еа ­Ґ­Ёп ўаҐ¬Ґ­­ле १г«мв в®ў*)
function checkUseTriad: Integer;
(*--------------------------------------------------------------------------*)

(* Њ ЄбЁ¬ «м­®Ґ Є®«ЁзҐбвў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›•  *)
const maxCountTmpVars = 20;  
(* ђҐ «м­® ­Ґ®Ўе®¤Ё¬®Ґ Є®«ЁзҐбвў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
var realCountTmpVars: Integer;
(* ‚६Ґ­   Євг «м­®бвЁ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›•:  
 *   ¤«п Є ¦¤®© ЇҐаҐ¬Ґ­­®© ᮤҐа¦Ёв ­®¬Ґа и Ј , Є®Ј¤  ҐҐ §­ зҐ­ЁҐ бв ­Ґв ­Ґ­г¦­л¬, ...
 *   ...в.Ґ. Є®Ј¤  нв  ЇҐаҐ¬Ґ­­ п ¬.Ў. ЁбЇ®«м§®ў ­  ¤«п еа ­Ґ­Ёп ¤агЈ®Ј® Їа®¬Ґ¦-Ј® १г«мв в *)
var timeTmpVars: array[1..maxCountTmpVars] of Integer;
  
  (*---------------------------------------------------------------------*)
  (* ‚뤥«Ґ­ЁҐ бў®Ў®¤­®© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ Ї®¤ १г«мв в ⥪г饩 ... 
   *   ...ваЁ ¤л gl_curTriada б ­®¬Ґа®¬ и Ј  gl_curTriadNum              *)
  function getNumTmpVar: Integer;
  var freeNum: Integer;
  begin
    freeNum := 1;
    while timeTmpVars[freeNum] >= gl_curTriadNum do inc(freeNum);
    (* freeNum == ­®¬Ґа ЇҐаў®© ўбваҐзҐ­­®© ­Ґ Євг «м­®© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ *)
    if freeNum > realCountTmpVars then realCountTmpVars := freeNum;
    (* ўаҐ¬п  Євг «м­®бвЁ i-© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ ==  ...
     *   ...== ўаҐ¬п  Євг «м­®б⨠१г«мв в  ⥪г饩 ваЁ ¤л *)
    timeTmpVars[freeNum] := gl_curTriada.useInfo.endUse; 
    getNumTmpVar := freeNum;
  end;

  (*-------------------------------------------------------------------*)
  (*------- Ё§ў«ҐЄ Ґв Ё§ бва®ЄЁ ‘‘›‹Љ“ (в.Ґ. зЁб«® Ё§ бЄ®Ў®Є): --------
   *   getTriadLink('(14)')   -> 15  // Ґб«Ё Ґбвм ‘‘›‹ЉЂ (зЁб«® ў бЄ®ЎЄ е)
   *   getTriadLink('lalala') -> 0   // Ґб«Ё ‘‘›‹Љ€ ­Ґв  
   *)
  function getTriadLink(s: string): Integer;
  var i,code,num:integer;
      numStr: string;
  begin
    getTriadLink := 0;
    if length(s)=0 then exit;
    if s[1]='(' then begin
      numStr := '';
      i := 2;
      while (s[i]<>')') or (i<length(s)) do begin
        numStr := numStr + s[i];
        inc(i);
      end;
      Val(numStr, num, code);
      if code=0 then getTriadLink := num;
    end;
  end;(* getTriadLink *)

  (*---------------------------------------------------------------------------*)
  (* Џ®¬Ґз Ґв ваЁ ¤г б ­®¬Ґа®¬ link Є Є ЁбЇ®«м§гҐ¬го Ё ЇҐаҐ­ бва Ёў Ґв UseInfo *)
  procedure setUseTriad(link: Integer);
  var linkedTriad: tTriadData;
  begin
     getTriadElemNum(TriadList, link, linkedTriad); (* „®бв Ґ¬ ваЁ ¤г Ё§ в Ў«Ёжл *)
     (* ЏҐаҐ­ бва®Ё¬ userInfo *)
     with linkedTriad.useInfo do begin
       isUse := true;
       endUse := gl_curTriadNum; (*в.Є. gl_curTriadNum == ­®¬Ґа ⥪г饩 ваЁ ¤л, ...
       ... Є®в®а п Їа®ўҐапҐвбп ў checkUseTriad Ё ббл« Ґвбп ­  ваЁ ¤г б ­®¬Ґа®¬ link *)
     end;
     setTriadElemNum(TriadList, link, linkedTriad); (* ‚бв ўЁ¬ Ё§¬Ґ­Ґ­­го ваЁ ¤г ®Ўа в­® ў в Ў«Ёжг *)
  end;(* setUseTriad *)

var linkOp1, linkOp2: Integer;
    i: Integer;
    linkedTriad: tTriadData;
    s: string;
begin
  (* Џа®е®¤ 1 == Џ®¬ҐвЁ¬ ваЁ ¤л, ­  Є®в®алҐ Ґбвм ббл«ЄЁ б ¤агЈЁе ваЁ ¤ *)
  for gl_curTriadNum := 1 to TriadList.top do begin    (* Їа®ЎҐЈ Ґ¬ Ї® ўбҐ¬ ваЁ ¤ ¬ *)
     getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
     (* Џ®б¬®ваЁ¬: Ґбвм «Ё ‘‘›‹ЉЂ б нв®© ваЁ ¤л ­  ¤агЈЁҐ? *)
       (* €§ў«ҐЄ Ґ¬ ‘‘›‹Љ€ Ё§ ®ЇҐа ­¤®ў *)
     linkOp1 := getTriadLink(gl_curTriada.op1);  
     linkOp2 := getTriadLink(gl_curTriada.op2);
     if linkOp1<>0 then setUseTriad(linkOp1); (* Ї®¬Ґз Ґв ваЁ ¤г б ­®¬Ґа®¬ linkOp1 Є Є "€бЇ®«м§гҐ¬ п" *)
     if linkOp2<>0 then setUseTriad(linkOp2); (* Ї®¬Ґз Ґв ваЁ ¤г б ­®¬Ґа®¬ linkOp2 Є Є "€бЇ®«м§гҐ¬ п" *)
  end;

  (* ЋЎ­г«Ґ­ЁҐ ўаҐ¬Ґ­  Євг «м­®бвЁ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
  for i := 1 to maxCountTmpVars do timeTmpVars[i] := 0;
  realCountTmpVars := 0; (* Ї®Є  ‚ђ…Њ…ЌЌ›… Џ…ђ…Њ…ЌЌ›… ­Ґ ­г¦­л  *)
  
  (* Џа®е®¤ 2 == § ¬Ґ­Ё¬ ў ваЁ ¤ е ббл«ЄЁ ­  Ё¬Ґ­  ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
  for gl_curTriadNum := 1 to TriadList.top do begin    (* Їа®ЎҐЈ Ґ¬ Ї® ўбҐ¬ ваЁ ¤ ¬ *)
     getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
     (* …б«Ё ­ и १г«мв в Є®¬г-в® ­г¦Ґ­ *)
     if gl_curTriada.useInfo.isUse then        
       gl_curTriada.useInfo.numTmpVar := getNumTmpVar; (* ўл¤Ґ«Ё¬ ‚ђ…Њ…ЌЌ“ћ Џ…ђ…Њ…ЌЌ“ћ Ї®¤ १г«мв в *)
     
     (* …б«Ё ­ ¬ ­г¦­л змЁ-⮠१г«мв вл*)
     linkOp1 := getTriadLink(gl_curTriada.op1);  
     if linkOp1<>0 then begin
       getTriadElemNum(TriadList, linkOp1, linkedTriad);
       str(linkedTriad.useInfo.numTmpVar, s);
       gl_curTriada.op1 := '_tmp_'+s;
     end;
     linkOp2 := getTriadLink(gl_curTriada.op2);  
     if linkOp2<>0 then begin
       getTriadElemNum(TriadList, linkOp2, linkedTriad);
       str(linkedTriad.useInfo.numTmpVar, s);
       gl_curTriada.op2 := '_tmp_'+s;
     end;       

     setTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada); (* ўбв ўЁ¬ Ё§¬Ґ­Ґ­­го ваЁ ¤г ®Ўа в­® ў в Ў«Ёжг *)
  end;

  (* ў®§ўа вЁ¬ Є®«-ў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• ¤«п еа ­Ґ­Ёп ўаҐ¬Ґ­­ле १г«мв в®ў*)
  checkUseTriad := realCountTmpVars;
end;(* checkUseTriad *)

(*=================================================================================================*)
(*============== ѓҐ­ҐаЁа®ў ­ЁҐ asm-Є®¤  ­ з «  Їа®Ја ¬¬л ==========================================*)
procedure tr_begprog;
var countTmpVars: Integer;
begin
  writeln(f_var, '; ‘⥪  Їа®Ја ¬¬л');
  writeln(f_var, 'Stck    SEGMENT  STACK');
  writeln(f_var, '          DW 128 DUP(?)     ; Ћвў®¤Ёвбп 128 б«®ў Ї ¬пвЁ');
  writeln(f_var, 'Stck    ENDS');
  writeln(f_var, '; „ ­­лҐ Їа®Ја ¬¬л');
  writeln(f_var, 'DATA      SEGMENT');


  countTmpVars := checkUseTriad;  (* Їа®ўҐаЁ¬ Ё ­ бва®Ё¬ ббл«ЄЁ ваЁ ¤ ¤агЈ ­  ¤агЈ  *)

  (*а бЇаҐ¤Ґ«Ґ­ЁҐ Ї ¬пвЁ*)
  selMemory(countTmpVars); 

  writeln(f_proc, 'DATA      ENDS');

  writeln(f_proc, '; Љ®¤ Їа®Ја ¬¬л');
  writeln(f_proc, 'CODE      SEGMENT');
  writeln(f_proc, '          ASSUME CS:CODE, DS:DATA, SS:Stck');
  
  write_AsmProc;

  writeln(f_proc, '; ѓ®«®ў­ п Їа®жҐ¤га ');
  writeln(f_proc, 'Main       PROC  FAR');
  writeln(f_proc, '           push  DS        ;‘®еа ­Ґ­ЁҐ  ¤аҐб  ­ з «  PSP ў б⥪Ґ');
  writeln(f_proc, '           sub   AX, AX    ;¤«п Ї®б«Ґ¤го饣® ў®ббв ­®ў«Ґ­Ёп Ї®');
  writeln(f_proc, '           push  AX        ;Є®¬ ­¤Ґ ret, § ўҐаи о饩 Їа®жҐ¤гаг.');
  writeln(f_proc, '           mov   AX, DATA             ; ‡ Јаг§Є  ᥣ¬Ґ­в­®Ј®');
  writeln(f_proc, '           mov   DS, AX               ; ॣЁбва  ¤ ­­ле.');
end;(* tr_begprog *)


(*=================================================================================================*)
(*============== ѓҐ­ҐаЁа®ў ­ЁҐ asm-Є®¤  Є®­ж  Їа®Ја ¬¬л ===========================================*)
procedure tr_endprog;
begin
  writeln(f_body, '           ret                       ; ‚л室 ў DOS Ї® Є®¬ ­¤Ґ,');
  writeln(f_body, '                                     ; ­ е-бп ў 1-®¬ б«®ўҐ PSP.');
  writeln(f_body, 'Main       ENDP');
  writeln(f_body, 'CODE       ENDS');
  writeln(f_body, '          END Main');
end;(* tr_endprog *)


(*=================================================================================================*)
(*============== ђ бЇаҐ¤Ґ«Ґ­ЁҐ Ї ¬пвЁ Ї®¤ ЇҐаҐ¬Ґ­­лҐ ==============================================*)
procedure selMemory(countTmpVars: Integer);
var t: tTable;
var i: Integer;
var p: tTable;
var n1,n2,n3, e: Integer;
begin
  t := constTable;
  writeln(f_var,'     ; Љ®­бв ­вл');
  writeln(f_var,'        b_true   equ  1   ; true');
  writeln(f_var,'        b_false  equ  0   ; false');
  while t <> nil do begin
    with t^ do begin
      if col1 = 'INTEGER' then writeln(f_var,'           _',num,'  equ  ',   col2, '   ; ', id);
      if col1 = 'BOOLEAN' then writeln(f_var,'           _',num,'  equ  b_', col2, '   ; ',col1);
    end;
    t := t^.next;
  end;

  t := varTable;
  writeln(f_var,'     ; ЏҐаҐ¬Ґ­­лҐ');
  while t <> nil do begin
    with t^ do begin
      if col1 = 'INTEGER' then 
        writeln(f_var,'           _',num,'  dw  0   ; ', id,': ',col1)
      else if col1 = 'BOOLEAN' then 
        writeln(f_var,'           _',num,'  dw  0   ; ', id,': ',col1)
    end;
    t := t^.next;
  end;

  
  if countTmpVars > 0 then begin
    writeln(f_var,'     ; ЏҐаҐ¬Ґ­­лҐ ¤«п еа ­Ґ­Ёп Їа®¬Ґ¦гв®з­ле १г«мв в®ў');
    for i := 1 to countTmpVars do
      writeln(f_var,'           _tmp_',i,' dw 0');
  end;

  if strCount > 0 then begin
    writeln(f_var,'     ;  ‘ва®Є®ўлҐ Є®­бв ­вл');
    for i := 1 to strCount do
      writeln(f_var, '          _str', i, '  db "',strTable[i],'", 0DH, 0AH, "$"');
  end;

  t := varTable;
  writeln(f_var,'     ; Њ ваЁжл');
  while t <> nil do begin
    if t^.num <> 400 then
    with t^ do begin
      if (col1 <> 'INTEGER')and(col1 <> 'BOOLEAN') then begin
        p := SearchId(typeTable,col1);
        (*!!!* if p <> nil then **)
        Val(p^.col2,n1,e);
        (*!!!* if e = 0 then **)
        Val(p^.col3,n2,e);
        writeln(f_var,'           _',num,'  dw   ',n1*n2,' dup(0)   ; ', id,': ',col1)
      end;
    end;
    t := t^.next;
  end;

end;(* selMemory *)


(*=================================================================================================*)
(*============== ‡ ЇЁбм ў asm-д ©« ­Ґ®Ўе®¤Ё¬ле Їа®жҐ¤га ===========================================*)
procedure write_AsmProc;
  procedure write_PrnMsg;
  begin
    writeln(f_proc,'WriteMsg  PROC  NEAR');
    writeln(f_proc,'          push  AX');
    writeln(f_proc,'          mov   AH,9');
    writeln(f_proc,'          int   21h');
    writeln(f_proc,'          pop   AX');
    writeln(f_proc,'          ret');
    writeln(f_proc,'WriteMsg  ENDP');

    writeln(f_var, '     ; ‚бЇ®¬®Ј вҐ«м­лҐ Є®­бв ­вл');
    writeln(f_var, '          EOLN   db 0DH, 0AH, "$"', '   ; ЇҐаҐў®¤ бва®ЄЁ');
  end; (* write_PrnMsg *)

  procedure write_PrnDec;
  begin
    writeln(f_proc,'PrnDec    PROC  NEAR');
    writeln(f_proc,'          push AX');
    writeln(f_proc,'          push CX');
    writeln(f_proc,'          push DX');
    writeln(f_proc,'          push -1');
    writeln(f_proc,'          mov  CX,10');
    writeln(f_proc,'pdl1:     xor  DX,DX');
    writeln(f_proc,'          div  CX');
    writeln(f_proc,'          push DX');
    writeln(f_proc,'          or   AX,AX');
    writeln(f_proc,'          jne  pdl1');
    writeln(f_proc,'          mov  AH,2h');
    writeln(f_proc,'pdl2:     pop  DX');
    writeln(f_proc,'          or   DX,DX');
    writeln(f_proc,'          jl   pdl3');
    writeln(f_proc,'          add  DL,"0"');
    writeln(f_proc,'          int  21h');
    writeln(f_proc,'          jmp  pdl2');
    writeln(f_proc,'pdl3:     pop  DX');
    writeln(f_proc,'          pop  CX');
    writeln(f_proc,'          pop  AX');
    writeln(f_proc,'          ret');
    writeln(f_proc,'PrnDec    ENDP');

    writeln(f_var, '          MINUS  db "-","$"', '         ; ¤«п ®ваЁж вҐ«м­ле зЁбҐ«');
  end; (* write_PrnDec *)
  
  procedure write_GetDec;
  begin
    writeln(f_proc,'GetDec  PROC NEAR');
    writeln(f_proc,'        push DI');
    writeln(f_proc,'        push SI');
    writeln(f_proc,'        push BP');
    writeln(f_proc,'        push BX');
    writeln(f_proc,'        push DX');
    writeln(f_proc,'        mov  DI,0');
    writeln(f_proc,'        mov  SI,0');
    writeln(f_proc,'        mov  BP,10');
    writeln(f_proc,'        push 1');
    writeln(f_proc,'        mov  AH,08h');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        cmp  AL,"-"');
    writeln(f_proc,'        jne  gdl2');
    writeln(f_proc,'        mov  AH,2h');
    writeln(f_proc,'        mov  DL,"-"');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        pop  BX');
    writeln(f_proc,'        push -1');
    writeln(f_proc,'gdl1:   mov  AH,08h');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'gdl2:   cmp  AL,"0"');
    writeln(f_proc,'        jb   gdl3');
    writeln(f_proc,'        cmp  AL,"9"');
    writeln(f_proc,'        ja   gdl1');
    writeln(f_proc,'        mov  BL,AL');
    writeln(f_proc,'        mov  AX,DI');
    writeln(f_proc,'        mul  BP');
    writeln(f_proc,'        mov  DL,BL');
    writeln(f_proc,'        sub  DL,"0"');
    writeln(f_proc,'        mov  DH,0');
    writeln(f_proc,'        add  DX,AX');
    writeln(f_proc,'        jc   gdl1');
    writeln(f_proc,'        inc  SI');
    writeln(f_proc,'        mov  DI,DX');
    writeln(f_proc,'        mov  DL,BL');
    writeln(f_proc,'        mov  AH,02h');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        jmp  gdl1');
    writeln(f_proc,'gdl3:   cmp  SI,0');
    writeln(f_proc,'        je   gdl1');
    writeln(f_proc,'        cmp  AL,13');
    writeln(f_proc,'        je   gdl4');
    writeln(f_proc,'        cmp  AL,8');
    writeln(f_proc,'        jne  gdl1');
    writeln(f_proc,'        dec  SI');
    writeln(f_proc,'        mov  AX,DI');
    writeln(f_proc,'        mov  DX,0');
    writeln(f_proc,'        div  BP');
    writeln(f_proc,'        mov  DI,AX');
    writeln(f_proc,'        mov  DL,8');
    writeln(f_proc,'        mov  AH,2');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        mov  DL,32');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        mov  DL,8');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        jmp  gdl1');
    writeln(f_proc,'gdl4:   mov  AH,2h');
    writeln(f_proc,'        mov  DL,13');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        mov  DL,10');
    writeln(f_proc,'        int  21h');
    writeln(f_proc,'        mov  AX,DI');
    writeln(f_proc,'        pop  BX');
    writeln(f_proc,'        cmp  BX,1');
    writeln(f_proc,'        je   gdl5');
    writeln(f_proc,'        neg  AX');
    writeln(f_proc,'gdl5:   pop  DX');
    writeln(f_proc,'        pop  BX');
    writeln(f_proc,'        pop  BP');
    writeln(f_proc,'        pop  SI');
    writeln(f_proc,'        pop  DI');
    writeln(f_proc,'        ret');
    writeln(f_proc,'GetDec  ENDP');
  end; (* write_GetDec *)

  procedure write_PrnMatr;
  begin
    writeln(f_proc,';*******');
    writeln(f_proc,'; ‚лў®¤ ¬ ббЁў  ­  нЄа ­ ў ўЁ¤Ґ ¬ ваЁжл ');
    writeln(f_proc,'; BX -  ¤аҐб ¬ ббЁў ');
    writeln(f_proc,'; CX - Є®«ЁзҐбвў® бва®Є');
    writeln(f_proc,'; ‚X - Є®«ЁзҐбвў® бв®«Ўж®ў');
    writeln(f_proc,'PrnMatr   PROC  NEAR');
    writeln(f_proc,'          push DX');
    writeln(f_proc,'          mov  DX, 0');
    writeln(f_proc,'          mov  AH, 2h ');
    writeln(f_proc,'pml1:');
    writeln(f_proc,'          push CX');
    writeln(f_proc,'          mov  BP, SP');
    writeln(f_proc,'          mov  CX, [BP+2]');
    writeln(f_proc,'          mov  DI, 0');
    writeln(f_proc,'pml2:');
    writeln(f_proc,'          push  DX');
    writeln(f_proc,'          mov  SI, DX');
    writeln(f_proc,'          add  SI, DI');
    writeln(f_proc,'          add  SI, DI');
    writeln(f_proc,'          mov  DX, [BX][SI]');
    writeln(f_proc,'          add  DX, "0"');
    writeln(f_proc,'          int 21h');
    writeln(f_proc,'          pop DX');
    writeln(f_proc,'          inc  DI');
    writeln(f_proc,'          loop pml2');
    writeln(f_proc,'          push DX');
    writeln(f_proc,'          mov DX, 0Dh');
    writeln(f_proc,'          int 21h');
    writeln(f_proc,'          mov DX, 0Ah');
    writeln(f_proc,'          int 21h');
    writeln(f_proc,'          pop DX');
    writeln(f_proc,'          mov  BP, SP');
    writeln(f_proc,'          mov  CX, [BP+2]');
    writeln(f_proc,'          add  DX, CX');
    writeln(f_proc,'          add  DX, CX');
    writeln(f_proc,'          pop  CX');
    writeln(f_proc,'          loop pml1');
    writeln(f_proc,'          pop  AX');
    writeln(f_proc,'          ret');
    writeln(f_proc,'PrnMatr   ENDP');
  end; (* write_PrnMatr *)

  procedure write_ConDisMatr;
  begin
    writeln(f_proc,';*******');
    writeln(f_proc,'; CON & DIS (Љ®­ко­ЄжЁп Ё „Ё§ко­ЄжЁп ¬ ббЁў®ў)');
    writeln(f_proc,'; DI -  ¤аҐб ЇаЁҐ¬­ЁЄ ');
    writeln(f_proc,'; SI -  ¤аҐб Ёбв®з­ЁЄ 1');
    writeln(f_proc,'; BX -  ¤аҐб Ёбв®з­ЁЄ 2');
    writeln(f_proc,'; CX - Є®«ЁзҐбвў® п祥Є');
    writeln(f_proc,'; DX - вЁЇ ®ЇҐа жЁЁ (1 - DIS, 0 - CON)');
    writeln(f_proc,'ConDisMatr   PROC  NEAR');
    writeln(f_proc,'          mov  AX, DS      ; ­ бва®©Є  ES ­  DS');
    writeln(f_proc,'          mov  ES, AX');
    writeln(f_proc,'cml:');
    writeln(f_proc,'          lodsw            ; ЇҐаҐбл«Є  ®зҐаҐ¤­®Ј® б«®ў  ў AX Ё§ Ёбв®з­ЁЄ 1');
    writeln(f_proc,'');
    writeln(f_proc,'          or    DX, DX     ; ®ЇаҐ¤Ґ«Ё¬ вЁЇ ®ЇҐа жЁЁ Ё ўлЇ®«­Ё¬ ҐҐ');
    writeln(f_proc,'          je    cml_CON');
    writeln(f_proc,'          or    AX, [BX]   ; DIS');
    writeln(f_proc,'          jmp   cml_DIS');
    writeln(f_proc,'cml_CON:');
    writeln(f_proc,'          and   AX, [BX]   ; CON');
    writeln(f_proc,'cml_DIS:');
    writeln(f_proc,'');
    writeln(f_proc,'          and  AX, 01h     ; ўл¤Ґ«пҐ¬ Ґ¤Ё­б⢥­­л© ­г¦­л© ЇҐаўл© ЎЁв');
    writeln(f_proc,'          stosw            ; १г«мв в - Є« ¤Ґ¬ ў ЇаЁҐ¬­ЁЄ');
    writeln(f_proc,'          add  BX, 2       ; б¤ўЁЈ Є б«Ґ¤го饩 п祩ЄҐ Ёбв®з­ЁЄ 2');
    writeln(f_proc,'          loop cml         ; жЁЄ«, Ї®Є  ­Ґ Їа®и«Ё ўбҐ п祩ЄЁ');
    writeln(f_proc,'          ret');
    writeln(f_proc,'ConDisMatr ENDP');
  end; (* write_ConDisMatr *)

var fl_write_PrnDec: Boolean; (* == Ўл«л «Ё § ЇЁб ­  ў asm-Є®¤ asm-дг­ЄжЁп PrnDec *)
var fl_write_PrnMsg: Boolean; (* == Ўл«л «Ё § ЇЁб ­  ў asm-Є®¤ asm-дг­ЄжЁп PrnMsg *)
var fl_write_PrnMatr: Boolean;(* == Ўл«л «Ё § ЇЁб ­  ў asm-Є®¤ asm-дг­ЄжЁп PrnMatr*)
var fl_write_GetDec: Boolean; (* == Ўл«л «Ё § ЇЁб ­  ў asm-Є®¤ asm-дг­ЄжЁп GetDec *)
var fl_write_ConDisMatr: Boolean; (* == Ўл«л «Ё § ЇЁб ­  ў asm-Є®¤ asm-дг­ЄжЁп ConDisMatr *)

    op: String;
begin
  fl_write_PrnDec := false;  
  fl_write_PrnMsg := false;
  fl_write_PrnMatr:= false;
  fl_write_GetDec := false;
  fl_write_ConDisMatr := false;

  for gl_curTriadNum := 1 to TriadList.top do begin
     getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
     op := gl_curTriada.name;

    if (op = 'WRT')   then begin
         if not fl_write_PrnMsg then begin 
            write_PrnMsg;
            fl_write_PrnMsg:= true;
         end;
         if not fl_write_PrnDec then begin 
            write_PrnDec;
            fl_write_PrnDec:= true;
         end;
     end
     else if (op = 'WRTS')  then begin
         if not fl_write_PrnMsg then begin 
            write_PrnMsg;
            fl_write_PrnMsg:= true;
         end;
     end
     else if (op = 'WRTM')  then begin
         if not fl_write_PrnMatr then begin 
            write_PrnMatr;
            fl_write_PrnMatr:= true;
         end;
     end
     else if (op = 'CON')or(op = 'DIS')  then begin
         if not fl_write_ConDisMatr then begin 
            write_ConDisMatr;
            fl_write_ConDisMatr:= true;
         end;
     end
     else if (op = 'RD')    then begin
         if not fl_write_GetDec then begin 
            write_GetDec;
            fl_write_GetDec:= true;
         end;
     end
  end;
end;


(*=== DEFL - ®ЇаҐ¤Ґ«Ґ­ЁҐ ¬ҐвЄЁ ====================================================================*)
procedure tr_defl;
begin
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  gl_curTriada.op1, ')');
  writeln(f_body, '     lab', gl_curTriada.op1, ':');
end;

(*=== BRL - ЎҐ§гб«®ў­л© ЇҐаҐе®¤ ­  ¬ҐвЄг ==========================================================*)
procedure tr_brl;
begin
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  gl_curTriada.op1, ')');
  writeln(f_body, '           jmp lab', gl_curTriada.op1);
end;

(*=== BF - гб«®ў­л© ЇҐаҐе®¤ ­  ¬ҐвЄг ==============================================================*)
procedure tr_bf;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* if op1 then goto op2 *)

  if (op1='true') or (op1='false') then op1:='b_'+op1;


  writeln(f_body, '           mov AX, ',op1);
  writeln(f_body, '           cmp AX, 0');

(*    ђ ­миҐ Ўл«® в Є:
 *      writeln(f_body, '           je  ', op2);
 *    Ћ¤­ Є® Ґб«Ё ¬ҐвЄ  op2 ¤ «миҐ +/- 128, в® ЇҐаҐ©вЁ ­  ­ҐҐ ®ЇҐа в®а®¬ гб«®ў­®Ј® ЇҐаҐе®¤  ­Ґў®§¬®¦­®.
 *    Џ®н⮬г ⥯Ґам ­  ¬ҐвЄг op2 ЇҐаҐе®¤Ё¬ б Ї®¬®ймо jmp
 *)

  writeln(f_body, '           jne _l',labelCount); 
  writeln(f_body, '           jmp lab', op2);
  writeln(f_body,'  _l',labelCount,':');
  inc(labelCount);

  if (gl_curTriada.useInfo.isUse) then 
    (* ! ! ! Error - Ї®ЇлвЄ  б®еа ­Ёвм १г«мв в ®ЇҐа жЁЁ BF ў® ўаҐ¬Ґ­­го ЇҐаҐ¬Ґ­­го *)
    writeln(f_body, '            ; ! ! ! Error - Ї®ЇлвЄ  б®еа ­Ёвм १г«мв в '+
                    '®ЇҐа жЁЁ BF ў® ўаҐ¬Ґ­­го ЇҐаҐ¬Ґ­­го ', op2);
end;

(*=== EQA - ЇаЁбў Ёў ­ЁҐ Ї®  ¤аҐбг ================================================================*)
procedure tr_eqa;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* [op2] := op1, Ј¤Ґ op2 -  ¤аҐб п祩ЄЁ*)

  if (op1='true') or (op1='false') then op1:='b_'+op1;

  writeln(f_body, '           mov      BX, ', op2);
  writeln(f_body, '           mov      AX, ', op1);
  writeln(f_body, '           mov      [BX], AX');
  (* end; *)


  if (gl_curTriada.useInfo.isUse) then 
    (* ! ! ! Error - Ї®ЇлвЄ  б®еа ­Ёвм १г«мв в ®ЇҐа жЁЁ ЇаЁбў Ёў ­Ёп ў® ўаҐ¬Ґ­­го ЇҐаҐ¬Ґ­­го *)
    writeln(f_body, '            ; ! ! ! Error - Ї®ЇлвЄ  б®еа ­Ёвм १г«мв в '+
                    '®ЇҐа жЁЁ ЇаЁбў Ёў ­Ёп ў® ўаҐ¬Ґ­­го ЇҐаҐ¬Ґ­­го ', op2);
    (* writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX'); *)
end;


(*=== EQ - ЇаЁбў Ёў ­ЁҐ ===========================================================================*)
procedure tr_eq;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* op2 := op1 *)
  if not isVariable(op2) then begin 
    (* ! ! ! Error - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ­ЁЁ б«Ґў  - ЌҐЏҐаҐ¬Ґ­­ п *)
    writeln(f_body, '            ; ! ! ! Error - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ­ЁЁ б«Ґў  - ЌҐЏҐаҐ¬Ґ­­ п ', op2);
    exit;
  end;
 
  (* §¤Ґбм isVariable(op2) *)
  if isConstVariable(op2) then begin 
    (* ! ! ! Warning - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ­ЁЁ б«Ґў  - Љ®­бв ­в­ п ЏҐаҐ¬Ґ­­ п *)
    writeln(f_body, '            ; ! ! ! Warning - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ­ЁЁ б«Ґў  - Љ®­бв ­в­ п ЏҐаҐ¬Ґ­­ п', op2);
    exit;
  end; 

  if (op1='true') or (op1='false') then op1:='b_'+op1;

  (* FixMe 08.05.2007 serg*)
  (* гв®з­Ёвм ЇаЁаЁбў®Ґ­Ёп вЁЇ  <k:=1> - ¬.Ў. ¬®¦­® <mov _402, 1> *)
  (* if isVariable(op1) then begin  *)
  writeln(f_body, '           mov      AX, ', op1);
  writeln(f_body, '           mov     ', op2 ,', AX');
  (* end; *)


  if (gl_curTriada.useInfo.isUse) then 
    (* ! ! ! Error - Ї®ЇлвЄ  б®еа ­Ёвм १г«мв в ®ЇҐа жЁЁ ЇаЁбў Ёў ­Ёп ў® ўаҐ¬Ґ­­го ЇҐаҐ¬Ґ­­го *)
    writeln(f_body, '            ; ! ! ! Error - Ї®ЇлвЄ  б®еа ­Ёвм १г«мв в '+
                    '®ЇҐа жЁЁ ЇаЁбў Ёў ­Ёп ў® ўаҐ¬Ґ­­го ЇҐаҐ¬Ґ­­го ', op2);
    (* writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX'); *)
end;

(*=== WRT - ўлў®¤ §­ зҐ­Ёп ­  нЄа ­ ===============================================================*)
procedure tr_wrt;
var op1: string;
begin
  op1 := gl_curTriada.op1;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ')');

(* FixMe ¤®ЇЁб вм ¤«п <WRT, true> *)

  if (op1='true') or (op1='false') then op1:='b_'+op1;


  writeln(f_body,'           mov  AX, ',  op1);
  writeln(f_body,'           cmp  AX, 0');
  writeln(f_body,'           jge  _l', labelCount);
  writeln(f_body,'           neg  AX');
  writeln(f_body,'           mov  DX, OFFSET MINUS');
  writeln(f_body,'           call WriteMsg');
  writeln(f_body,'  _l',labelCount,':    call PrnDec');
  writeln(f_body,'           mov  DX, OFFSET EOLN');
  writeln(f_body,'           call WriteMsg');
  inc(labelCount);
end;

(*=== WRTM - ўлў®¤ ¬ ваЁжл ­  нЄа ­ ===============================================================*)
procedure tr_wrtm;
var op1: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowCount,colCount,resultNum, op2Num, e: Integer;
var typeName, resultStr, matrNumberStr: string;
var matrNumber: Integer;
begin
  op1 := gl_curTriada.op1;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ')');
 (* WRTM op1 *)

 (*Find variable ==> type ==> bounds*)
   p := varTable;
   matrNumberStr := Copy(op1,2,3);
   Val(matrNumberStr,matrNumber,e);
   while p <> nil do begin
     if p^.num = matrNumber then begin
       break
     end;
     p := p^.next
   end;

   if (p=nil) then begin
     writeln(f_body, '         ; Matrix not found in varTable');
     exit;
   end;

   typeName := p^.col1;

   p := SearchId(typeTable,typeName);
   if (p=nil) then begin
     writeln(f_body, '         ; Type of Matrix not found in TypeTable');
     exit;
   end;
   (*!!!* if e = 0 then **)
   Val(p^.col2, colCount,e);
   Val(p^.col3, rowCount,e);

  writeln(f_body,'           mov  BX, OFFSET ',op1);
  writeln(f_body,'           mov  CX, ',p^.col2,'; col count');
  writeln(f_body,'           mov  DX, ',p^.col3,'; row count');
  writeln(f_body,'           call PrnMatr');

end;


(*=== WRTS - ўлў®¤ бва®ЄЁ ­  нЄа ­ ===============================================================*)
procedure tr_wrts;
var op1: string;
begin
  op1 := gl_curTriada.op1;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ')');

  writeln(f_body,'           mov  DX, OFFSET _str',op1);
  writeln(f_body,'           call WriteMsg');
end;

(*=================================================================================================*)
procedure tr_rd;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ')');

  writeln(f_body, '           call     GetDec');
  writeln(f_body, '           mov      ', op1,',  AX');
end;


(*=================================================================================================*)
procedure tr_neg;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ')');

 (* - op1*)

  writeln(f_body, '           mov      AX, ', op1);
  writeln(f_body, '           neg      AX');

  if (gl_curTriada.useInfo.isUse) then 
    writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;

(*=================================================================================================*)
procedure tr_not;
var op1: string;
begin
  op1 := gl_curTriada.op1;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ')');

 (* not op1*)

  if (op1='true') or (op1='false') then op1:='b_'+op1;
 
  writeln(f_body, '           mov      AX, ', op1);
  writeln(f_body, '           not      AX');
  writeln(f_body, '           and      AX, 01h');

  if (gl_curTriada.useInfo.isUse) then 
    writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;

(*=== AddOp in [ADD, SUB] - ®ЇҐа жЁЁ ‘«®¦Ґ­ЁҐ Ё ‚лзЁв ­ЁҐ =========================================*)
procedure tr_AddOp(oper: string);
var op1,op2: string;
    labelNum1, labelNum2: Integer;
    operStr: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');
  
 (* op2 @ op1, Ј¤Ґ @ in [+, -] *)

       if (oper = 'ADD')     then operStr := 'add'
  else if (oper = 'SUB')     then operStr := 'sub'
  else operStr := '!!! Err';
 
  labelNum1 := labelCount; inc(labelCount);
  labelNum2 := labelCount; inc(labelCount);
  
  writeln(f_body, '           mov      AX, ', op2);
  writeln(f_body, '           ',operStr,'      AX, ', op1);

  if (gl_curTriada.useInfo.isUse) then 
    writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;

(*=== LogOp in [AND, OR] - «®ЈЁзҐбЄЁҐ ®ЇҐа жЁЁ €, €‹€ =============================================*)
procedure tr_LogOp(oper: string);
var op1,op2: string;
    labelNum1, labelNum2: Integer;
    operStr: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');
 (* op2 @ op1, Ј¤Ґ @ in [or, and] *)

  if (op1='true') or (op1='false') then op1:='b_'+op1;
  if (op2='true') or (op2='false') then op2:='b_'+op2;


       if (oper = 'AND') then operStr := 'je '
  else if (oper = 'OR')  then operStr := 'jne'
  else operStr := '!!! Err';


  labelNum1 := labelCount; inc(labelCount);
  labelNum2 := labelCount; inc(labelCount);
  
  writeln(f_body, '           mov      AX, ', op2);
  writeln(f_body, '           cmp      AX, 0');
  writeln(f_body, '           ',operStr ,'      _l', labelNum1);
  writeln(f_body, '           mov      AX, ', op1);
  writeln(f_body, '           cmp      AX, 0');
  writeln(f_body, '           ',operStr ,'      _l', labelNum1);

  if (oper = 'AND') then 
    writeln(f_body, '           mov      AX, 1  ; true')
  else if (oper = 'OR') then 
    writeln(f_body, '           mov      AX, 0  ; false');

  writeln(f_body, '           jmp      _l', labelNum2);
  writeln(f_body,'     _l',labelNum1,':');

  if (oper = 'AND') then 
    writeln(f_body, '           mov      AX, 0  ; false')
  else if (oper = 'OR') then 
    writeln(f_body, '           mov      AX, 1  ; true');

  writeln(f_body,'     _l',labelNum2,':');

  if (gl_curTriada.useInfo.isUse) then 
    writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;


(*=== RelOp - «®ЈЁзҐбЄЁҐ ®ЇҐа жЁЁ ба ў­Ґ­Ёп =======================================================*)
procedure tr_RelOp(oper: string);
var op1,op2: string;
    labelNum1, labelNum2: Integer;
    operStr: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');
  
 (* op2 @ op1, Ј¤Ґ @ in [>, <, >=, <=, =, <>] *)

       if (oper = '>')     then operStr := 'jg '
  else if (oper = '<')     then operStr := 'jl '
  else if (oper = '>=')    then operStr := 'jge'
  else if (oper = '<=')    then operStr := 'jle'
  else if (oper = '=')     then operStr := 'je '
  else if (oper = '<>')    then operStr := 'jne'
  else operStr := '!!! Err';

  labelNum1 := labelCount; inc(labelCount);
  labelNum2 := labelCount; inc(labelCount);
  
  writeln(f_body, '           mov      AX, ', op2);
  writeln(f_body, '           cmp      AX, ', op1);
  writeln(f_body, '           ',operStr ,'      _l', labelNum1);
  writeln(f_body, '           mov      AX, 0  ; false');
  writeln(f_body, '           jmp      _l', labelNum2);
  writeln(f_body,'     _l',labelNum1,':');
  writeln(f_body, '           mov      AX, 1  ; true');
  writeln(f_body,'     _l',labelNum2,':');

  if (gl_curTriada.useInfo.isUse) then 
    writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;

(*=================================================================================================*)
procedure tr_mul;
var op1,op2: string;
    operand1: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');
 (* op2 * op1*)

  writeln(f_body, '           mov      AX, ', op2);

  if isVariable(op1) and not isConstVariable(op1) then begin 
    operand1 := op1; (* - в Є ¬®¦­® в®«мЄ® ¤«п Ќ бв®пйЁе ЇҐаҐ¬Ґ­­ле (~ _401) *)
  end else begin 
    writeln(f_body, '           mov      BX, ', op1);
    operand1 := 'BX';(* - Є®­бв ­вл Ё Є®­бв ­в­лҐ ЇҐаҐ¬Ґ­­лҐ - зҐаҐ§ ॣЁбва *)
  end;

  writeln(f_body, '           imul     ', operand1);

  (* ђҐ§г«мв в ў DX:AX, ­® ЎҐаҐ¬ в®«мЄ® ¬« ¤иго з бвм - Ё§ AX *)
  if (gl_curTriada.useInfo.isUse) then 
    writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;

(*=================================================================================================*)
procedure tr_DivOp(oper: string);
var op1,op2: string;
    operand1: string;
    resultStr: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* op2 @ op1, Ј¤Ґ @ in [div, mod] *)

  writeln(f_body, '           mov      AX, ', op2, '  ;  б«®ў®-¤Ґ«Ё¬®Ґ - ў AX');
  writeln(f_body, '           cwd             ;  а биЁаЁвм ¤Ґ«Ё¬®Ґ ў DX' );

  if isVariable(op1) and not isConstVariable(op1) then begin 
    operand1 := op1; (* - в Є ¬®¦­® в®«мЄ® ¤«п Ќ бв®пйЁе ЇҐаҐ¬Ґ­­ле (~ _401) *)
  end else begin 
    writeln(f_body, '           mov      BX, ', op1, '  ;  б«®ў®-¤Ґ«ЁвҐ«м - ў BX');
    operand1 := 'BX';  	(* - Є®­бв ­вл Ё Є®­бв ­в­лҐ ЇҐаҐ¬Ґ­­лҐ - зҐаҐ§ ॣЁбва *)
  end;

  writeln(f_body, '           idiv      ', operand1,'  ;  ®бв в®Є:з бв­®Ґ ў DX:AX');

  if (gl_curTriada.useInfo.isUse) then begin
     if (oper = 'DIV')      then resultStr := 'AX'
     else if (oper = 'MOD') then resultStr := 'DX';
     writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', ',resultStr);
  end;
end;

(*=================================================================================================*)
procedure tr_ConDis(oper: string; dest: string);
var op1,op2: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowCount,colCount, e: Integer;
var typeName, matrNumberStr: string;
var matrNumber: Integer;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

  (* dest := op1 @ op2, @ in [DIS, CON]*)  

 (*Find variable ==> type ==> bounds*)
   p := varTable;
   matrNumberStr := Copy(op1,2,3);
   Val(matrNumberStr,matrNumber,e);
   while p <> nil do begin
     if p^.num = matrNumber then begin
       break
     end;
     p := p^.next
   end;

   if (p=nil) then begin
     writeln(f_body, '         ; Matrix not found in varTable');
     exit;
   end;

   typeName := p^.col1;

   p := SearchId(typeTable,typeName);
   if (p=nil) then begin
     writeln(f_body, '         ; Type of Matrix not found in TypeTable');
     exit;
   end;
   (*!!!* if e = 0 then **)
   Val(p^.col2, colCount,e);
   Val(p^.col3, rowCount,e);


  writeln(f_body, '           mov  DI, OFFSET ', dest,' ; ЇаЁҐ¬­ЁЄ');
  writeln(f_body, '           mov  SI, OFFSET ', op1, ' ; Ёбв®з­ЁЄ1');
  writeln(f_body, '           mov  BX, OFFSET ', op2, ' ; Ёбв®з­ЁЄ2');
  writeln(f_body, '           mov  CX, ',colCount*rowCount, ' ; зЁб«® п祥Є');

  if (oper = 'CON') then
    writeln(f_body, '           mov  DX, 0 ; вЁЇ ®ЇҐа жЁЁ - CON')
  else 
    writeln(f_body, '           mov  DX, 1 ; вЁЇ ®ЇҐа жЁЁ - DIS');
  writeln(f_body, '           call ConDisMatr');
end;

(*=================================================================================================*)
procedure tr_subs;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ;  (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* SUBS op1 op2 == op1[op2]   - ᮤҐа¦Ё¬®Ґ п祩ЄЁ*)

  writeln(f_body, '           mov      BX, ', op2);
  writeln(f_body, '           add      BX, ', op2); (* в.Ґ. BX*2, в.Є. б«®ў®,   ­Ґ Ў ©в*)
  writeln(f_body, '           mov      AX, ',op1,'[BX]');
  if (gl_curTriada.useInfo.isUse) then begin
     writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
  end;
end;

(*=================================================================================================*)
procedure tr_addr;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* SUBS op1 op2 == addr(op1[op2]) -  ¤аҐб п祩ЄЁ*)

  writeln(f_body, '           mov      AX, offset ', op1);
  writeln(f_body, '           add      AX, ', op2);
  writeln(f_body, '           add      AX, ', op2); (* в.Ґ. AX*2, в.Є. б«®ў®,   ­Ґ Ў ©в*)

  if (gl_curTriada.useInfo.isUse) then begin
     writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
  end;

end;

(*=================================================================================================*)
procedure tr_ColRow(oper: string);
var op1,op2: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowLength,resultNum, op2Num, e: Integer;
var typeName, matrNumberStr: string;
var matrNumber: Integer;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2;
  writeln(f_body, '         ; (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');

 (* @ op1 op2 , Ј¤Ґ @ in [COL, ROW] *)

  if (gl_curTriada.useInfo.isUse) then begin
     if (oper = 'COL')      then begin 
       writeln(f_body, '           mov      AX, ', op2);
       writeln(f_body, '           dec      AX');  (* (k)-© бв®«ЎҐж => ᬥ饭ЁҐ (k-1) *)
       writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
     end else if (oper = 'ROW') then begin

       (*Find variable ==> type ==> bounds*)
       p := varTable;
       matrNumberStr := Copy(op1,2,3);
       Val(matrNumberStr,matrNumber,e);
       while p <> nil do begin
         if p^.num = matrNumber then begin
           break
         end;
         p := p^.next
       end;

       if (p=nil) then begin
         writeln(f_body, '         ; Matrix not found in varTable');
         exit;
       end;

       typeName := p^.col1;

       p := SearchId(typeTable,typeName);
       if (p=nil) then begin
         writeln(f_body, '         ; Type of Matrix not found in TypeTable');
         exit;
       end;
       (*!!!* if e = 0 then **)
       Val(p^.col3, rowLength,e);

       resultNum := (op2Num-1)*rowLength;

       writeln(f_body, '           mov      AX, ', op2);
       writeln(f_body, '           dec      AX');  (* (k)-п бва®Є  => ᬥ饭ЁҐ (k-1)*rowLength *)
       writeln(f_body, '           mov      BX, ', rowLength);
       writeln(f_body, '           imul     BX');
  (* ђҐ§г«мв в ў DX:AX, ­® ЎҐаҐ¬ в®«мЄ® ¬« ¤иго з бвм - Ё§ AX *)
       writeln(f_body, '           mov  _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
     end;
  end;
end;

(*=================================================================================================*)
(* ‡ Ј«гиЄ  *)
procedure tr_col;
var op1,op2: string;
begin
  op1 := gl_curTriada.op1;
  op2 := gl_curTriada.op2; 
  writeln(f_body, '         ; ‡ Ј«гиЄ  : (', gl_curTriada.name, ', ',  op1, ', ', op2, ')');
end;

(*=================================================================================================*)
(* ‡ Ј«гиЄ  *)
procedure tr_blbeg;
begin
  writeln(f_body, '         ; ‡ Ј«гиЄ  : (', gl_curTriada.name, ')');
end;

(*=================================================================================================*)
(* ‡ Ј«гиЄ  *)
procedure tr_blend;
begin
  writeln(f_body, '         ; ‡ Ј«гиЄ  : (', gl_curTriada.name,')');
end;


(*=================================================================================================*)
procedure print_all_table;
var f: Text;
    i: integer;
const fname = 'tables.txt';

  procedure print_table(table: tTable);
  var t: tTable;
  begin
    t := table;
    writeln(f, 'num':10, 'id':10, 'col1':10, 'col2':10, 'col3':10, 'col4':10);
    while t <> nil do begin
      with t^ do writeln(f, num:10,  id:10, col1:10, col2:10, col3:10, col4:10);
      t := t^.next;
    end;
  end;(*print_table*)

begin
  assign(f, fname);
  rewrite(f);
  writeln(f,'typeTable');
  print_table(typeTable);
  writeln(f,'constTable');
  print_table(constTable);
  writeln(f,'varTable');
  print_table(varTable);
  writeln(f,'labelTable');
  print_table(labelTable);

(*  
  writeln(f,'matrTable');
  print_table(matrTable);
  writeln(f,'hTable');
  print_table(hTable);
*)
  writeln(f,'strTable');
  writeln(f,'num':10,'str':10);
  for i := 1 to strCount do writeln(f, i:10,'     <',strTable[i],'>');
   
  close(f);
end;(*print_all_table*)
(*=================================================================================================*)

end .
Соседние файлы в папке src