📄 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -