[Delphi] Własny kompilator - zmienne

shoock12

Użytkownik
Dołączył
Styczeń 24, 2009
Posty
123
Otóż piszę kompilator. Robię to tak, że podczepiam kod źródłowy pod plik .exe i on go intepretuje. Kod źródłowy tego oryginalnego exe-ka:
Kod:
program stub;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  Windows;

var
  kod : TStrings;
  XXX : string;
  i : integer;
  tmp : Tstrings;
  obecne : string;
  zmienne : TStrings;

function Split(input:string;s:integer):string;

var

l : integer;

d : integer;

finish :string;

begin

l :=0;

d :=0;

while (d <= s) and (length(input) >= l) do

begin

l := l + 1;

if d = s then

finish := FINISH + copy(input,l,1);

if copy(input,l,1) = '|' then

d := d + 1;

end;

while Pos('|', finish) > 0 do

delete(finish, Pos('|', finish), 1);

split := finish;

end;



//



function LoadFromExe(FName: string): string;

var

F : file of Byte;

i : Integer;

begin

Result := '';

AssignFile(F, FName);

FileMode := fmOpenRead;

Reset(F);

try

Seek(F, FileSize(F) - SizeOf(i));

BlockRead(F, i, SizeOf(i));

if (i < SizeOf(i)) or (i > FileSize(f)) then Exit;

Seek(F, FileSize(F) - i);

SetLength(Result, i - SizeOf(i));

BlockRead(F, Result[1], Length(Result));

XXX := Result;

Split(XXX,0); // Odpowiada Edit1 z konfiguratora

Split(XXX,1); // Odpowiada Edit2 z konfiguratora

//Ile editów, tyle razy powielamy Split...

finally

CloseFile(F);

end;

end;

function zmienna(text:string; zmienna:TStrings):string;
var
e:integer;
t:TStrings;
gotowe:string;
z:integer;
begin
t:=TStringList.Create;
t.Clear;
gotowe:='';

  for e := 0 to zmienna.Count-1 do
  begin
    ExtractStrings([','],[','],PChar(zmienna[e]),t);
    if(t[0]=text) then begin
      gotowe:=t[1];
      z:=1;
      end;
      end;

if(z=1) then
result:=gotowe
else
result:=text;

end;

begin
kod:=TStringList.Create;
tmp:=TStringList.Create;
zmienne:=TStringList.Create;
LoadFromExe(ParamStr(0));
kod.Text:=Split(XXX,0);

for i:=0 to kod.Count-1 do
begin

  obecne:=kod[i];

  if Pos('printf', obecne) > 0 then
  begin
    delete(obecne,1,7);
    WriteLn(zmienna(obecne, zmienne));
  end;

  if(obecne='pause') then
  begin
    ReadLn;
  end;

  if Pos('MessageBox', obecne) > 0 then
  begin
    delete(obecne,1, 11);
    ExtractStrings([','],[','],pchar(obecne),tmp);
    MessageBox(0, PChar(zmienna(tmp[0], zmienne)) , PChar(zmienna(tmp[1], zmienne)), MB_OK);
  end;

  if Pos('set', obecne) > 0 then
  begin
    tmp.Clear;
    delete(obecne,1,4);
    ExtractStrings([','],[','],pchar(obecne),tmp);
    zmienne.Add(tmp[0] + ',' + tmp[1]);
  end;

  if(obecne='a') then
    WriteLn(zmienne.text);

end;

end.

Kompilatora:
Kod:
program sc;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  Windows;

procedure SaveToExe(FName, Str: string);

var

F : File of Byte;

I : Integer;

begin

AssignFile(F, FName);

Reset(F);

try

Seek(F, FileSize(F) - SizeOf(I));

BlockRead(F, I, SizeOf(I));

if (I < SizeOf(I)) or (I > FileSize(F)) then I := 0;

Seek(F, FileSize(F) - I);

Truncate(F);

BlockWrite(F, Str[1], Length(Str));

I := Length(Str) + SizeOf(I);

BlockWrite(F, I, SizeOf(I));

finally

CloseFile(F);

end;

end;

var
  zrodla:TStrings;

begin

if (ParamStr(1)='') or (ParamStr(2)='') or (ParamStr(1)='/h')  or (ParamStr(1)='/help') then
begin
  WriteLn('Uzycie: sc.exe <plik zrodlowy> <plik wynikowy>');
end else
begin
  WriteLn('Trwa kompilowanie...');
  zrodla:=TStringList.Create;
  zrodla.LoadFromFile(ParamStr(1));
  copyfile('stub.exe', PChar(ParamStr(2)), False);
  SaveToExe(ParamStr(2),zrodla.Text);
  WriteLn('Gotowe!');
end;

end.


Ale mam taki błąd piszę w moim języku skryptowym np.
Kod:
set $z1,text ze zmiennej 1
set $z2,text ze zmiennej 2
set $z3,text ze zmiennej 3
printf $z1
printf $z2
printf $z3
printf $z1

Ale wyświetla tak:
text ze zmiennej 1
$z2
$z3
text ze zmiennej 1

Czyli jakby akceptuje tylko jedną zmienną. Nie wiem co jest źle. Proszę o pomoc.
 
Do góry Bottom