Changeset 142


Ignore:
Timestamp:
Jan 16, 2018, 3:19:23 PM (6 years ago)
Author:
chronos
Message:
  • Added: Support for begin end block.
Location:
branches/easy compiler
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/easy compiler/Steps.txt

    r141 r142  
    1 
    21
    32Add abstract compiler
     
    1716Add integer type
    1817- support for mutiple types
     18Add begin-end block support
     19- local variables, constants, types
  • branches/easy compiler/UCompiler.pas

    r141 r142  
    4141  private
    4242    Tokenizer: TTokenizer;
    43     procedure Parse(Tokens: TSourceTokens; Code: TSourceCode);
     43    procedure Parse(Code: TSourceCode);
     44    procedure ParseBeginEnd(BeginEnd: TSourceBeginEnd);
    4445  public
    4546    procedure Compile(Source: string; SourceCode: TSourceCode);
     
    168169{ TCompiler }
    169170
    170 procedure TCompiler.Parse(Tokens: TSourceTokens; Code: TSourceCode);
     171procedure TCompiler.Parse(Code: TSourceCode);
     172begin
     173  Tokenizer.TokenIndex := 0;
     174  ParseBeginEnd(Code.Main);
     175end;
     176
     177procedure TCompiler.ParseBeginEnd(BeginEnd: TSourceBeginEnd);
    171178var
    172179  Token: TSourceToken;
     
    186193    NewReference := TSourceReferenceConstant.Create;
    187194    TSourceReferenceConstant(NewReference).Constant :=
    188       Code.Constants.AddNewString(Token.Text);
     195      BeginEnd.SourceCode.Constants.AddNewString(Token.Text);
    189196  end else
    190197  if Token.Kind = stIdentifier then begin
    191198    NewReference := TSourceReferenceVariable.Create;
    192199    TSourceReferenceVariable(NewReference).Variable :=
    193       Code.Variables.Search(Token.Text);
     200      BeginEnd.SourceCode.Variables.Search(Token.Text);
    194201    if TSourceReferenceVariable(NewReference).Variable = nil then
    195202      raise Exception.Create('Variable not found: ' + Token.Text);
     
    198205    NewReference := TSourceReferenceConstant.Create;
    199206    TSourceReferenceConstant(NewReference).Constant :=
    200       Code.Constants.AddNewInteger(StrToInt(Token.Text));
     207      BeginEnd.SourceCode.Constants.AddNewInteger(StrToInt(Token.Text));
    201208  end else
    202209  raise Exception.Create('Unexpected parameter');
     
    210217    NewReference := TSourceReferenceVariable.Create;
    211218    TSourceReferenceVariable(NewReference).Variable :=
    212       Code.Variables.Search(Token.Text);
     219      BeginEnd.SourceCode.Variables.Search(Token.Text);
    213220    if TSourceReferenceVariable(NewReference).Variable = nil then
    214221      raise Exception.Create('Variable not found: ' + Token.Text);
     
    219226
    220227begin
    221   Tokenizer.TokenIndex := 0;
    222   while Tokenizer.TokenIndex < Length(Tokens.Tokens) do begin
     228  while True do begin
    223229    Token := Tokenizer.GetNext;
     230    if Token.Kind = stEof then Break
     231    else
    224232    if Token.Kind = stIdentifier then begin
    225233      Keyword := LowerCase(Token.Text);
     
    229237        if Token2.Kind <> stIdentifier then
    230238          raise Exception.Create('Expected type parameter');
    231         Variable := Code.Variables.Search(Token.Text);
     239        Variable := BeginEnd.SourceCode.Variables.Search(Token.Text);
    232240        if not Assigned(Variable) then begin
    233           ValueType := Code.Types.Search(Token2.Text);
     241          ValueType := BeginEnd.SourceCode.Types.Search(Token2.Text);
    234242          if not Assigned(ValueType) then
    235243            raise Exception.Create('Unsupported type: ' + Token2.Text);
    236           Variable := Code.Variables.AddNew(Token.Text,
     244          Variable := BeginEnd.SourceCode.Variables.AddNew(Token.Text,
    237245            ValueType);
    238         end else raise Exception.Create('Variable redefined');
    239       end else begin
    240         Funct := Code.Functions.Search(Keyword);
     246        end else raise Exception.Create('Variable redefined: ' + Token.Text);
     247      end else
     248      if Keyword = 'begin' then begin
     249        Instruction := TSourceBeginEnd.Create;
     250        BeginEnd.Instructions.Add(Instruction);
     251        TSourceBeginEnd(Instruction).SourceCode := BeginEnd.SourceCode;
     252        ParseBeginEnd(TSourceBeginEnd(Instruction));
     253      end else
     254      if Keyword = 'end' then begin
     255        Break;
     256      end else
     257      begin
     258        Funct := BeginEnd.SourceCode.Functions.Search(Keyword);
    241259        if Assigned(Funct) then begin
    242           Instruction := TSourceInstructionFunction.Create;
    243           TSourceInstructionFunction(Instruction).Name := Keyword;
     260          Instruction := TSourceFunctionCall.Create;
     261          TSourceFunctionCall(Instruction).Name := Keyword;
    244262          for Param in Funct.Parameters do
    245263          if Param.Kind = pkString then begin
    246             TSourceInstructionFunction(Instruction).AddParameter(ParseReference)
     264            TSourceFunctionCall(Instruction).AddParameter(ParseReference)
    247265          end else
    248266          if Param.Kind = pkVariable then begin
    249             TSourceInstructionFunction(Instruction).AddParameter(ParseReferenceVariable(True));
     267            TSourceFunctionCall(Instruction).AddParameter(ParseReferenceVariable(True));
    250268          end else
    251269          raise Exception.Create('Unsupported parameter type.');
    252           Code.Instructions.Add(Instruction);
     270          BeginEnd.Instructions.Add(Instruction);
    253271        end else raise Exception.Create('Unsupported keyword: ' + Token.Text);
    254272      end;
     
    265283
    266284  Tokenizer.Tokenize(Source, SourceTokens);
    267   Parse(SourceTokens, SourceCode);
     285  Parse(SourceCode);
    268286
    269287  Tokenizer.Free;
     
    277295  TargetInstruction: TTargetInstruction;
    278296begin
    279   Target.Instructions.Count := 0;
     297{  Target.Instructions.Count := 0;
    280298  for I := 0 to SourceCode.Instructions.Count - 1 do begin
    281299    Instruction := TSourceInstruction(SourceCode.Instructions[I]);
    282     if Instruction is TSourceInstructionFunction then begin
     300    if Instruction is TSourceFunctionCall then begin
    283301      TargetInstruction := TTargetInstruction.Create;
    284302      TargetInstruction.Kind := tiFunction;
    285       TargetInstruction.Name := TSourceInstructionFunction(Instruction).Name;
     303      TargetInstruction.Name := TSourceFunctionCall(Instruction).Name;
    286304      Target.Instructions.Add(TargetInstruction)
    287305    end else raise Exception.Create('Unsupported source instruction');
    288306  end;
     307  }
    289308end;
    290309
  • branches/easy compiler/UFormMain.pas

    r141 r142  
    6363    Add('InputLn Value2');
    6464
     65    Add('begin');
    6566    Add('Assign Result Value1');
    6667    Add('Increment Result Value2');
    6768    Add('Print ''Sum of two values is: ''');
    6869    Add('PrintLn Result');
     70    Add('end');
    6971  end;
    7072{  with MemoSource.Lines do begin
     
    99101    Add('Assign AnimalCount 2');
    100102    Add('Repeat');
    101     Add('BeginBlock');
     103    Add('Begin');
    102104      Add('PrintLn ''Think an animal.''');
    103105      Add('Assign I 0');
    104106      Add('Repeat');
    105       Add('BeginBlock');
     107      Add('Begin');
    106108        Add('Print AnimalProperty[I]');
    107109        Add('Print ''? (y/n)''');
    108110        Add('InputLn Answer');
    109111        Add('IfEqual Answer ''y''');
    110         Add('BeginBlock');
     112        Add('Begin');
    111113          Add('PrintLn ''That''s clear. It is ''');
    112114          Add('PrintLn AnimalName[I]');
    113115          Add('Break');
    114         Add('EndBlock');
     116        Add('End');
    115117        Add('Increment I');
    116118        Add('IfHigherOrEqual I AnimalCount');
    117119        Add('Break');
    118       Add('EndBlock');
     120      Add('End');
    119121      Add('PrintLn ''I am lost. What is the animal?''');
    120122      Add('InputLn AnimalName[I]');
     
    124126      Add('Increment AnimalCount 1');
    125127      Add('PrintLn ''''');
    126     Add('EndBlock');
     128    Add('End');
    127129  end;
    128130  }
  • branches/easy compiler/USourceCode.pas

    r141 r142  
    116116  end;
    117117
    118   { TSourceInstructionFunction }
    119 
    120   TSourceInstructionFunction = class(TSourceInstruction)
     118  { TSourceFunctionCall }
     119
     120  TSourceFunctionCall = class(TSourceInstruction)
    121121    Name: string;
    122122    Parameters: array of TSourceReference;
    123123    procedure AddParameter(Value: TSourceReference);
     124  end;
     125
     126  TSourceCode = class;
     127
     128  { TSourceBeginEnd }
     129
     130  TSourceBeginEnd = class(TSourceInstruction)
     131    SourceCode: TSourceCode;
     132    Instructions: TSourceInstructions;
     133    constructor Create;
     134    destructor Destroy; override;
    124135  end;
    125136
     
    134145    Constants: TSourceConstants;
    135146    Functions: TSourceFunctions;
    136     Instructions: TSourceInstructions;
     147    Main: TSourceBeginEnd;
    137148    constructor Create;
    138149    destructor Destroy; override;
     
    141152
    142153implementation
     154
     155{ TSourceBeginEnd }
     156
     157constructor TSourceBeginEnd.Create;
     158begin
     159  Instructions := TSourceInstructions.Create;
     160end;
     161
     162destructor TSourceBeginEnd.Destroy;
     163begin
     164  Instructions.Free;
     165  inherited Destroy;
     166end;
    143167
    144168{ TSourceTypes }
     
    290314end;
    291315
    292 { TSourceInstructionFunction }
    293 
    294 procedure TSourceInstructionFunction.AddParameter(Value: TSourceReference);
     316{ TSourceFunctionCall }
     317
     318procedure TSourceFunctionCall.AddParameter(Value: TSourceReference);
    295319begin
    296320  SetLength(Parameters, Length(Parameters) + 1);
     
    339363  Constants := TSourceConstants.Create;
    340364  Functions := TSourceFunctions.Create;
    341   Instructions := TSourceInstructions.Create;
     365  Main := TSourceBeginEnd.Create;
     366  Main.SourceCode := Self;
    342367  InitFunctions;
    343368end;
     
    345370destructor TSourceCode.Destroy;
    346371begin
    347   Instructions.Free;
     372  Main.Free;
    348373  Functions.Free;
    349374  Variables.Free;
  • branches/easy compiler/USourceExecutor.pas

    r141 r142  
    2828    FOnOutput: TOutputEvent;
    2929    Variables: TExecutorVariables;
     30    procedure ExecuteBeginEnd(BeginEnd: TSourceBeginEnd);
    3031  public
    3132    constructor Create;
     
    6869
    6970procedure TSourceExecutor.Execute(SourceCode: TSourceCode);
     71begin
     72  ExecuteBeginEnd(SourceCode.Main);
     73end;
     74
     75procedure TSourceExecutor.ExecuteBeginEnd(BeginEnd: TSourceBeginEnd);
    7076var
    7177  IP: Integer;
     
    96102begin
    97103  IP := 0;
    98   while IP < SourceCode.Instructions.Count do begin
    99     Instruction := TSourceInstruction(SourceCode.Instructions[IP]);
    100     if Instruction is TSourceInstructionFunction then
    101     with TSourceInstructionFunction(Instruction) do begin
     104  while IP < BeginEnd.Instructions.Count do begin
     105    Instruction := TSourceInstruction(BeginEnd.Instructions[IP]);
     106    if Instruction is TSourceFunctionCall then
     107    with TSourceFunctionCall(Instruction) do begin
    102108      if Name = 'print' then begin
    103109        if Assigned(FOnOutput) then begin
     
    156162        else raise Exception.Create('Wrong type for increment');
    157163      end else
    158       raise Exception.Create('Unsupported function: ' + TSourceInstructionFunction(Instruction).Name);
    159     end else raise Exception.Create('Unsupported instruction');
     164      raise Exception.Create('Unsupported function: ' + TSourceFunctionCall(Instruction).Name);
     165    end else
     166    if Instruction is TSourceBeginEnd then begin
     167      ExecuteBeginEnd(TSourceBeginEnd(Instruction));
     168    end else
     169    raise Exception.Create('Unsupported instruction');
    160170    Inc(IP);
    161171  end;
  • branches/easy compiler/USourceGenerator.pas

    r141 r142  
    1212
    1313  TSourceGenerator = class
     14  private
     15    function GenerateBeginEnd(BeginEnd: TSourceBeginEnd): string;
     16  public
    1417    function Generate(SourceCode: TSourceCode): string;
    1518  end;
     
    2124
    2225function TSourceGenerator.Generate(SourceCode: TSourceCode): string;
     26var
     27  I: Integer;
     28begin
     29  Result := '';
     30  if SourceCode.Variables.Count > 0 then
     31    Result := Result + 'var' + LineEnding;
     32  with SourceCode do
     33  for I := 0 to Variables.Count - 1 do
     34  with TSourceVariable(Variables[I]) do begin
     35    Result := Result + '  ' + Name + ': ';
     36    if ValueType.Name = 'String' then
     37      Result := Result + 'string'
     38    else if ValueType.Name = 'Integer' then
     39      Result := Result + 'Integer'
     40    else raise Exception.Create('Unsupported type');
     41    Result := Result + ';' + LineEnding;
     42  end;
     43  Result := Result + GenerateBeginEnd(SourceCode.Main) + '.' + LineEnding;
     44end;
     45
     46function TSourceGenerator.GenerateBeginEnd(BeginEnd: TSourceBeginEnd): string;
    2347var
    2448  Output: string;
     
    4569begin
    4670  Output := '';
    47   if SourceCode.Variables.Count > 0 then
    48     Output := Output + 'var' + LineEnding;
    49   with SourceCode do
    50   for I := 0 to Variables.Count - 1 do
    51   with TSourceVariable(Variables[I]) do begin
    52     Output := Output + '  ' + Name + ': ';
    53     if ValueType.Name = 'String' then
    54       Output := Output + 'string'
    55     else if ValueType.Name = 'Integer' then
    56       Output := Output + 'Integer'
    57     else raise Exception.Create('Unsupported type');
    58     Output := Output + ';' + LineEnding;
    59   end;
    6071  Output := Output + 'begin' + LineEnding;
    61   with SourceCode do
     72  with BeginEnd do
    6273  for I := 0 to Instructions.Count - 1 do begin
    6374    Instruction := TSourceInstruction(Instructions[I]);
    64     if Instruction is TSourceInstructionFunction then
    65     with TSourceInstructionFunction(Instruction) do begin
     75    if Instruction is TSourceFunctionCall then
     76    with TSourceFunctionCall(Instruction) do begin
    6677      if Name = 'print' then begin
    6778        Output := Output + '  Write(' + GenerateRef(Parameters[0]) + ');' +
     
    8495      end else
    8596      raise Exception.Create('Unsupported instruction name.');
    86     end else raise Exception.Create('Unsupported instruction');
     97    end else
     98    if Instruction is TSourceBeginEnd then begin
     99      Output := Output + GenerateBeginEnd(TSourceBeginEnd(Instruction)) +
     100        ';' + LineEnding;
     101    end else
     102    raise Exception.Create('Unsupported instruction');
    87103  end;
    88   Output := Output + 'end.' + LineEnding;
     104  Output := Output + 'end';
    89105  Result := Output;
    90106end;
Note: See TracChangeset for help on using the changeset viewer.