Changeset 18


Ignore:
Timestamp:
Apr 9, 2009, 11:17:38 AM (15 years ago)
Author:
george
Message:
  • Upraveno: Vylepšené parsování.
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Example.pas

    r11 r18  
    11program Test;
    22var
    3   A: Byte;
     3  a: Byte;
     4  B: Byte;
    45begin
    5   A := 'a' + (10 + 2) * 3 xor 10 / 2;
     6  A := 'a' + (10 + 2 * 3 + 2) xor 10 / 2;
     7  B := 20;
    68  while A < 10 do A := A + 1;
     9
    710end;
  • trunk/UMainForm.pas

    r11 r18  
    1212  TModuleType = (mdProgram, mdUnit, mdLibrary, mdPackage);
    1313
    14   TInstruction = (inJump, inConditionalJump, inExpressionEvaluation);
    15 
    16   TNodeType = (ntNone, ntVariable, ntMethod, ntConstant, ntOperator);
     14  TInstruction = (inNone, inJump, inConditionalJump, inExpressionEvaluation,
     15    inReturn);
     16
     17  TNodeType = (ntNone, ntVariable, nTFunction, ntConstant, ntOperator);
    1718
    1819  TValue = array of Byte;
     
    2324  TConstantList = class;
    2425  TVariableList = class;
    25   TMethodList = class;
     26  TFunctionList = class;
    2627  TExpression = class;
    2728  TOperationList = class;
     29  TFunction = class;
    2830
    2931  TDevice = class
     
    3840    Types: TTypeList;
    3941    Variables: TVariableList;
    40     Methods: TMethodList;
     42    Methods: TFunctionList;
    4143    Operations: TOperationList;
    4244    procedure AllocateMemory;
     
    4850    procedure ParseOperation(Compiler: TCompiler);
    4951    procedure GenerateAssembler(Compiler: TCompiler; LabelPrefix: string);
     52    procedure CheckReferences;
    5053  end;
    5154
     
    9396    NodeType: TNodeType;
    9497    Variable: TVariable;
    95     Method: TMethod;
     98    Method: TFunction;
    9699    Value: TValue;
    97100    OperatorName: string;
     
    108111    GotoAddress: Integer;
    109112    Negative: Boolean;
     113    Referenced: Boolean;
    110114  end;
    111115
     
    114118  end;
    115119
    116   TMethod = class(TCommonBlock)
     120  TFunction = class(TCommonBlock)
    117121    Parameters: TList; // TList<TParameter>
    118122    ResultType: TType;
     
    122126  end;
    123127
    124   TMethodList = class(TList)
     128  TFunctionList = class(TList)
    125129    Parent: TCommonBlock;
    126130    procedure Parse(Compiler: TCompiler);
    127     function Search(Name: string): TMethod;
     131    function Search(Name: string): TFunction;
    128132  end;
    129133
     
    137141    procedure ParseUnit(Compiler: TCompiler);
    138142    procedure ParseProgram(Compiler: TCompiler);
     143    procedure Clear;
    139144  end;
    140145
     
    275280  ProgramCode.Parse(Self);
    276281  ProgramCode.AllocateMemory;
     282  AssemblyCode.Clear;
    277283  GenerateAssemblyCode;
    278284end;
     
    438444end;
    439445
    440 { TMethod }
    441 
    442 constructor TMethod.Create;
     446{ TFunction }
     447
     448constructor TFunction.Create;
    443449begin
    444450  inherited;
     
    447453end;
    448454
    449 destructor TMethod.Destroy;
     455destructor TFunction.Destroy;
    450456begin
    451457  Parameters.Free;
     
    454460end;
    455461
    456 procedure TMethod.Parse(Compiler: TCompiler);
     462procedure TFunction.Parse(Compiler: TCompiler);
    457463begin
    458464  with Compiler do begin
     
    478484  Device := TDevice.Create;
    479485  Modules := TList.Create;
     486end;
     487
     488destructor TProgram.Destroy;
     489begin
     490
     491end;
     492
     493procedure TProgram.GenerateAssembler(Compiler: TCompiler);
     494var
     495  I: Integer;
     496begin
     497  for I := 0 to Modules.Count - 1 do
     498    TModule(Modules[I]).GenerateAssembler(Compiler, '');
     499end;
     500
     501procedure TProgram.Parse(Compiler: TCompiler);
     502var
     503  I: Integer;
     504begin
     505  for I := 0 to Modules.Count - 1 do
     506    TModule(Modules[I]).Clear;
     507  Modules.Clear;
    480508  with TModule(Modules[Modules.Add(TModule.Create)]) do begin
    481509    Name := 'main';
     
    486514    end;
    487515  end;
    488 end;
    489 
    490 destructor TProgram.Destroy;
    491 begin
    492 
    493 end;
    494 
    495 procedure TProgram.GenerateAssembler(Compiler: TCompiler);
    496 var
    497   I: Integer;
    498 begin
    499   for I := 0 to Modules.Count - 1 do
    500     TModule(Modules[I]).GenerateAssembler(Compiler, '');
    501 end;
    502 
    503 procedure TProgram.Parse(Compiler: TCompiler);
    504 begin
    505516  TModule(Modules[0]).Parse(Compiler);
    506517end;
     
    537548
    538549{ TModule }
     550
     551procedure TModule.Clear;
     552begin
     553  Variables.Clear;
     554  Constants.Clear;
     555  Methods.Clear;
     556  Operations.Clear;
     557end;
    539558
    540559constructor TModule.Create;
     
    589608end;
    590609
     610procedure TCommonBlock.CheckReferences;
     611var
     612  I: Integer;
     613begin
     614  for I := 0 to Operations.Count - 1 do
     615  with TOperation(Operations[I]) do begin
     616    if (Instruction = inJump) or (Instruction = inConditionalJump) then
     617      TOperation(Operations[GotoAddress]).Referenced := True;
     618  end;
     619end;
     620
    591621constructor TCommonBlock.Create;
    592622begin
     
    597627  Variables := TVariableList.Create;
    598628  Variables.Parent := Self;
    599   Methods := TMethodList.Create;
     629  Methods := TFunctionList.Create;
    600630  Methods.Parent := Self;
    601631  Operations := TOperationList.Create;
     
    615645var
    616646  I: Integer;
     647  LabelName: string;
    617648begin
    618649  with Compiler do
    619   for I := 0 to Operations.Count - 1 do
     650  for I := 0 to Operations.Count - 1 do 
    620651  with TOperation(Operations[I]) do begin
     652    if Referenced then LabelName := Name + '_L' + IntToStr(I)
     653      else LabelName := '';
    621654    case Instruction of
    622655      inJump: begin
    623         AddInstruction('', 'JMP', Name + '_L' + IntToStr(GotoAddress), '');
     656        AddInstruction(LabelName, 'JMP', Name + '_L' + IntToStr(GotoAddress), '');
    624657      end;
    625658      inConditionalJump: begin
    626659        ExpressionTree.GenerateAssembler(Compiler, LabelPrefix + '_L' + IntToStr(GotoAddress));
    627         AddInstruction('', 'BRCS', Name + '_L' + IntToStr(GotoAddress), '');
     660        AddInstruction(LabelName, 'BRCS', Name + '_L' + IntToStr(GotoAddress), '');
    628661      end;
    629662      inExpressionEvaluation: begin
     663        if LabelName <> '' then AddInstruction(LabelName, '', '', '');
    630664        ExpressionTree.GenerateAssembler(Compiler, Name + '_L' + IntToStr(GotoAddress));
    631665      end;
     666      inReturn:
     667        AddInstruction(LabelName, 'RET', '', '');
    632668    end;
    633669  end;
     
    652688var
    653689  Identifier: string;
    654   Variable: TVariable;
    655   Method: TMethod;
     690  NewVariable: TVariable;
     691  Method: TFunction;
    656692  Constant: TConstant;
    657693//  Brackets: Integer;
     
    680716        end else
    681717        if IsIdentificator(Identifier) then begin
    682           Variable := Variables.Search(Identifier);
    683           if Assigned(Variable) then begin
     718          NewVariable := Variables.Search(Identifier);
     719          if Assigned(NewVariable) then begin
    684720            with TExpression(Expressions[Expressions.Count - 1]) do begin
    685721              SubItems[1] := TExpression.Create;
    686722              TExpression(SubItems[1]).NodeType := ntVariable;
    687               TExpression(SubItems[1]).Variable := Variable;
     723              TExpression(SubItems[1]).Variable := NewVariable;
    688724            end;
    689725            with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin
     
    705741                  Expect(')');
    706742                end;
    707                 TExpression(SubItems[1]).NodeType := ntMethod;
     743                TExpression(SubItems[1]).NodeType := nTFunction;
    708744                TExpression(SubItems[1]).Method := Method;
    709745              end;
     
    722758                  SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1];
    723759                end;
     760              end else begin
     761                ErrorMessage('Neznámý identifikátor: ' + Identifier);
    724762              end;
    725763            end;
     
    769807  Identifier: string;
    770808  Variable: TVariable;
    771   Method: TMethod;
     809  Method: TFunction;
    772810  First: TOperation;
    773811  Second: TOperation;
     
    909947    end;
    910948    Expect('end');
    911   end;
     949    with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     950      Instruction := inReturn;
     951    end;
     952  end;
     953  CheckReferences;
    912954end;
    913955
     
    10101052end;
    10111053
    1012 { TMethodList }
    1013 
    1014 procedure TMethodList.Parse(Compiler: TCompiler);
    1015 begin
    1016 
    1017 end;
    1018 
    1019 function TMethodList.Search(Name: string): TMethod;
     1054{ TFunctionList }
     1055
     1056procedure TFunctionList.Parse(Compiler: TCompiler);
     1057begin
     1058
     1059end;
     1060
     1061function TFunctionList.Search(Name: string): TFunction;
    10201062var
    10211063  I: Integer;
    10221064begin
    10231065  I := 0;
    1024   while (I < Count) and (TMethod(Items[I]).Name <> Name) do Inc(I);
     1066  while (I < Count) and (TFunction(Items[I]).Name <> Name) do Inc(I);
    10251067  if I < Count then Result := Items[I] else begin
    10261068    if Assigned(Parent.Parent) then Result := Parent.Parent.Methods.Search(Name)
     
    10451087end;
    10461088
    1047 procedure TExpression.GenerateAssembler(Compiler: TCompiler;
    1048   LabelPrefix: string);
     1089procedure TExpression.GenerateAssembler(Compiler: TCompiler; LabelPrefix: string);
    10491090var
    10501091  I: Integer;
     
    10531094  case NodeType of
    10541095    ntNone: ;
    1055     ntVariable: AddInstruction('', 'CALL', '', '');
    1056     ntMethod: AddInstruction('', 'CALL', '', '');
     1096    ntVariable: if Assigned(Variable) then AddInstruction('', 'GETVAR', Variable.Name, '');
     1097    nTFunction: AddInstruction('', 'CALL', Method.Name, '');
    10571098    ntConstant: AddInstruction('', 'CONST', '', '');
    10581099    ntOperator: begin
     
    10841125function TAssemblerLine.AsString: string;
    10851126begin
    1086   Result := LabelName + ': ' + Instruction + ' ' + Operand1 + ',' + Operand2;
     1127  if LabelName = '' then LabelName := #9 else
     1128    LabelName := LabelName + ':'#9;
     1129  if Operand2 <> '' then Operand1 := Operand1 + ', ';
     1130 
     1131  Result := LabelName + Instruction + ' ' + Operand1 + Operand2;
    10871132end;
    10881133
Note: See TracChangeset for help on using the changeset viewer.