Changeset 2


Ignore:
Timestamp:
May 19, 2019, 1:23:18 PM (6 years ago)
Author:
chronos
Message:
  • Fixed: >= and <= operators.
  • Added: Read source code from file supplied as command line parameter.
Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore set to
      lib
      compiler
      compiler.lps
  • trunk/Examples/Square.pas

    r1 r2  
    88begin
    99   x := 1;
    10    while x [ 10 do
     10   while x <= 10 do
    1111   begin
    1212      call square;
    13       ! squ;
     13      !squ;
    1414      x := x + 1
    1515   end
  • trunk/compiler.pas

    r1 r2  
    7474  CharacterCount: Integer;
    7575  LineLength: Integer;
    76   kk: Integer;
    7776  ErrorCount: Integer;
    7877  CodeAllocationIndex: Integer;
    7978  Line: array [1..81] of Char;
    80   a: TIdentifier;
    8179  Code: array [0..MaxCodeIndex] of TInstruction;
    8280  ReservedWords: array [1..ReservedWordsCount] of TIdentifier;
     
    8886  FactorBeginSymbolSet: TSymbolSet;
    8987  SymbolTable: array [0..IdentifierTableSize] of TSymbol;
     88  SourceFile: Text;
    9089
    9190procedure Error(ErrorCode: TError);
     
    9897begin
    9998  if CharacterCount = LineLength then begin
    100     if Eof(Input) then begin
     99    if Eof(SourceFile) then begin
    101100      Write(' program incomplete');
    102101      goto 99;
     
    105104    CharacterCount := 0;
    106105    Write(CodeAllocationIndex: 5, ' ');
    107     while not Eoln(Input) do begin
     106    while not Eoln(SourceFile) do begin
    108107      LineLength := LineLength + 1;
    109       Read(LastChar);
     108      Read(SourceFile, LastChar);
    110109      Write(LastChar);
     110      if LastChar in ['A'..'Z'] then
     111        LastChar := Chr(Ord(LastChar) - Ord('A') + Ord('a'));
    111112      Line[LineLength] := LastChar;
    112113    end;
    113114    WriteLn;
    114     ReadLn;
     115    ReadLn(SourceFile);
    115116    LineLength := LineLength + 1;
    116117    Line[LineLength] := ' ';
     
    120121end;
    121122
     123function SearchReservedWord(Identifier: TIdentifier): Integer;
     124var
     125  I: Integer;
     126  J: Integer;
     127  K: Integer;
     128begin
     129  I := 1;
     130  J := ReservedWordsCount;
     131  repeat
     132    K := (I + J) div 2;
     133    if Identifier <= ReservedWords[K] then J := K - 1;
     134    if Identifier >= ReservedWords[K] then I := K + 1;
     135  until I > J;
     136  if I - 1 > J then SearchReservedWord := K
     137    else SearchReservedWord := 0;
     138end;
     139
     140
    122141procedure GetSymbol;
    123142var
    124   i, j, k: Integer;
     143  I, K: Integer;
     144  Identifier: TIdentifier;
     145  kk: Integer;
    125146begin
    126147  while LastChar = ' ' do GetCharacter;
    127148  if LastChar in ['a'..'z'] then begin
    128149    {identifier or reserved ReservedWords}
    129     k := 0;
     150    K := 0;
    130151    repeat
    131       if k < MaxIdentifierLength then begin
    132         k := k + 1;
    133         a[k] := LastChar;
     152      if K < MaxIdentifierLength then begin
     153        K := K + 1;
     154        Identifier[K] := LastChar;
    134155      end;
    135156      GetCharacter;
    136157    until not (LastChar in ['a'..'z', '0'..'9']);
    137     if k >= kk then kk := k
     158    kk := MaxIdentifierLength;
     159    if K >= kk then kk := K
    138160      else repeat
    139         a[kk] := ' ';
     161        Identifier[kk] := ' ';
    140162        kk := kk - 1
    141       until kk = k;
    142     LastIdentifier := a;
    143     i := 1;
    144     j := ReservedWordsCount;
    145     repeat
    146       k := (i + j) div 2;
    147       if LastIdentifier <= ReservedWords[k] then j := k - 1;
    148       if LastIdentifier >= ReservedWords[k] then i := k + 1;
    149     until i > j;
    150     if i - 1 > j then LastSymbol := WordSymbols[k]
     163      until kk = K;
     164    LastIdentifier := Identifier;
     165    I := SearchReservedWord(Identifier);
     166    if I > 0 then LastSymbol := WordSymbols[I]
    151167      else LastSymbol := skIdentifier;
    152168  end else
    153169  if LastChar in ['0'..'9'] then begin
    154170    {skNumber}
    155     k := 0;
     171    K := 0;
    156172    LastNumber := 0;
    157173    LastSymbol := skNumber;
    158174    repeat
    159175      LastNumber := 10 * LastNumber + (Ord(LastChar) - Ord('0'));
    160       k := k + 1;
     176      K := K + 1;
    161177      GetCharacter
    162178    until not (LastChar in ['0'..'9']);
    163     if k > MaxNumberDigitsCount then Error(erNumberOutOfRange);
     179    if K > MaxNumberDigitsCount then Error(erNumberOutOfRange);
    164180  end else
    165181  if LastChar = ':' then begin
     
    173189    LastSymbol := SingleCharSymbols[LastChar];
    174190    GetCharacter;
     191    { Check two characters symbols }
     192    if LastSymbol = skLess then begin
     193      if LastChar = '=' then begin
     194        LastSymbol := skLessOrEqual;
     195        GetCharacter;
     196      end
     197    end else
     198    if LastSymbol = skGreater then begin
     199      if LastChar = '=' then begin
     200        LastSymbol := skGreaterOrEqual;
     201        GetCharacter;
     202      end;
     203    end;
    175204  end;
    176205end;
     
    259288procedure ListGeneratedCode(var Block: TBlock);
    260289var
    261   i: Integer;
    262 begin
    263   for i := Block.InitialCodeIndex to CodeAllocationIndex - 1 do
    264     with Code[i] do
    265       WriteLn(i: 5, Mnemonic[Func]: 5, 1: 3, Address: 5);
     290  I: Integer;
     291begin
     292  for I := Block.InitialCodeIndex to CodeAllocationIndex - 1 do
     293    with Code[I] do
     294      WriteLn(I: 5, Mnemonic[Func]: 5, 1: 3, Address: 5);
    266295end;
    267296
     
    285314          end;
    286315      GetSymbol;
    287     end
    288     else
     316    end else
    289317    if LastSymbol = skNumber then begin
    290318      if LastNumber > MaxAddress then begin
     
    294322      Generate(fnLoadConstant, 0, LastNumber);
    295323      GetSymbol;
    296     end
    297     else
     324    end else
    298325    if LastSymbol = skLeftParenthesis then begin
    299326      GetSymbol;
     
    308335procedure ParseTerm(var Block: TBlock; SymbolSet: TSymbolSet);
    309336var
    310   Operation: TSymbolKind;
     337  MultiplyOperation: TSymbolKind;
    311338begin
    312339  ParseFactor(Block, SymbolSet + [skTimes, skSlash]);
    313   while LastSymbol in [skTimes, skSlash] do
    314   begin
    315     Operation := LastSymbol;
     340  while LastSymbol in [skTimes, skSlash] do begin
     341    MultiplyOperation := LastSymbol;
    316342    GetSymbol;
    317343    ParseFactor(Block, SymbolSet + [skTimes, skSlash]);
    318     if Operation = skTimes then Generate(fnOperation, 0, Integer(opMultiply))
     344    if MultiplyOperation = skTimes then Generate(fnOperation, 0, Integer(opMultiply))
    319345      else Generate(fnOperation, 0, Integer(opDivide));
    320346  end;
     
    323349procedure ParseExpression(var Block: TBlock; SymbolSet: TSymbolSet);
    324350var
    325   addop: TSymbolKind;
     351  AddOperation: TSymbolKind;
    326352begin
    327353  if LastSymbol in [skPlus, skMinus] then begin
    328     addop := LastSymbol;
     354    AddOperation := LastSymbol;
    329355    GetSymbol;
    330356    ParseTerm(Block, SymbolSet + [skPlus, skMinus]);
    331     if addop = skMinus then
     357    if AddOperation = skMinus then
    332358      Generate(fnOperation, 0, Integer(opNegative));
    333   end
    334   else
     359  end else
    335360    ParseTerm(Block, SymbolSet + [skPlus, skMinus]);
    336   while LastSymbol in [skPlus, skMinus] do
    337   begin
    338     addop := LastSymbol;
     361  while LastSymbol in [skPlus, skMinus] do begin
     362    AddOperation := LastSymbol;
    339363    GetSymbol;
    340364    ParseTerm(Block, SymbolSet + [skPlus, skMinus]);
    341     if addop = skPlus then
    342       Generate(fnOperation, 0, Integer(opAdd))
    343     else
    344       Generate(fnOperation, 0, Integer(opSubtract));
     365    if AddOperation = skPlus then Generate(fnOperation, 0, Integer(opAdd))
     366      else Generate(fnOperation, 0, Integer(opSubtract));
    345367  end;
    346368end;
     
    348370procedure ParseCondition(var Block: TBlock; SymbolSet: TSymbolSet);
    349371var
    350   relop: TSymbolKind;
     372  RelationOperation: TSymbolKind;
    351373begin
    352374  if LastSymbol = skOdd then begin
     
    362384    else
    363385    begin
    364       relop := LastSymbol;
     386      RelationOperation := LastSymbol;
    365387      GetSymbol;
    366388      ParseExpression(Block, SymbolSet);
    367       case relop of
     389      case RelationOperation of
    368390        skEqual: Generate(fnOperation, 0, Integer(opEqual));
    369391        skNotEqual: Generate(fnOperation, 0, Integer(opNotEqual));
    370392        skLess: Generate(fnOperation, 0, Integer(opLess));
    371         skGreaterOrEqual: Generate(fnOperation, 0, Integer(opGreater));
    372         skGreater: Generate(fnOperation, 0, Integer(opGreaterOrEqual));
     393        skGreaterOrEqual: Generate(fnOperation, 0, Integer(opGreaterOrEqual));
     394        skGreater: Generate(fnOperation, 0, Integer(opGreater));
    373395        skLessOrEqual: Generate(fnOperation, 0, Integer(opLessOrEqual));
    374396      end;
     
    379401procedure ParseStatement(var Block: TBlock; SymbolSet: TSymbolSet);
    380402var
    381   i, cx1, cx2: Integer;
     403  I, cx1, cx2: Integer;
    382404begin
    383405  if LastSymbol = skIdentifier then begin
    384     i := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
    385     if i = 0 then Error(erSymbolNotFound)
     406    I := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
     407    if I = 0 then Error(erSymbolNotFound)
    386408    else
    387     if SymbolTable[i].ObjectKind <> okVariable then begin
     409    if SymbolTable[I].ObjectKind <> okVariable then begin
    388410      Error(erAssignmentToNonVariable);
    389       i := 0;
     411      I := 0;
    390412    end;
    391413    GetSymbol;
     
    393415      else Error(erExpectedEqualOperator);
    394416    ParseExpression(Block, SymbolSet);
    395     if i <> 0 then
    396       with SymbolTable[i] do
     417    if I <> 0 then
     418      with SymbolTable[I] do
    397419        Generate(fnStoreVariable, Block.Level - Level, Address);
    398420  end else
     
    401423    if LastSymbol <> skIdentifier then Error(erExpectedProcedureName)
    402424    else begin
    403       i := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
    404       if i = 0 then Error(erSymbolNotFound)
     425      I := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
     426      if I = 0 then Error(erSymbolNotFound)
    405427      else
    406         with SymbolTable[i] do
     428        with SymbolTable[I] do
    407429          if ObjectKind = okProcedure then Generate(fnCall, Block.Level - Level, Address)
    408430          else Error(erIdentifierIsNotProcedureName);
     
    414436    if LastSymbol <> skIdentifier then Error(erExpectedIdentifier)
    415437    else begin
    416       i := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
    417       if i = 0 then Error(erSymbolNotFound)
     438      I := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
     439      if I = 0 then Error(erSymbolNotFound)
    418440      else
    419         with SymbolTable[i] do
     441        with SymbolTable[I] do
    420442          if ObjectKind = okVariable then Generate(fnWrite, Block.Level - Level, Address)
    421443          else Error(erExpectedVariableName);
     
    427449    if LastSymbol <> skIdentifier then Error(erExpectedIdentifier)
    428450    else begin
    429       i := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
    430       if i = 0 then Error(erSymbolNotFound)
     451      I := SearchSymbol(LastIdentifier, Block.SymbolTableIndex);
     452      if I = 0 then Error(erSymbolNotFound)
    431453      else
    432         with SymbolTable[i] do
     454        with SymbolTable[I] do
    433455          if ObjectKind = okVariable then Generate(fnRead, Block.Level - Level, Address)
    434456          else Error(erExpectedVariableName);
     
    554576  Instruction: TInstruction;
    555577  DataStore: array [1..StackSize] of Integer;
     578  X: Char;
    556579
    557580  function GetBaseDown(Levels: Integer): Integer;
     
    607630            DataStore[TopStack] := DataStore[TopStack] div DataStore[TopStack + 1];
    608631          end;
    609           opOdd: DataStore[TopStack] := Ord(odd(DataStore[TopStack]));
     632          opOdd: DataStore[TopStack] := Ord(Odd(DataStore[TopStack]));
    610633          opEqual: begin
    611634            TopStack := TopStack - 1;
     
    656679        end;
    657680        fnWrite: Write(DataStore[GetBaseDown(Level) + Address]:0, ' ');
    658         fnRead: Read(DataStore[GetBaseDown(Level) + Address]);
     681        fnRead: ReadLn(DataStore[GetBaseDown(Level) + Address]);
    659682      end;
    660683  until ProgramCounter = 0;
     
    700723  SingleCharSymbols['<'] := skLess;
    701724  SingleCharSymbols['>'] := skGreater;
    702   SingleCharSymbols['['] := skLessOrEqual;
    703   SingleCharSymbols[']'] := skGreaterOrEqual;
    704725  SingleCharSymbols[';'] := skSemicolon;
    705726  SingleCharSymbols['!'] := skWrite;
     
    724745  LineLength := 0;
    725746  LastChar := ' ';
    726   kk := MaxIdentifierLength;
    727 end;
    728 
    729 begin
     747end;
     748
     749begin
     750  if ParamCount > 0 then begin
     751    WriteLn(ParamStr(1));
     752    Assign(SourceFile, ParamStr(1));
     753    Reset(SourceFile);
     754  end else SourceFile := Input;
    730755  Init;
    731756  ParseProgram;
     757  Close(SourceFile);
    732758  if ErrorCount = 0 then Interpret
    733759    else Write(ErrorCount, ' errors in pl/0 program');
Note: See TracChangeset for help on using the changeset viewer.