(* PARSER.PAS: Please read the bottom of DWIN.PAS for Copyright details.   *)

function parseDefFile(inFile: PChar): PDef;
var
 dfline, sourceName: string;
 source: text;
 scrapAct: PAct;
 scrapCmd, DCmd: PDef;
 SChar: char; i: word;
begin
 {First, extract the header}
 sourceName := strPas(infile);
 assign(source, sourceName);
 reset(source);
 new(scrapAct);
 scrapAct^.asmLn := nil;
 DAct := scrapAct;
 readln(source, dfline);
 while dfline <> '/.' do
 begin
  new(DAct^.nextAct);
  DAct := DAct^.nextAct;
  DAct^.nextAct := nil;
  getMem(DAct^.asmLn, length(dfline)+1);
  strPCopy(DAct^.asmLn, dfline);
  readln(source, dfline);
 end;
 THead := scrapAct^.nextAct;
 dispose(scrapAct);

 {Now you start looking at the commands themselves}
 new(scrapCmd);
 scrapCmd^.command := '';
 scrapCmd^.nextDef := nil;
 scrapCmd^.actions :=  nil;
 DCmd := scrapCmd;
 dfline[1]  :=  ' ';
 while dfline <> '/.' do
 begin
  readln(source, dfline);
  if verbose = 1 then writeln('Defing '+dfline);
  i := 1; while dfline[i] = ' ' do i := i+1;
  if dfline[i] <> '#' then
  begin
   if dfline = '/.' then break;
   SChar := dfline[1];
   new(DCmd^.nextDef);
   DCmd := DCmd^.nextDef;
   DCmd^.nextDef := nil;
   getMem(DCmd^.command, length(dfline)+1);
   strPCopy(DCmd^.command, dfline);
   new(DCmd^.actions);
   DAct := DCmd^.actions;
   DAct^.nextAct := nil;
   readln(source, dfline);
   while dfline[1] <> SChar do
   begin
    new(DAct^.nextAct);
    DAct := DAct^.nextAct;
    DAct^.nextAct := nil;
    getMem(DAct^.asmLn, length(dfline)+1);
    strPCopy(DAct^.asmLn, dfline);
    readln(source, dfline);
   end;
  end;
 end;
 parseDefFile := scrapCmd^.nextDef;
 {And you are finished?}
end;

procedure destroyAct(inAct: PAct);
var tempAct, nextAct: PAct;
begin
 tempAct := inAct;
 while tempAct <> nil do
 begin
  nextAct := tempAct^.nextAct;
  dispose(tempAct);
  tempAct := nextAct;
 end;
end;

{Spliting the line will put a end of line ($13) at every seperated
code line (intermost first)}
function splitLine(unsplit: string): PChar;
var tempP, usPlace, tpPlace, unsplitP, freeSplitP: PChar;
begin
 {Right now this function does squat, except return the line in PChar form}
 {Now this function will seperate commands on the same line (or comments)}
 {by the ; modifier.  I will be changing this so that ; can be changeable}
 {and that it will look into experssions.  How i'll do that is a very good}
 {question}
 {FEOD: I will need to add a header part to the .def file}
 getMem(tempP, 255);
 getMem(unsplitP, length(unsplit)+1);
 strPCopy(unsplitP, unsplit);
 freeSplitP := unsplitP;
 tpPlace := tempP;
 while strScan(unsplitP, ';') <> nil do
 begin
  usPlace := strScan(unsplitP, ';');
  usPlace^ := #0;
  strCopy(tpPlace, unsplitP);
  tpPlace[strLen(unsplitP)] := #13;
  tpPlace[strLen(unsplitP)+1] := #0;
  tpPlace := tpPlace+strLen(unsplitP)+1;
  usPlace^ := ';';
  unsplitP := usPlace + 1;
 end;
 if tpPlace = tempP then
 begin
  strCopy(tpPlace, unsplitP);
  tpPlace[strLen(unsplitP)] := #13;
  tpPlace[strLen(unsplitP)+1] := #0;
 end;
 i := strLen(tempP)+1;
 getMem(tpPlace, strLen(tempP)+1);
 strCopy(tpPlace, tempP);
 freeMem(tempP, 255);
 freeMem(freeSplitP, strLen(freeSplitP)+1);
 splitLine := tpPlace;
end;

function replaceSyn(icode: PChar; syn: PSyn): PChar;
var i, p, pp, o: word;
 dsyn: PSyn; temp: PChar; temp1: PChar;
 charSave: char;
begin
 i := 0; o := 0;
 getMem(temp, 255);
 while icode[i] = ' ' do i := i+1; i := i+1;
 while icode[i] <> #0 do
 begin
  while ((icode[i] <> '%') AND (icode[i] <> #0)) do
   begin temp[o] := icode[i]; o := o+1; i := i+1; end;
  if icode[i] = #0 then break;
  i:= i+1; dsyn := syn;
  if icode[i] = '%' then
  begin
   i := i+1;
   temp[o] := '%';
   o := o+1;
   continue;
  end;
{  if NOT((incode[i] >= '0') AND (incode[i] <= '9')) then
  begin
   i := i+1;
   temp[o] := '%';
   temp[o+1] := incode[i-1];
   o := o+2;
   continue;
  end;}
  charSave := icode[i+1];
  icode[i+1] := #0;
  if icode[i] = '0' then
  begin
   strCat(temp, currReg); o := o+strLen(currReg);
   icode[i+1] := charSave; i := i+1; continue;
  end;
  for p := 0 to vala(icode+i)-1 do
   dsyn := dsyn^.nextSyntax;
  icode[i+1] := charSave;
  p := strLen(dsyn^.synVal);
  case icode[i+1] of
   'd':
   begin
    pp := determineSize(dsyn^.synType);
    if pp = 1 then begin temp[o] := 'b'; temp[o+1] := 'y';
     temp[o+2] := 't'; temp[o+3] := 'e'; o := o+4; end;
    if pp = 2 then begin temp[o] := 'b'; temp[o+1] := 'y';
     temp[o+2] := 't'; temp[o+3] := 'e'; o := o+4; end;
    if pp = 4 then begin temp[o] := 'b'; temp[o+1] := 'y';
     temp[o+2] := 't'; temp[o+3] := 'e'; o := o+4; end;
    if pp = 8 then begin temp[o] := 'b'; temp[o+1] := 'y';
     temp[o+2] := 't'; temp[o+3] := 'e'; o := o+4; end;
    i := i+1;
    continue;
   end;
  end;

  for p := 0 to strLen(dsyn^.synVal) do
   begin temp[o] := dsyn^.synVal[p]; o := o+1; end;
  i := i+1; o := o-1;
 end;
 temp[o] := #0;
 getMem(temp1, o+1);
 strCopy(temp1, temp);
 replaceSyn := temp1;
 freeMem(temp, 255);
end;