home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 February
/
Chip_2000-02_cd.bin
/
zkuste
/
Delphi
/
navody
/
tt
/
objvm.exe
/
UNITS
/
ObjCodeGeneration.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-03-12
|
9KB
|
325 lines
unit ObjCodeGeneration;
interface
uses
Code,OpCodes,IntStack,NodeStack;
type TObjCodeGeneration=class
protected
fCode:TCode;
public
Cur:Integer;
Stack:TIntStack;
NodeStack:TNodeStack;
constructor Create(c:TCode);
destructor Destroy;override;
function Code:TCode;
procedure cOpCode(OpCode:Integer);
procedure cByte(a:Byte);
procedure cHalt;
procedure cAdd;
procedure cSub;
procedure cMul;
procedure cDiv;
procedure cNegate;
{ Boolean operations }
procedure cAnd;
procedure cOr;
procedure cNot;
{Comparison ops}
procedure cEqu;
procedure cNE;
procedure cG;
procedure cL;
procedure cLE;
procedure cGE;
{Value operations }
procedure cGet;
procedure cSet;
procedure cExec;
procedure cEval;
procedure cGetElem;
procedure cRoot;
{Constant operations }
procedure cStr(const a:string);
procedure cFloat(a:Extended);
procedure cInt(a:Integer);
procedure cBool(a:boolean);
{Execution flow operations }
procedure cNop;
procedure cJZ(a:Integer);
procedure cJNZ(a:Integer);
procedure cJMP(a:Integer);
procedure cJRZ(a:Integer);
procedure cDcrR;
procedure cToR;
{Moves value from return stack to data stack}
procedure cFromR;
{Drops value from reaturn stack}
procedure cRDrop;
{Structural Macros }
{<e> IF <1> ELSE <2> THEN - Like FORTH}
procedure cIF;
procedure cTHEN;
procedure cELSE;
{<e> TIMES <Action> LOOP }
procedure cTIMES;
procedure cLOOP;
{BEGIN <e> WHILE <Action> REPEAT}
procedure cBEGIN;
procedure cWHILE;
procedure cREPEAT;
{Adds Gen code to current generation}
procedure cGen(Gen:TObjCodeGeneration);
end;
implementation
function TObjCodeGeneration.Code;
begin
Result:=fCode;
end;
constructor TObjCodeGeneration.Create;
begin
fCode:=c;
Cur:=0;
Stack:=TIntStack.Create(20);
NodeStack:=TNodeSTack.Create;
end;
destructor TObjCodeGeneration.Destroy;
begin
cHalt;
Stack.Free;
NodeStack.Free;
Inherited Destroy;
end;
procedure TObjCodeGeneration.cOpCode;
begin
fCode.Int[Cur]:=OpCode;
Cur:=Cur+Sizeof(Integer);
end;
procedure TObjCodeGeneration.cHalt;
begin
cOpCode(ocHalt);
end;
procedure TObjCodeGeneration.cAdd;
begin
cOpCode(ocAdd);
end;
procedure TObjCodeGeneration.cSub;
begin
cOpCode(ocSub);
end;
procedure TObjCodeGeneration.cMul;
begin
cOpCode(ocMul);
end;
procedure TObjCodeGeneration.cDiv;
begin
cOpCode(ocDiv);
end;
procedure TObjCodeGeneration.cNegate;
begin
cOpCode(ocNegate);
end;
{ Boolean operations }
procedure TObjCodeGeneration.cAnd;
begin
cOpCode(ocAnd);
end;
procedure TObjCodeGeneration.cOr;
begin
cOpCode(ocOr);
end;
procedure TObjCodeGeneration.cNot;
begin
cOpCode(ocNot);
end;
{Comparison ops}
procedure TObjCodeGeneration.cEqu;
begin
cOpCode(ocEqu);
end;
procedure TObjCodeGeneration.cNE;
begin
cOpCode(ocNE);
end;
procedure TObjCodeGeneration.cG;
begin
cOpCode(ocG);
end;
procedure TObjCodeGeneration.cL;
begin
cOpCode(ocL);
end;
procedure TObjCodeGeneration.cLE;
begin
cOpCode(ocLE);
end;
procedure TObjCodeGeneration.cGE;
begin
cOpCode(ocGE);
end;
{Value operations }
procedure TObjCodeGeneration.cGet;
begin
cOpCode(ocGet);
end;
procedure TObjCodeGeneration.cSet;
begin
cOpCode(ocSet);
end;
procedure TObjCodeGeneration.cExec;
begin
cOpCode(ocExec);
end;
procedure TObjCodeGeneration.cEval;
begin
cOpCode(ocEval);
end;
procedure TObjCodeGeneration.cGetElem;
begin
cOpCode(ocGetElem);
end;
procedure TObjCodeGeneration.cRoot;
begin
cOpCode(ocRoot);
end;
{Constant operations }
procedure TObjCodeGeneration.cStr(const a:string);
Var i:Integer;
begin
cOpCode(ocStr);
fCode.Str[Cur]:=a;
Cur:=Cur+Length(a)+1;
end;
procedure TObjCodeGeneration.cFloat(a:Extended);
begin
cOpCode(ocFloat);
fCode.Num[Cur]:=a;
Cur:=Cur+SizeOf(a);
end;
procedure TObjCodeGeneration.cInt(a:Integer);
begin
cOpCode(ocInt);
fCode.Int[Cur]:=a;
Cur:=Cur+SizeOf(a);
end;
procedure TObjCodeGeneration.cBool(a:boolean);
begin
cOpCode(ocBool);
if a then
fCode.Int[Cur]:=-1
else
fCode.Int[Cur]:=0;
Cur:=Cur+SizeOf(a);
end;
{Execution flow operations }
procedure TObjCodeGeneration.cNop;
begin
cOpCode(ocNop);
end;
procedure TObjCodeGeneration.cJZ(a:Integer);
begin
cOpCode(ocJZ);
fCode.Int[Cur]:=a;
Cur:=Cur+SizeOf(a);
end;
procedure TObjCodeGeneration.cJNZ(a:Integer);
begin
cOpCode(ocJNZ);
fCode.Int[Cur]:=a;
Cur:=Cur+SizeOf(a);
end;
procedure TObjCodeGeneration.cJMP(a:Integer);
begin
cOpCode(ocJMP);
fCode.Int[Cur]:=a;
Cur:=Cur+SizeOf(a);
end;
procedure TObjCodeGeneration.cJRZ(a:Integer);
begin
cOpCode(ocJRZ);
fCode.Int[Cur]:=a;
Cur:=Cur+SizeOf(a);
end;
procedure TObjCodeGeneration.cDcrR;
begin
cOpCode(ocDcrR);
end;
procedure TObjCodeGeneration.cToR;
begin
cOpCode(ocToR);
end;
procedure TObjCodeGeneration.cFromR;
begin
cOpCode(ocFromR);
end;
procedure TObjCodeGeneration.cRDrop;
begin
cOpCode(ocRDrop);
end;
procedure TObjCodeGeneration.cIF;
begin
cJNZ(0);
Stack.Push(Cur-SizeOf(Integer));
end;
procedure TObjCodeGeneration.cTHEN;
begin
fCode.Int[Stack.Pop]:=Cur;
end;
procedure TObjCodeGeneration.cELSE;
Var Old:integer;
begin
Old:=Stack.Pop;
cJMP(0);
Stack.Push(Cur-SizeOf(Integer));
fCode.Int[Old]:=Cur;
end;
procedure TObjCodeGeneration.cTIMES;
begin
cToR;
Stack.Push(Cur);
cJRZ(0);
Stack.Push(Cur-Sizeof(Integer));
cDcrR;
end;
procedure TObjCodeGeneration.cLOOP;
Var a,b:Integer;
begin
a:=Stack.Pop;
b:=STack.Pop;
cJMP(b);
fCode.Int[a]:=Cur;
cRDrop;
end;
procedure TObjCodeGeneration.cBEGIN;
begin
Stack.Push(Cur);
end;
procedure TObjCodeGeneration.cWHILE;
begin
cJNZ(0);
Stack.Push(Cur-SizeOf(Integer));
end;
procedure TObjCodeGeneration.cREPEAT;
Var a,b:Integer;
begin
a:=STack.Pop;
b:=Stack.Pop;
cJMP(b);
fCode.Int[a]:=Cur;
end;
procedure TObjCodeGeneration.cByte;
begin
Code[Cur]:=a;
Cur:=Cur+1;
end;
procedure TObjCodeGeneration.cGen;
Var i:Integer;
begin
for i:=0 to Gen.Cur-1 do
cByte(Gen.Code[i]);
end;
end.