PL/0语言编译程序整理实现:(7)、目标代码
来源:互联网 发布:网络机顶盒怎么刷机 编辑:程序博客网 时间:2024/05/16 03:52
unit uCode;
interface
uses
SysUtils,Classes,uSymbolType,uCodeType,uError;
type
TCodes = class
private
FError: TError;
FCode: PInstructions; //--代码表
FCodeAddress: integer;
procedure GenerateCode(AType: TInstructionType; ALevel,AAddress: integer);
public
constructor Create(pCode: PInstructions; const AError: TError = nil);
//---
procedure ListCode(AList: TStrings);
//---
procedure GenerateCode_Factor(ASign: TSymbolType);
procedure GenerateCode_Term(ASign: TSymbolType; const AIsFirst: boolean = false);
procedure GenerateCode_Condition(ASign: TSymbolType);
procedure GenerateCode_Return;
procedure GenerateCode_Odd;
procedure GenerateCode_AllocMem(ASize: integer);
procedure GenerateCode_Write;
procedure GenerateCode_WriteLn;
procedure GenerateCode_Read(ALevel,AAddress: integer);
procedure GenerateCode_Call(ALevel,AAddress: integer);
procedure GenerateCode_SetVar(ALevel,AAddress: integer);
procedure GenerateCode_GetVar(ALevel,AAddress: integer);
procedure GenerateCode_SetNum(AValue: integer);
function GenerateCode_JMP(ADestAddress: integer): integer;
procedure UpdateAddress_JMP(ASourceAddress,ADestAddress: integer);
function GenerateCode_JPC(ADestAddress: integer): integer;
procedure UpdateAddress_JPC(ASourceAddress,ADestAddress: integer);
//---
property CodeAddress: integer read FCodeAddress;
end;
implementation
uses uErrorInfo;
constructor TCodes.Create(pCode: PInstructions; const AError: TError);
begin
FCode := pCode;
FError := AError;
end;
procedure TCodes.GenerateCode(AType: TInstructionType; ALevel,AAddress:
integer);
(*
名称:目标代码生成
功能:用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行
参数:
AType:代码类型
ALevel, AAddress:代码的两个操作数
*)
//---
procedure _ReportError(const AMsg: string);
begin
if Assigned(FError) then
FError.ReportError(AMsg);
end;
begin
if FCodeAddress > high(FCode^) then
_ReportError(CNT_Error4);
//---写入目标代码
with FCode[FCodeAddress] do
begin
IType := AType;
Level := ALevel;
Address := AAddress;
end;
//---指向下一个空位
FCodeAddress := FCodeAddress + 1;
end;
procedure TCodes.ListCode(AList: TStrings);
var
i: integer;
begin
AList.Clear;
for i := 0 to FCodeAddress - 1 do
with FCode[i] do
AList.Add(format('%.3d : %s %d , %d', [i,CNT_CodeNames[IType],Level,Address]));
end;
procedure TCodes.GenerateCode_Factor(ASign: TSymbolType);
begin
if ASign = symTimes then
self.GenerateCode(opr,0,4) //--生成"乘法运算指令"
else
self.GenerateCode(opr,0,5); //--生成"除法运算指令"
end;
procedure TCodes.GenerateCode_Term(ASign: TSymbolType; const AIsFirst: boolean =
false);
begin
if AIsFirst then
begin
if ASign = symMinus then
self.GenerateCode(opr,0,1) //--如果是负号,生成"取反运算指令"; 如果是正号,不需生成指令
end
else
begin
if ASign = symPlus then
self.GenerateCode(opr,0,2) //--生成"加法运算指令"
else
self.GenerateCode(opr,0,3); //--生成"减法运算指令"
end;
end;
procedure TCodes.GenerateCode_Condition(ASign: TSymbolType);
begin
case ASign of
symEql: self.GenerateCode(opr,0,8); //--等号:生成"判等运算指令"
symNeq: self.GenerateCode(opr,0,9); //--不等号:生成"判不等运算指令"
symLss: self.GenerateCode(opr,0,10); //--小于号:生成"判小运算指令"
symGeq: self.GenerateCode(opr,0,11); //--大于等号号:生成"判不小于运算指令"
symGtr: self.GenerateCode(opr,0,12); //--大于号:生成"判大于运算指令"
symLeq: self.GenerateCode(opr,0,13); //--小于等于号:生成"判不大于运算指令"
end;
end;
procedure TCodes.GenerateCode_Return;
begin
self.GenerateCode(opr,0,0); //---生成"从子程序返回操作指令"
end;
procedure TCodes.GenerateCode_AllocMem(ASize: integer);
begin
self.GenerateCode(int,0,ASize); //---生成"分配空间指令",分配ASize个空间
end;
procedure TCodes.GenerateCode_WriteLn;
begin
self.GenerateCode(opr,0,15); //--生成"输出一个换行指令"
end;
procedure TCodes.GenerateCode_Write;
begin
self.GenerateCode(opr,0,14); //--生成"向屏幕输出指令"
end;
procedure TCodes.GenerateCode_Read(ALevel,AAddress: integer);
begin
self.GenerateCode(opr,0,16); //--生成"从键盘读入数字指令"
self.GenerateCode(sto,ALevel,AAddress); //--生成"sto指令",把读入的值存入指定变量所在的空间
end;
procedure TCodes.GenerateCode_Call(ALevel,AAddress: integer);
begin
self.GenerateCode(cal,ALevel,AAddress); //--生成"调用子过程指令"
end;
procedure TCodes.GenerateCode_Odd;
begin
self.GenerateCode(opr,0,6); //--生成"奇偶判断运算指令"
end;
procedure TCodes.GenerateCode_SetVar(ALevel,AAddress: integer);
begin
self.GenerateCode(sto,ALevel,AAddress); //--生成"更新变量内容指令"
end;
procedure TCodes.GenerateCode_SetNum(AValue: integer);
begin
self.GenerateCode(lit,0,AValue); //--生成"数值放到栈顶指令"
end;
procedure TCodes.GenerateCode_GetVar(ALevel,AAddress: integer);
begin
self.GenerateCode(lod,ALevel,AAddress); //--生成指令,把位于距离当前层level层、偏移地址为Address的变量的值放到栈顶
end;
function TCodes.GenerateCode_JMP(ADestAddress: integer): integer;
begin
Result := FCodeAddress;
self.GenerateCode(jmp,0,ADestAddress); //---生成"条件跳转指令",跳转位置为ADestAddress
end;
procedure TCodes.UpdateAddress_JMP(ASourceAddress,ADestAddress: integer);
begin
FCode[ASourceAddress].Address := ADestAddress; //---把ASourceAddress位置的跳转语句的跳转位置改成ADestAddress位置
end;
function TCodes.GenerateCode_JPC(ADestAddress: integer): integer;
begin
Result := FCodeAddress;
self.GenerateCode(jpc,0,ADestAddress); //---生成"条件跳转指令",跳转位置为ADestAddress
end;
procedure TCodes.UpdateAddress_JPC(ASourceAddress,ADestAddress: integer);
begin
UpdateAddress_JMP(ASourceAddress,ADestAddress);
end;
end.
- PL/0语言编译程序整理实现:(7)、目标代码
- PL/0语言编译程序整理实现:(6)、代码类型
- PL/0语言编译程序整理实现:(8)、代码执行
- PL/0语言编译程序整理实现:(12)、测试代码
- PL/0语言编译程序整理实现:(2)、单词类型
- PL/0语言编译程序整理实现:(3)、词法分析
- PL/0语言编译程序整理实现:(4)、对象类型
- PL/0语言编译程序整理实现:(5)、语法分析
- PL/0语言编译程序整理实现:(9)、错误信息
- PL/0语言编译程序整理实现:(10)、错误处理
- PL/0语言编译程序整理实现:(11)、测试界面
- PL/0语言编译程序整理实现:(1)、语法描述EBNF
- PL/0语言编译程序分析
- PL/0语言编译程序分析
- PL/0语言编译程序分析
- PL/0语言编译程序分析
- PL/0语言编译程序分析
- PL/0语言编译程序分析
- 下雪啦
- PL/0语言编译程序整理实现:(6)、代码类型
- 图文并茂详解VisualStudio使用技巧
- 顺序表(数据结构)
- RedHat AS 5.3 yum源配置
- PL/0语言编译程序整理实现:(7)、目标代码
- 每天是一个新的开始.加油.
- win2008建立无线共享有线网络
- PL/0语言编译程序整理实现:(8)、代码执行
- PL/0语言编译程序整理实现:(9)、错误信息
- PL/0语言编译程序整理实现:(10)、错误处理
- SQL server 临时表和表变量
- 我的第一年--程序员
- 奇文共赏