www.pudn.com > byyl.rar > Plassemb.pas


{   Pass3  :  THE PL ASSEMBLER  --  PLASSEMB.PAS   } 
unit plassemb; 
interface 
uses pcommon,plscan,plparser; 
 
 
procedure Pass3; 
 
implementation 
 
  procedure Pass3; 
    type 
        Operations = set of OperationPart; 
        OpTables = array [0..28] of OperationPart; 
        AssemblyTable = array [1..MaxLabel] of integer; 
    var 
        NoArguments, OneArgument,TwoArguments: Operations; 
        Op: OperationPart; 
        OpTable: OpTables; 
        Table: AssemblyTable; 
        OpOrd, Arg1, Arg2, Address: integer; 
 
    procedure NextInstruction; 
      begin 
          Readln(Input1, OpOrd); 
          Op := OpTable [ OpOrd ]; 
          if Op in NoArguments then {skip} 
          else 
            if Op in OneArgument then  Read(Input1, Arg1) 
            else   { Read two arguement } 
              Read(Input1, Arg1, Arg2) 
      end; 
 
    procedure Emit1(Op: OperationPart); 
      begin 
          Emit(ord(Op)); 
          Address := Address + 1 
      end; 
 
    procedure Emit2(Op: OperationPart; Arg: integer); 
      begin 
          Emit(ord(Op)); 
          Emit(Arg); 
          Address := Address + 2 
      end; 
 
    procedure Emit3(Op: OperationPart; Arg1, Arg2: integer); 
      begin 
          Emit(ord(Op)); 
          Emit(Arg1); 
          Emit(arg2); 
          Address := Address + 3 
      end; 
 
    procedure DefAddr(LabelNo: integer); 
      begin 
          Table[LabelNo] := Address; 
          NextInstruction 
      end; 
 
    procedure DefArg(LabelNo, Value: integer); 
      begin 
          Table[LabelNo] := Value; 
          NextInstruction 
      end; 
 
    procedure Arrow(Addr:integer); 
      begin 
          Emit2(Arrow2,Table[Addr]); 
          NextInstruction 
      end; 
 
    procedure Bar(Addr:integer); 
      begin 
          Emit2(Bar2,Table[Addr]); 
          NextInstruction; 
      end; 
 
    procedure ProcCall(Level,Displ:integer); 
      begin 
          Emit3(Call2,Level,Table[Displ]); 
          NextInstruction; 
      end; 
 
    procedure Proc(VarLen,Addr:integer); 
      begin 
          Emit3(Proc2,Table[VarLen],Table[Addr]); 
          NextInstruction; 
      end; 
 
    procedure Prog(VarLen,Addr:integer); 
      begin 
          Emit3(Prog2,Table[VarLen],Table[Addr]); 
          NextInstruction; 
      end; 
 
    procedure CopyInstruction; 
      begin 
          if Op in NoArguments then  Emit1(Op) 
          else 
            if Op in OneArgument then  Emit2(Op, Arg1) 
            else 
              Emit3(Op, Arg1, Arg2); 
          NextInstruction 
      end; 
 
    procedure Assemble; 
      begin 
          Address := 1; 
          NextInstruction; 
          while Op <> EndProg2 do 
            if Op = DefAddr2  then  DefAddr(Arg1) 
            else 
              if Op = DefArg2   then  DefArg(Arg1,Arg2) 
              else 
                if Op = Arrow2  then  Arrow(Arg1) 
                else 
                  if Op = Bar2   then  Bar(Arg1) 
                  else 
                    if Op = Call2    then  ProcCall(Arg1,Arg2) 
                    else 
                      if Op = Proc2 then  Proc(Arg1,Arg2) 
                      else 
                        if Op = Prog2 then Prog(Arg1,Arg2) 
                        else  CopyInstruction; 
          Emit1(EndProg2) 
      end; 
 
    procedure Initialize; 
      var 
          LabelNo: integer; 
      begin 
          NoArguments  := [ Add2, And2, Divide2, EndProc2, EndProg2, 
                            Equal2, Greater2, Less2, Minus2, Modulo2, 
                            Multiply2, Not2, Or2, Subtract2, Value2 ]; 
          OneArgument:=[ Arrow2, Assign2, Bar2, Constant2, Fi2, 
                         Read2, Write2, DefAddr2 ]; 
          TwoArguments := [ Call2, Index2, Proc2, Prog2, Variable2,DefArg2 ]; 
          for LabelNo := 1 to MaxLabel do 
              Table[LabelNo] := 0; 
          OpTable[0]:=Add2;           OpTable[1]:=And2; 
          OpTable[2]:=Arrow2;         OpTable[3]:=Assign2; 
          OpTable[4]:=Bar2;           OpTable[5]:=Call2; 
          OpTable[6]:=constant2;      OpTable[7]:=Divide2; 
          OpTable[8]:=Endproc2;        OpTable[9]:=EndProg2; 
          OpTable[10]:=Equal2;        OpTable[11]:=Fi2; 
          OpTable[12]:=Greater2;      OpTable[13]:=Index2; 
          OpTable[14]:=Less2;         OpTable[15]:=Minus2; 
          OpTable[16]:=Modulo2;       OpTable[17]:=Multiply2; 
          OpTable[18]:=Not2;          OpTable[19]:=Or2; 
          OpTable[20]:=Proc2;         OpTable[21]:=Prog2; 
          OpTable[22]:=Read2;         OpTable[23]:=Subtract2; 
          OpTable[24]:=Value2;        OpTable[25]:=Variable2; 
          OpTable[26]:=Write2;        OpTable[27]:=DefAddr2; 
          OpTable[28]:=DefArg2; 
      end; 
 
    {  Pass3 : THE PL ASSEMBLER  } 
  begin 
      Initialize; 
      Assemble; 
      Rerun; 
      Assemble 
  end; 
 
end.